前言
在Spring框架中,Bean的加载和初始化过程是一个复杂而细致的过程,涉及多个阶段和扩展点。在我们日常开发中也会用到相关的知识,所以我们必须了解。
1. Spring容器启动
Spring容器启动时,会扫描配置的包路径并找到所有标注了
@Component
(以及其他派生注解如@Service
、@Repository
、@Controller
等)的类,并将其注册为Spring Bean。具体代码看在启动类上的@SpringBootApplication注解。
2. Bean定义阶段
在这个阶段,Spring会根据扫描到的类生成Bean定义(
BeanDefinition
),并将这些定义存储在容器中。这些定义包含了Bean的配置信息,包括作用域、依赖关系等。
3. Bean实例化阶段
当需要创建Bean实例时,Spring会进行如下步骤:
(1) 静态代码块
静态代码块在类加载器载入类时执行,只执行一次。
(2)默认代码块
默认代码块(实例初始化块)在每次实例化对象时执行,在构造方法之前执行。
(3)构造函数
构造函数在对象创建时调用,用于初始化对象的基本信息。
4. 属性赋值阶段
在Bean实例化后,Spring会进行依赖注入,分为以下几种方式:
(1)
@
Resource注入或者@Autowired注入通过
@Autowired
注解,Spring会自动装配被标注的字段、方法或构造函数。(2)
@Value
注入通过
@Value
注解,Spring会将外部配置文件中的值注入到Bean的字段中。
5. Aware 接口回调
如果Bean实现了各种
Aware
接口(如BeanNameAware
、BeanFactoryAware
、ApplicationContextAware
等),Spring会在属性赋值后调用相应的方法。
public class MyBean implements ApplicationContextAware {
@Override
public void setApplicationContext(ApplicationContext applicationContext) {
System.out.println("ApplicationContext set in MyBean");
}
}
6. Bean后处理器(BeanPostProcessor
)
在
BeanPostProcessor
接口的实现类中,Spring允许在初始化方法调用前后对Bean进行自定义修改。这些方法包括:
postProcessBeforeInitialization
postProcessAfterInitialization
7. 初始化方法
(1)
@PostConstruct
注解在依赖注入完成后,调用标注了
@PostConstruct
的初始化方法。
@PostConstruct
public void init() {
System.out.println("PostConstruct of MyBean");
}
(2) 初始化回调(
InitializingBean
接口)如果Bean实现了
InitializingBean
接口,则会调用其afterPropertiesSet
方法。
public class MyBean implements InitializingBean {
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("afterPropertiesSet of MyBean");
}
}
(3) 自定义初始化方法
如果在配置中指定了init-method,Spring会调用这个自定义的初始化方法。
8. 在容器中使用Bean
在所有的初始化步骤完成之后,Bean就可以在容器中被使用了。
9. 销毁阶段
当Spring容器关闭时,会进行Bean的销毁工作。如果Bean实现了
DisposableBean
接口,或者配置了destroy-method
,Spring会调用相应的方法进行清理工作。
public class MyBean implements DisposableBean {
@Override
public void destroy() throws Exception {
System.out.println("destroy of MyBean");
}
}
总结
整个Bean加载和初始化的顺序如下:
- 类加载:静态代码块。
- 实例化:默认代码块 -> 构造函数。
- 依赖注入:
@Autowired
、@Value
。- Aware接口:各类
Aware
接口的方法。- BeanPostProcessor:前置处理器。
- 初始化方法:
@PostConstruct
->afterPropertiesSet
-> 自定义初始化方法。- BeanPostProcessor:后置处理器。
- 使用Bean。
- 销毁方法:
DisposableBean
-> 自定义销毁方法。