Spring IoC(Inverse of Control,控制反转)是Spring框架的核心功能之一。
定义与概念
- 控制反转:是一种设计思想,将对象的创建和对象之间的依赖关系的管理从应用程序本身转移到外部容器。在传统编程中,对象A如果依赖对象B,那么对象A通常会在内部自行创建或查找对象B。而在IoC模式下,对象A不再负责获取或创建它所依赖的对象B,而是由一个外部的IoC容器来负责创建和注入对象B到对象A中。
- 依赖注入(Dependency Injection,DI):是实现IoC的一种具体方式,它是指容器在创建对象时,将其所依赖的对象通过构造函数、方法参数或属性等方式注入到该对象中。
Spring IoC容器
- 容器的作用:Spring IoC容器负责创建、管理和维护对象的生命周期以及对象之间的依赖关系。它就像是一个对象工厂,根据配置信息或注解来创建对象,并将它们装配在一起。
- 主要接口
- BeanFactory:是Spring IoC容器的基础接口,提供了基本的容器功能,如获取Bean等。它采用延迟加载的方式,只有在真正需要使用某个Bean时才会创建它。
- ApplicationContext:是BeanFactory的子接口,它除了具备BeanFactory的所有功能外,还提供了一些额外的功能,如支持国际化、事件发布等。通常在Spring应用中,会优先使用ApplicationContext作为IoC容器。
配置方式
- XML配置:通过XML文件来定义Bean及其属性、依赖关系等。例如:
<bean id="userService" class="com.example.UserServiceImpl"><property name="userDao" ref="userDao"/>
</bean>
<bean id="userDao" class="com.example.UserDaoImpl"/>
- 注解配置:在类、方法或字段上使用注解来标识Bean以及注入依赖。如
@Component
、@Service
、@Repository
、@Autowired
、@Qualifier
等。示例如下:
@Service
public class UserServiceImpl implements UserService {@Autowiredprivate UserDao userDao;//...
}
- Java配置:使用Java类和注解来替代XML进行配置。通过
@Configuration
和@Bean
等注解来定义Bean。例如:
@Configuration
public class AppConfig {@Beanpublic UserService userService() {return new UserServiceImpl(userDao());}@Beanpublic UserDao userDao() {return new UserDaoImpl();}
}
Bean的生命周期
- 实例化:容器根据配置信息创建Bean的实例。
- 属性赋值:将Bean的属性值和依赖关系注入到实例中。
- 初始化:如果Bean实现了
InitializingBean
接口,会调用其afterPropertiesSet
方法;也可以通过@PostConstruct
注解标记的方法进行初始化操作;还可以在配置中指定init-method
属性来指定初始化方法。 - 使用:Bean可以在应用中被使用,处理各种业务逻辑。
- 销毁:当容器关闭时,如果Bean实现了
DisposableBean
接口,会调用其destroy
方法;也可以通过@PreDestroy
注解标记的方法进行销毁操作;还可以在配置中指定destroy-method
属性来指定销毁方法。
依赖注入方式
- 构造函数注入:通过Bean的构造函数来注入依赖。例如:
public class UserServiceImpl implements UserService {private UserDao userDao;public UserServiceImpl(UserDao userDao) {this.userDao = userDao;}//...
}
- Setter方法注入:通过Bean的Setter方法来注入依赖。如下所示:
public class UserServiceImpl implements UserService {private UserDao userDao;public void setUserDao(UserDao userDao) {this.userDao = userDao;}//...
}
- 字段注入:直接在字段上使用
@Autowired
等注解进行注入。如前面的注解配置示例所示。
作用域
- singleton:单例模式,在整个容器中,只会创建一个Bean实例,所有对该Bean的请求都返回同一个实例。
- prototype:原型模式,每次请求获取Bean时,都会创建一个新的实例。
- request:在一次HTTP请求范围内有效,每个请求都会创建一个新的Bean实例。仅适用于Web应用。
- session:在一个HTTP Session范围内有效,同一个Session中获取的是同一个Bean实例。仅适用于Web应用。
- application:在ServletContext范围内有效,整个Web应用共享一个Bean实例。仅适用于Web应用。
优势
- 解耦对象之间的依赖关系:使得代码的可维护性和可扩展性更强,当某个对象的依赖关系发生变化时,只需要在配置或注解中进行修改,而不需要在大量的代码中进行查找和修改。
- 提高代码的可测试性:可以很方便地为被测试对象注入模拟的依赖对象,从而更容易编写单元测试。
- 便于管理和维护对象:Spring IoC容器集中管理对象的创建和生命周期,使得整个应用的对象结构更加清晰,易于理解和管理。