这篇文章是 IOC
容器初始化启动时,抽象类 AbstractAutowireCapableBeanFactory
的 doCreateBean()
方法里面的 initializeBean()
方法,它是进行 bean
的初始化的方法
阅读本篇文章,同时可以参考阅读 spring源码之getBean(获取 bean)方法解读(二) 和 Spring Aop代理对象的产生(一) 这两篇文章的 doCreateBean()
方法
initializeBean()
方法概览到此时,bean
已完成了如下两个重要工作
createBeanInstance()
方法:完成 bean
的实例化工作populateBean()
方法:完成 bean
的属性填充注入工作protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
// 对特殊的bean进行处理:实现了 Aware、BeanClassLoaderAware、BeanFactoryAware 的处理
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
// 激活 Aware 方法
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
}
else {
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
// 调用了bean后处理器的方法
// BeanPostProcessor 提供的方法,在bean初始化前调用,这时的 bean已完成了实例化和属性填充注入工作
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
// 激活自定义的init的方法
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
if (mbd == null || !mbd.isSynthetic()) {
// 调用bean后处理器的方法
// BeanPostProcessor 提供的方法,在bean初始化后调用,这时候的bean 已经创建完成了
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
Aware
接口的 bean
进行相关设置bean
后处理器的方法 applyBeanPostProcessorsBeforeInitialization()
InitializingBean
或者用户自定义的 init
方法方法bean
后处理器的方法 applyBeanPostProcessorsAfterInitialization()
:此处可以产生 aop
的代理对象initializeBean()
方法详解invokeAwareMethods()
方法实现 Aware
接口用于让 bean
能拥有某些额外的感知能力
bean
实现了 BeanNameAware
接口,则将 beanName
设置进去bean
实现了 BeanClassLoaderAware
接口,则将 ClassLoader
设置进去bean
实现了 BeanFactoryAware
接口,则将 beanFactory
设置进去private void invokeAwareMethods(final String beanName, final Object bean) {
if (bean instanceof Aware) {
if (bean instanceof BeanNameAware) {
((BeanNameAware) bean).setBeanName(beanName);
}
if (bean instanceof BeanClassLoaderAware) {
ClassLoader bcl = getBeanClassLoader();
if (bcl != null) {
((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
}
}
if (bean instanceof BeanFactoryAware) {
((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
}
}
}
applyBeanPostProcessorsBeforeInitialization()
方法(重点)@Override
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
// 获取所有实现了 BeanPostProcessors 接口的类,进行遍历
for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
// 核心方法:postProcessBeforeInitialization()
Object current = beanProcessor.postProcessBeforeInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
postProcessBeforeInitialization()
方法是 BeanPostProcessor
接口提供的方法,可以看到它是在 bean
初始化之前调用的,这时的 bean
已完成了实例化和属性填充注入工作
public interface BeanPostProcessor {
@Nullable
default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
@Nullable
default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
}
postProcessBeforeInitialization()
:在 bean
初始化之前调用,可以改变 bean
的一些属性postProcessAfterInitialization()
:在 bean
初始化之后调用,可以改变 bean
的一些属性关于 BeanPostProcessor
接口的详解可以查看:https://blog.csdn.net/qq_36882793/article/details/106040809
关于 BeanPostProcessor
接口的详细使用可以查看:https://blog.csdn.net/mamamalululu00000000/article/details/106547490
invokeInitMethods()
方法(重点)bean
的初始化方式除了可以在 xml
文件中配置 init-method
标签或使用注解@Bean(initMethod=" ")
,还可以通过实现 InitializingBean
接口,并且在 afterPropertiesSet()
方法中实现自己初始化的业务逻辑
调用顺序则是 afterPropertiesSet()
先调用,后面调用 init-method
指定的方法
Spring
为 bean
提供了两种初始化的方式,第一种是实现 InitializingBean
接口
xml
配置文件 init-method
标签来指定@Bean
注解中通过 initMethod
属性来指定两种方式可以同时使用。同时使用先调用 afterPropertiesSet()
方法,后执行 init-method
指定的方法
InitializingBean
接口是直接调用 afterPropertiesSet()
方法,与通过反射调用 init-method
指定的方法相比,效率相对来说要高点。但是 init-method
方式消除了对 Spring
的依赖afterPropertiesSet()
方法时出错,那么就不会调用 init-method
指定的方法了applyBeanPostProcessorsAfterInitialization()
方法(重点)@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
// 获取所有实现了 BeanPostProcessors 接口的类,进行遍历
for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
// 核心方法:postProcessAfterInitialization()
Object current = beanProcessor.postProcessAfterInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
postProcessAfterInitialization()
方法是 BeanPostProcessor
接口提供的方法,可以看到它是在 bean
初始化之后调用的,这时的 bean
已完成了实例化,属性填充注入,初始化的工作;可以认为是一个完整的 bean
已在 spring
容器中了
如果使用了 spring aop
功能,那么代理对象的产生就在这个 applyBeanPostProcessorsAfterInitialization()
方法中。注意产生代理对象的时机
bean
的实例化 createBeanInstance()
方法,属性填充注入populateBean()
方法之后的 initializeBean()
初始化方法中产生的initializeBean()
方法中的applyBeanPostProcessorsAfterInitialization()
方法具体产生Spring
中初始化 bean
的方式xml
配置文件中指定 init-method
标签@PostConstruct
注解InitializingBean
接口@Bean
注解指定@PostConstruct
注解@Service
public class AService {
@PostConstruct
public void init() {
System.out.println("===初始化===");
}
}
InitializingBean
接口@Service
public class BService implements InitializingBean {
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("===初始化===");
}
}
@Bean
注解使用 initMethod()
可以指定初始化方法
@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Bean {
@AliasFor("name")
String[] value() default {};
@AliasFor("value")
String[] name() default {};
Autowire autowire() default Autowire.NO;
String initMethod() default "";
String destroyMethod() default AbstractBeanDefinition.INFER_METHOD;
}