初始化流程概要
1.invokeAwareMethods
(1)BeanNameAware.setBeanName
(2)BeanClassLoaderAware.setBeanClassLoader
(3)BeanFactoryAware.setBeanFactory
2.接着调用BeanPostProcessor.postProcessBeforeInitialization方法
(1) org.springframework.context.support.ApplicationContextAwareProcessor
- EnvironmentAware.setEnvironment
- EmbeddedValueResolverAware.setEmbeddedValueResolver
- ResourceLoaderAware.setResourceLoader
- ApplicationEventPublisherAware.setApplicationEventPublisher
- MessageSourceAware.setMessageSource
- ApplicationContextAware.setApplicationContext
(2) org.springframework.web.context.support.ServletContextAwareProcessor
- ServletContextAware.setServletContext
- ServletConfigAware.setServletConfig
(3) org.springframework.context.annotation.ConfigurationClassPostProcessor.ImportAwareBeanPostProcessor
- ImportAware.setImportMetadata
(4) org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor
- 与@ConfigurationProperties 和Validated注解相关,感兴趣可观看
(5) org.springframework.boot.web.server.WebServerFactoryCustomizerBeanPostProcessor
if (bean instanceof WebServerFactory) {
WebServerFactoryCustomizer。customize(((WebServerFactory) bean);
}
(6) org.springframework.context.annotation.CommonAnnotationBeanPostProcessor
- 调用@PostConstruct注解作用的方法
(7) org.springframework.boot.test.autoconfigure.properties.PropertyMappingContextCustomizer.PropertyMappingCheckBeanPostProcessor
- @Component和@PropertyMapping注解的处理
(8)....
3.调用初始化方法
(1) 当前 bean 实现了 InitializingBean 会调用InitializingBean.afterPropertiesSet()方法
- 但是@PostConstruct修饰的方法名称为afterPropertiesSet不会调用InitializingBean.afterPropertiesSet()方法
(2)@Bean的initMethod属性如果定义了初始化方法名称,也会调用
- 但是如果Bean的initMethod属性定义的初始化名称为afterPropertiesSet
- 当前bean实现了InitializingBean接口
- @PostConstruct修饰的方法名称为afterPropertiesSet
这三种情况都不会调用Bean的initMethod属性定义的初始化方法
4.初始化
(1) org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator
- 与AOP有关
(2) org.springframework.aop.framework.AbstractAdvisingBeanPostProcessor
- 与AOP有关
(3)org.springframework.context.support.ApplicationListenerDetector
applicationContext.addApplicationListener((ApplicationListener) 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 {
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
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()) {
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
1.invokeAwareMethods
当前bean实现了,**Aware接口调用其实现方法
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);
}
}
}
2.调用BeanPostProcessor.postProcessBeforeInitialization方法
调用@PostConstruct修饰的方法(包含父类)
org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor
class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBeanPostProcessor
public CommonAnnotationBeanPostProcessor() {
//定义bean初始化方法需要的注解
setInitAnnotationType(PostConstruct.class);
//定义bean销毁方法需要的注解
setDestroyAnnotationType(PreDestroy.class);
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
//找出bean所有@PostConstruct注解和(PreDestroy注解的方法
LifecycleMetadata metadata = findLifecycleMetadata(bean.getClass());
try {
//调用@PostConstruct注解修饰方法
metadata.invokeInitMethods(bean, beanName);
}
catch (InvocationTargetException ex) {
throw new BeanCreationException(beanName, "Invocation of init method failed", ex.getTargetException());
}
catch (Throwable ex) {
throw new BeanCreationException(beanName, "Failed to invoke init method", ex);
}
return bean;
}
private LifecycleMetadata findLifecycleMetadata(Class<?> clazz) {
//缓存找出的bean所有@PostConstruct注解和(PreDestroy注解的方法,有缓存数据,从缓存数据中获取,没有才会解析
if (this.lifecycleMetadataCache == null) {
return buildLifecycleMetadata(clazz);
}
LifecycleMetadata metadata = this.lifecycleMetadataCache.get(clazz);
if (metadata == null) {
synchronized (this.lifecycleMetadataCache) {
metadata = this.lifecycleMetadataCache.get(clazz);
if (metadata == null) {
metadata = buildLifecycleMetadata(clazz);
this.lifecycleMetadataCache.put(clazz, metadata);
}
return metadata;
}
}
return metadata;
}
怎么找出@PostConstruct注解修饰的方法和@DestoryConstruct方法
不仅仅会获取当前Class的@PostConstruct注解修饰的方法和@DestoryConstruct方法,还会依次递归获取父类的。但是在当前环节只调用@PostConstruct注解修饰的方法
private LifecycleMetadata buildLifecycleMetadata(final Class<?> clazz) {
List<LifecycleElement> initMethods = new ArrayList<>();
List<LifecycleElement> destroyMethods = new ArrayList<>();
Class<?> targetClass = clazz;
do {
final List<LifecycleElement> currInitMethods = new ArrayList<>();
final List<LifecycleElement> currDestroyMethods = new ArrayList<>();
ReflectionUtils.doWithLocalMethods(targetClass, method -> {
if (this.initAnnotationType != null && method.isAnnotationPresent(this.initAnnotationType)) {
LifecycleElement element = new LifecycleElement(method);
currInitMethods.add(element);
if (logger.isTraceEnabled()) {
logger.trace("Found init method on class [" + clazz.getName() + "]: " + method);
}
}
if (this.destroyAnnotationType != null && method.isAnnotationPresent(this.destroyAnnotationType)) {
currDestroyMethods.add(new LifecycleElement(method));
if (logger.isTraceEnabled()) {
logger.trace("Found destroy method on class [" + clazz.getName() + "]: " + method);
}
}
});
initMethods.addAll(0, currInitMethods);
destroyMethods.addAll(currDestroyMethods);
targetClass = targetClass.getSuperclass();
}
while (targetClass != null && targetClass != Object.class);
return new LifecycleMetadata(clazz, initMethods, destroyMethods);
}