😀 这里写文章的前言: 一个简单的开头,简述这篇文章讨论的问题、目标、人物、背景是什么?并简述你给出的答案。
可以说说你的故事:阻碍、努力、结果成果,意外与转折。
📝 SpringBoot中BeanPostProcessor BeanPostProcessor 是在Spring中实例化bean的时候使用到的,也是对bean的一种扩展. 理解好 BeanPostProcessor是对理解好 bean 的初始化是很重要的. 每种BeanPostProcessor都有各自不同的用途.
看下 BeanPostProcessor 这个接口,是只有 postProcessBeforeInitialization 和 postProcessAfterInitialization 这二种方法的,并且都是用 default来进行修饰,也就是实现这个接口的时候,可以实现其方法,也可以不用实现其方法的,这就是接口上的方法使用 default 来进行修饰的情况.
ApplicationContextAwareProcessor
WebApplicationContextServletContextAwareProcessor
ConfigurationClassPostProcessor.ImportAwareBeanPostProcessor (内部类)
PostProcessorRegistrationDelegate.BeanPostProcessorChecker(内部类)
ConfigurationPropertiesBindingPostProcessor
WebServerFactoryCustomizerBeanPostProcessor
ErrorPageRegistrarBeanPostProcessor
CommonAnnotationBeanPostProcessor
AutowiredAnnotationBeanPostProcessor
ApplicationListenerDetector
如果没有对 SpringBoot 中的beanPostProcessor 进行扩展什么的话, 那么当你创建bean的时候,应该是十个的样子(当然了,这是基于目前的版本的).
如果你看看这十个 beanPostProcessor,其中有的是直接继承 BeanPostProcessor, 有的是 集成其BeanPostProceesor的子类,但是最顶层的话,就是BeanPostProcessor. 需要结合 doCreateBean这个方法一起看了,当其创建一个 bean 的时候, 是怎么使用这些 beanPostProcessor进行扩展的.
beanPostProcessor 添加 AbstractBeanFactory#beanPostProcessors 可以看到beanFactory中的beanPostProcessors属性字段,该字段就是对BeanPostProcessor进行存储的集合.
在 refresh() 方法中进行添加 beanPostProcessor进来的 可以看到主要添加 beanPostProcessor进来的地方是 registerBeanPostProcessors 方法. 可以看到这里是添加了 十二个.
走完 prepareBeanFactory方法: 添加了 ApplicationContextAwareProceesor和ApplicationListenerDetector
postProcessBeanFactory 走完 : 添加 WebApplicationContextServletContextAwareProceesor
invokeBeanFactoryPostProcessors 走完: 添加 ConfigurationClassPostProcessor$ImportAwareBeanPostProcessor 进来
registerBeanPostProcessors 走完 : PostProcessorRegisrationDelegate$BeanPostProceesorChecker/ConfigurationPropertiesBindingPostProcessor/AsyncAnnotationBeanPostProcessor/WebServerFactoryCustomizerBeanPostProcessor/ErrorPageRegistrarBeanPostProcessor/CommonAnnotationBeanPostProcessor/ScheduleAnnotationBeanPostProcessor/ApplicationListenerDetector
ApplicationContextAwareProcessor 该Processor的针对性还是比较强的,主要就是处理 EnvironmentAware/EmbeddedValueResolverAware/ResourceLoaderAware/ApplicationEventPublisherAware/MessageSourceAware/ApplicationContextAware 这几种情况的
@Override @Nullable public Object postProcessBeforeInitialization (Object bean, String beanName) throws BeansException { if (!(bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware || bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware || bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware)){ return bean; } AccessControlContext acc = null ; if (System.getSecurityManager() != null ) { acc = this .applicationContext.getBeanFactory().getAccessControlContext(); } if (acc != null ) { AccessController.doPrivileged((PrivilegedAction<Object>) () -> { invokeAwareInterfaces(bean); return null ; }, acc); } else { invokeAwareInterfaces(bean); } return bean; }
WebApplicationContextServletContextAwareProcessor 该类继承了org.springframework.web.context.support.ServletContextAwareProcessor,先看其父类重写PostProcessor的方法.
可以看到这个 Processor 主要就是处理 web 环境的. 也就是在有web环境的情况下, 对 bean 是 ServletContextAware和ServletConfigAware的进行处理.
@Override public Object postProcessBeforeInitialization (Object bean, String beanName) throws BeansException { if (getServletContext() != null && bean instanceof ServletContextAware) { ((ServletContextAware) bean).setServletContext(getServletContext()); } if (getServletConfig() != null && bean instanceof ServletConfigAware) { ((ServletConfigAware) bean).setServletConfig(getServletConfig()); } return bean; } @Override public Object postProcessAfterInitialization (Object bean, String beanName) { return bean; }
ImportAwareBeanPostProcessor ImportAwareBeanPostProcessor –> InstantiationAwareBeanPostProcessorAdapter –> SmartInstantiationAwareBeanPostProcessor —> SmartInstantiationAwareBeanPostProcessor –> InstantiationAwareBeanPostProcessor —> BeanPostProcessor
可以看到, 该 BeanPostProcessor 其上面的接口和类还是蛮多的. 从该 postProcessor的名字上看,其要做的功能还是很好晓得的,那就是做关于 @Import 这些相关的.
TODO : 后续 debug 进行跟进看
@Override public PropertyValues postProcessProperties (@Nullable PropertyValues pvs, Object bean, String beanName) { if (bean instanceof EnhancedConfiguration) { ((EnhancedConfiguration) bean).setBeanFactory(this .beanFactory); } return pvs; } @Override public Object postProcessBeforeInitialization (Object bean, String beanName) { if (bean instanceof ImportAware) { ImportRegistry ir = this .beanFactory.getBean(IMPORT_REGISTRY_BEAN_NAME, ImportRegistry.class); AnnotationMetadata importingClass = ir.getImportingClassFor(ClassUtils.getUserClass(bean).getName()); if (importingClass != null ) { ((ImportAware) bean).setImportMetadata(importingClass); } } return bean; } }
BeanPostProcessorChecker 该 PostProcessor 是直接继承 BeanPostProcessor 的, 所以看这二个重写的方法即可.
可以看到该 BeanPostProcessor是对初始化完了后进行检查,如果满足条件的话,就会打印一句log出来. log里面的主要内容就是,不符合自动代理的条件.
@Override public Object postProcessBeforeInitialization (Object bean, String beanName) { return bean; } @Override public Object postProcessAfterInitialization (Object bean, String beanName) { if (!(bean instanceof BeanPostProcessor) && !isInfrastructureBean(beanName) && this .beanFactory.getBeanPostProcessorCount() < this .beanPostProcessorTargetCount) { if (logger.isInfoEnabled()) { logger.info("Bean '" + beanName + "' of type [" + bean.getClass().getName() + "] is not eligible for getting processed by all BeanPostProcessors " + "(for example: not eligible for auto-proxying)" ); } } return bean; }
ConfigurationPropertiesBindingPostProcessor 该PostProcessor是直接实现了BeanPostProcessor 接口的, 但是该类也实现了ApplicationContextAware和InitializingBean这二个方法的. ApplicationContextAware 是提供application的, InitializingBean 方法是在初始完该bean后,调用afterPropertiesSet进行回调的
@Override public Object postProcessBeforeInitialization (Object bean, String beanName) throws BeansException { bind(ConfigurationPropertiesBean.get(this .applicationContext, bean, beanName)); return bean; } --------------------------------- public static ConfigurationPropertiesBean get (ApplicationContext applicationContext, Object bean, String beanName) { Method factoryMethod = findFactoryMethod(applicationContext, beanName); return create(beanName, bean, bean.getClass(), factoryMethod); } private static Method findFactoryMethod (ApplicationContext applicationContext, String beanName) { if (applicationContext instanceof ConfigurableApplicationContext) { return findFactoryMethod((ConfigurableApplicationContext) applicationContext, beanName); } return null ; } private static Method findFactoryMethod (ConfigurableListableBeanFactory beanFactory, String beanName) { if (beanFactory.containsBeanDefinition(beanName)) { BeanDefinition beanDefinition = beanFactory.getMergedBeanDefinition(beanName); if (beanDefinition instanceof RootBeanDefinition) { Method resolvedFactoryMethod = ((RootBeanDefinition) beanDefinition).getResolvedFactoryMethod(); if (resolvedFactoryMethod != null ) { return resolvedFactoryMethod; } } return findFactoryMethodUsingReflection(beanFactory, beanDefinition); } return null ; } private static Method findFactoryMethodUsingReflection (ConfigurableListableBeanFactory beanFactory, BeanDefinition beanDefinition) { String factoryMethodName = beanDefinition.getFactoryMethodName(); String factoryBeanName = beanDefinition.getFactoryBeanName(); if (factoryMethodName == null || factoryBeanName == null ) { return null ; } Class<?> factoryType = beanFactory.getType(factoryBeanName); if (factoryType.getName().contains(ClassUtils.CGLIB_CLASS_SEPARATOR)) { factoryType = factoryType.getSuperclass(); } AtomicReference<Method> factoryMethod = new AtomicReference <>(); ReflectionUtils.doWithMethods(factoryType, (method) -> { if (method.getName().equals(factoryMethodName)) { factoryMethod.set(method); } }); return factoryMethod.get(); }
WebServerFactoryCustomizerBeanPostProcessor 该 PostProcessor 是有实现 BeanFactoryAware 的,实现该接口是可以获取到 beanFactory的. 然后 赋值给其自身的参数. 也就是说该类是有一个 beanFactory的.
可以看到该 postProcessor 主要处理 bean 是 WebServerFactory的
@Override public Object postProcessBeforeInitialization (Object bean, String beanName) throws BeansException { if (bean instanceof WebServerFactory) { postProcessBeforeInitialization((WebServerFactory) bean); } return bean; } @Override public Object postProcessAfterInitialization (Object bean, String beanName) throws BeansException { return bean; }
该 PostProcessor 也是实现了 BeanFactoryAware 接口的,所以其内部也是有一个 ListableBeanFactory 的.
可以看到该 PostProcessor 主要就是 设置 ErrorPage 的.
@Override public Object postProcessBeforeInitialization (Object bean, String beanName) throws BeansException { if (bean instanceof ErrorPageRegistry) { postProcessBeforeInitialization((ErrorPageRegistry) bean); } return bean; } @Override public Object postProcessAfterInitialization (Object bean, String beanName) throws BeansException { return bean; }
CommonAnnotationBeanPostProcessor 该类继承了 InitDestroyAnnotationBeanPostProcessor , 实现了InstantiationAwareBeanPostProcessor/BeanFactoryAware 接口,
实现了 BeanFactoryAware 接口,就是相当于获取到了 beanFactory,可以看到下面的setBeanFactory方法.
该PostProcessor 主要是处理一些 @Resource注解,其父类处理@PostConstruct和@PreDestroy注解修饰的方法.
@Override public void setBeanFactory (BeanFactory beanFactory) { Assert.notNull(beanFactory, "BeanFactory must not be null" ); this .beanFactory = beanFactory; if (this .resourceFactory == null ) { this .resourceFactory = beanFactory; } if (beanFactory instanceof ConfigurableBeanFactory) { this .embeddedValueResolver = new EmbeddedValueResolver ((ConfigurableBeanFactory) beanFactory); } } ----------------------------------- @Override public void postProcessMergedBeanDefinition (RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) { super .postProcessMergedBeanDefinition(beanDefinition, beanType, beanName); InjectionMetadata metadata = findResourceMetadata(beanName, beanType, null ); metadata.checkConfigMembers(beanDefinition); } ------------------------------------------- @Override public PropertyValues postProcessProperties (PropertyValues pvs, Object bean, String beanName) { InjectionMetadata metadata = findResourceMetadata(beanName, bean.getClass(), pvs); try { metadata.inject(bean, beanName, pvs); } catch (Throwable ex) { throw new BeanCreationException (beanName, "Injection of resource dependencies failed" , ex); } return pvs; }
其父类 InitDestroyAnnotationBeanPostProcessor
@Override public Object postProcessBeforeInitialization (Object bean, String beanName) throws BeansException { LifecycleMetadata metadata = findLifecycleMetadata(bean.getClass()); try { 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; } @Override public void postProcessBeforeDestruction (Object bean, String beanName) throws BeansException { LifecycleMetadata metadata = findLifecycleMetadata(bean.getClass()); try { metadata.invokeDestroyMethods(bean, beanName); } catch (InvocationTargetException ex) { String msg = "Destroy method on bean with name '" + beanName + "' threw an exception" ; if (logger.isDebugEnabled()) { logger.warn(msg, ex.getTargetException()); } else { logger.warn(msg + ": " + ex.getTargetException()); } } catch (Throwable ex) { logger.warn("Failed to invoke destroy method on bean with name '" + beanName + "'" , ex); } }
AutowiredAnnotationBeanPostProcessor @Override public PropertyValues postProcessProperties (PropertyValues pvs, Object bean, String beanName) { InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs); try { metadata.inject(bean, beanName, pvs); } catch (BeanCreationException ex) { throw ex; } catch (Throwable ex) { throw new BeanCreationException (beanName, "Injection of autowired dependencies failed" , ex); } return pvs; } -------------------- @Override @Nullable public Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, final String beanName) throws BeanCreationException { .................. Constructor<?>[] candidateConstructors = this .candidateConstructorsCache.get(beanClass); if (candidateConstructors == null ) { synchronized (this .candidateConstructorsCache) { candidateConstructors = this .candidateConstructorsCache.get(beanClass); if (candidateConstructors == null ) { Constructor<?>[] rawCandidates; try { rawCandidates = beanClass.getDeclaredConstructors(); } catch (Throwable ex) { throw new BeanCreationException (beanName, "Resolution of declared constructors on bean Class [" + beanClass.getName() + "] from ClassLoader [" + beanClass.getClassLoader() + "] failed" , ex); } List<Constructor<?>> candidates = new ArrayList <>(rawCandidates.length); Constructor<?> requiredConstructor = null ; Constructor<?> defaultConstructor = null ; Constructor<?> primaryConstructor = BeanUtils.findPrimaryConstructor(beanClass); int nonSyntheticConstructors = 0 ; for (Constructor<?> candidate : rawCandidates) {} if (!candidates.isEmpty()) { ........ else { candidateConstructors = new Constructor <?>[0 ]; } }
ApplicationListenerDetector 可以看到该类自己内部维护了一个 application 和 singletonNames(集合) 的.
该BeanPostProcess 可以看到初始完后调用的回调方法,根据beanName获取出true的哈,就往application中添加ApplicationListener进来.
销毁之前,也是对application中ApplicationListener进行remove
@Override public Object postProcessAfterInitialization (Object bean, String beanName) { if (bean instanceof ApplicationListener) { Boolean flag = this .singletonNames.get(beanName); if (Boolean.TRUE.equals(flag)) { this .applicationContext.addApplicationListener((ApplicationListener<?>) bean); } else if (Boolean.FALSE.equals(flag)) { if (logger.isWarnEnabled() && !this .applicationContext.containsBean(beanName)) { logger.warn("Inner bean '" + beanName + "' implements ApplicationListener interface " + "but is not reachable for event multicasting by its containing ApplicationContext " + "because it does not have singleton scope. Only top-level listener beans are allowed " + "to be of non-singleton scope." ); } this .singletonNames.remove(beanName); } } return bean; } @Override public void postProcessBeforeDestruction (Object bean, String beanName) { if (bean instanceof ApplicationListener) { try { ApplicationEventMulticaster multicaster = this .applicationContext.getApplicationEventMulticaster(); multicaster.removeApplicationListener((ApplicationListener<?>) bean); multicaster.removeApplicationListenerBean(beanName); } catch (IllegalStateException ex) { } } }
🤗 总结归纳 除了SpringBoot中没有做任何配置中有的这些之外,肯定是还有很多其他的.
当你在debug的时候,你会发现,有一些 processor 在初始化之前的名字 : 比如:org.springframework.context.annotation.internalAutowiredAnnotationProcessor ,其实它就是一个AutowiredAnnotationProcessor才是正确的,但是该名字前面却是有 internal 这个单词的,也就是内部的意思. 所以从名字上看,还是可以通过名字进行初始化区分的.
📎 参考文章
💡 有关文章的问题,欢迎您在底部评论区留言,一起交流~