一 总结
总结下Spring几个基础后置处理器的使用方法和调用时机
二 BeanFactoryPostPrecessor
作用于所有被Spring管理的类都转换成BeanDifinition缓存到BeanDifinitionMap中但还都未进行实例化中调用,可以在此时操作BeanDifinition,可以有多个并且可以使用Order接口进行排序。
@Component
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
//拿到容器
DefaultListableBeanFactory defaultListableBeanFactory = (DefaultListableBeanFactory)beanFactory;
//通过容器拿到想操作的BeanDefinition
BeanDefinition cat = defaultListableBeanFactory.getBeanDefinition("cat");
}
}
触发时机在Spring最核心的方法refresh()中
invokeBeanFactoryPostProcessors()中触发
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory);
// Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);
// Initialize message source for this context.
initMessageSource();
// Initialize event multicaster for this context.
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
onRefresh();
// Check for listener beans and register them.
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
finishRefresh();
}
catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
// Destroy already created singletons to avoid dangling resources.
destroyBeans();
// Reset 'active' flag.
cancelRefresh(ex);
// Propagate exception to caller.
throw ex;
}
finally {
// Reset common introspection caches in Spring's core, since we
// might not ever need metadata for singleton beans anymore...
resetCommonCaches();
}
}
}
调用时会区分是普通的BeanFactoryPostPrecessor还是BeanDefinitionRegistryPostProcessor。因为BeanDefinitionRegistryPostProcessor先于普通的BeanFactoryPostPrecessor被触发,他在触发时普通后置处理器还未进行调用,BeanDefinitionRegistryPostProcessor全部执行完才会触发普通的,所有也可以在BeanDefinitionRegistryPostProcessor中添加新的BeanFactoryPostPrecessor。
三 BeanPostPrecessor
在Bean属性注入后,初始化前后被调用,可以在此进行一些逻辑操作。
public class MyBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
//通过反射对bean进行操作
bean.getClass();
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
//通过反射对bean进行操作
bean.getClass();
return bean;
}
}
他的触发时机是在doCreateBean()方法中initializeBean()中触发
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;
}
applyBeanPostProcessorsBeforeInitialization()和applyBeanPostProcessorsAfterInitialization()就是触发的两个方法
四 InstantiationAwareBeanPostProcessor
他是BeanPostPrecessor的子类,所有除了原有两个方法以外还多了三个方法
@Component
public class MyInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor {
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
return null;
}
@Override
public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
return false;
}
@Override
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
return null;
}
}
1. postProcessBeforeInstantiation()
该方法是在createBean()时在真正创建Bean的doCreateBean()方法执行前被调用,方法为resolveBeforeInstantiation()
@Nullable
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
Object bean = null;
if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
// Make sure bean class is actually resolved at this point.
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
Class<?> targetType = determineTargetType(beanName, mbd);
if (targetType != null) {
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
if (bean != null) {
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
}
}
mbd.beforeInstantiationResolved = (bean != null);
}
return bean;
}
2. postProcessAfterInstantiation()
改方法在doCreateBean()中的populateBean()被调用
boolean continueWithPropertyPopulation = true;
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
continueWithPropertyPopulation = false;
break;
}
}
}
}
if (!continueWithPropertyPopulation) {
return;
}
可以看到如果返回true则continueWithPropertyPopulation被修改成false,最后直接return就不走下面的流程了,而postProcessProperties()方法就不会被调用了
3. postProcessProperties()
在该方法修改Bean的属性值。@Autowired 就是通过实现了InstantiationAwareBeanPostProcessor的类AutowiredAnnotationBeanPostProcessor通过该方法将属性注入