您现在的位置是:首页 >技术教程 >Spring IOC - Bean的初始化网站首页技术教程
Spring IOC - Bean的初始化
在bean的初始化阶段,bean已经被实例化及属性填充了,此时的bean已相对成熟,接下来的初始化阶段还会做一些额外的工作对bean做进一步处理,主要包括以下四个方面:
-
调用aware接口方法
-
初始化前:调用初始化前的后置处理器方法
-
初始化:调用InitializingBean接口的afterPropertiesSet方法
-
初始化后:调用初始化后的后置处理器方法
1. Bean初始化主流程
AbstractAutowireCapableBeanFactory#initializeBean
运用aware回调接口、afterPropertiesSet方法、后置处理器完成bean实例的初始化
// 运用aware回调接口、afterPropertiesSet方法、后置处理器完成bean实例的初始化
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
}
else {
// 1.调用aware接口的方法
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
// 2.调用初始化前后置处理器
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
// 3.调用初始化方法,其实就是afterPropertiesSet方法
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()) {
// 4.调用初始化后后置处理器
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
2. Aware接口调用
如果Bean实现了BeanNameAware、BeanClassLoaderAware、BeanFactoryAware接口,则会调用相应接口的方法。
- BeanNameAware:在Bean实例化后进行扩展操作,可以获取Bean的名称
- BeanClassLoaderAware:在Bean实例化后进行扩展操作,可以获取Bean的类加载器
- BeanFactoryAware:在Bean实例化后进行扩展操作,可以获取Bean所属的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);
}
}
}
3. 初始化前:调用初始化前的后置处理器方法
这里涉及到了Bean后置处理器:BeanPostProcessor,其作用如下:
-
spring会自动从它的所有的bean定义中检测BeanPostProcessor类型的bean定义,然后实例化它们,再将它们应用于随后创建的每一个bean实例
-
在bean实例的初始化方法回调之前调用BeanPostProcessor的postProcessBeforeInitialization的方法
-
在bean实例的初始化方法回调之后调用BeanPostProcessor的postProcessAfterInitialization的方法
-
通常,通过标记接口等方式填充bean的后置处理器会实现postProcessBeforeInitialization方法,而将bean包装为代理的后置处理器会实现postProcessAfterInitialization方法
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;
}
}
@Override
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) {
Object current = processor.postProcessBeforeInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
例如ApplicationContextAwareProcessor后置处理器,其重写了postProcessBeforeInitialization方法,如果bean实现了EnvironmentAware、EmbeddedValueResolverAware、ResourceLoaderAware、ApplicationEventPublisherAware、MessageSourceAware、ApplicationContextAware接口,则会调用响应接口的方法
- EnvironmentAware:在Bean实例化后进行扩展操作,可以获取Environment实例
- EmbeddedValueResolverAware:在Bean实例化后进行扩展操作,可以获取StringValueResolver实例,可用于解析占位符
- ResourceLoaderAware:在Bean实例化后进行扩展操作,可以获取ResourceLoader实例
- ApplicationEventPublisherAware:在Bean实例化后进行扩展操作,可以获取ApplicationEventPublisher实例
- MessageSourceAware:在Bean实例化后进行扩展操作,可以获取MessageSource实例
- ApplicationContextAware:在Bean实例化后进行扩展操作,可以获取ApplicationContext实例
4. 初始化:调用InitializingBean接口的afterPropertiesSet方法或自定义的init方法
protected void invokeInitMethods(String beanName, final Object bean, @Nullable RootBeanDefinition mbd)
throws Throwable {
boolean isInitializingBean = (bean instanceof InitializingBean);
if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
if (logger.isTraceEnabled()) {
logger.trace("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
}
if (System.getSecurityManager() != null) {
try {
AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
((InitializingBean) bean).afterPropertiesSet();
return null;
}, getAccessControlContext());
}
catch (PrivilegedActionException pae) {
throw pae.getException();
}
}
else {
// 调用afterPropertiesSet方法
((InitializingBean) bean).afterPropertiesSet();
}
}
if (mbd != null && bean.getClass() != NullBean.class) {
String initMethodName = mbd.getInitMethodName();
if (StringUtils.hasLength(initMethodName) &&
!(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
!mbd.isExternallyManagedInitMethod(initMethodName)) {
// 调用自定义的init方法
invokeCustomInitMethod(beanName, bean, mbd);
}
}
}
5. 初始化后:调用初始化后的后置处理器方法
@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) {
Object current = processor.postProcessAfterInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}