InstantiationAwareBeanPostProcessor 接口继承了 BeanPostProcessor 接口。
BeanPostProcessor 次要是在 Bean 调用初始化办法前后进行拦挡。
而 InstantiationAwareBeanPostProcessor 接口在 BeanPostProcessor 根底上增加了对 bean 的创立前后,以及设置属性前进行拦挡。
它的办法如下:
办法 | 执行程序 | 备注 |
---|---|---|
postProcessBeforeInstantiation() | 在 Bean 创立前调用 | 可用于创立代理类,如果返回的不是 null(也就是返回的是一个代理类) ,那么后续只会调用 postProcessAfterInitialization() 办法 |
postProcessAfterInstantiation() | 在 Bean 创立后调用 | 返回值会影响 postProcessProperties() 是否执行,其中返回 false 的话,是不会执行。 |
postProcessProperties() | 在 Bean 设置属性前调用 | 用于批改 bean 的属性,如果返回值不为空,那么会更改指定字段的值 |
postProcessBeforeInitialization() | 在 Bean 调用初始化办法前调用 | 容许去批改 bean 实例化后,没有调用初始化办法前状态的属性 |
postProcessAfterInitialization() | 在 Bean 调用初始化办法后调用 | 容许去批改 bean 调用初始化办法后状态的属性 |
验证
TestBean 类
public class TestBean implements InitializingBean { protected Object field; public TestBean() { System.out.println("创立 TestBean 对象"); } public Object getField() { return field; } public void setField(Object field) { System.out.println("设置 field 属性"); this.field = field; } @Override public void afterPropertiesSet() throws Exception { System.out.println("调用初始化办法"); } @Override public String toString() { return "TestBean{" + "field=" + field + '}'; }}
InstantiationAwareBeanPostProcessor 类
/*** InstantiationAwareBeanPostProcessor 的实现类*/public class CustomInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor { @Override public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException { if(isMatchClass(beanClass)){ System.out.println("调用 postProcessBeforeInstantiation 办法"); } return null; } @Override public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException { if(isMatchClass(bean.getClass())){ System.out.println("调用 postProcessAfterInstantiation 办法"); } return true; } @Override public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException { if(isMatchClass(bean.getClass())){ System.out.println("调用 postProcessProperties 办法"); } return pvs; } @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { if(isMatchClass(bean.getClass())){ System.out.println("调用 postProcessBeforeInitialization 办法"); } return bean; } @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { if(isMatchClass(bean.getClass())){ System.out.println("调用 postProcessAfterInitialization 办法"); } return bean; } private boolean isMatchClass(Class<?> beanClass){ // ClassUtils 类为 org.springframework.util.ClassUtils return TestBean.class.equals(ClassUtils.getUserClass(beanClass)); }}
测试类
@SpringBootTestpublic class CustomProcessorTest { @Autowired private ApplicationContext applicationContext; @Test void test(){ TestBean testBean = applicationContext.getBean(TestBean.class); System.out.println(testBean); } /** * 创立 TestBean 和 CustomInstantiationAwareBeanPostProcessor 这2个 bean */ @TestConfiguration static class TestConfig{ @Bean public TestBean getTestBean(){ TestBean testBean = new TestBean(); testBean.setField("1"); return testBean; } @Bean public CustomInstantiationAwareBeanPostProcessor customInstantiationAwareBeanPostProcessor(){ return new CustomInstantiationAwareBeanPostProcessor(); } }}
执行后果
调用 postProcessBeforeInstantiation 办法创立 TestBean 对象设置 field 属性调用 postProcessAfterInstantiation 办法调用 postProcessProperties 办法调用 postProcessBeforeInitialization 办法调用初始化办法调用 postProcessAfterInitialization 办法TestBean{field=1}
分析方法
1. postProcessBeforeInstantiation()
postProcessBeforeInstantiation() 办法是在 Bean 创立之前调用的,该办法容许咱们返回 Bean 的其余子类(咱们也能够用 cglib 返回一个代理对象)。
这个办法在 InstantiationAwareBeanPostProcessor 接口的默认实现是返回 null。
论断
如果 postProcessBeforeInstantiation() 返回的不是 null ,那么 Spring 只会在 Bean 创立的时候,
只调用 postProcessBeforeInstantiation() 和 postProcessAfterInitialization() 办法。
验证
批改 CustomInstantiationAwareBeanPostProcessor 的 postProcessBeforeInstantiation() 办法:
@Overridepublic Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException { if (isMatchClass(beanClass)) { System.out.println("调用 postProcessBeforeInstantiation 办法"); Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(beanClass); enhancer.setCallback((MethodInterceptor) (obj, method, args, proxy) -> { System.out.println("指标办法执行前:" + method); Object object = proxy.invokeSuper(obj, args); System.out.println("指标办法执行后:" + method); return object; }); return enhancer.create(); } return null;}
执行后果:
调用 postProcessBeforeInstantiation 办法创立 TestBean 对象调用 postProcessAfterInitialization 办法指标办法执行前:public java.lang.String TestBean.toString()指标办法执行后:public java.lang.String TestBean.toString()TestBean{field=null}
从执行后果中看,Spring 容器只执行了 postProcessBeforeInstantiation() 和 postProcessAfterInitialization() 办法,CustomInstantiationAwareBeanPostProcessor 其余的办法均不执行。
也没有执行 TestBean 的 setField() 和 afterPropertiesSet() 办法。
起因
从 Spring 创立 Bean 的过程中动手, Spring 在创立 Bean 时,会调用 AbstractAutowireCapableBeanFactory 的 createBean() 办法:
@Overrideprotected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException { // 省略下面的办法 try { // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance. Object bean = resolveBeforeInstantiation(beanName, mbdToUse); if (bean != null) { return bean; } } catch (Throwable ex) { throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, "BeanPostProcessor before instantiation of bean failed", ex); } try { Object beanInstance = doCreateBean(beanName, mbdToUse, args); if (logger.isTraceEnabled()) { logger.trace("Finished creating instance of bean '" + beanName + "'"); } return beanInstance; } // 省略上面的办法}
从 createBean() 的代码片段中,它先去调用 resolveBeforeInstantiation() 办法来尝试获取代理类,如果获取到了,就间接返回该代理类。
否则就去调用 doCreateBean() 办法,以创立 bean 的实例,并且返回。
resolveBeforeInstantiation() 办法以及调用到的关联办法:
@Nullableprotected 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;}@Nullableprotected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) { for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) { // 这里会遍历每一个 InstantiationAwareBeanPostProcessor 的子类,所以 InstantiationAwareBeanPostProcessor 的子类程序很重要 Object result = bp.postProcessBeforeInstantiation(beanClass, beanName); // 如果返回的不为 null ,前面的所有 InstantiationAwareBeanPostProcessor 的子类就跳过执行了 if (result != null) { return result; } } return null;}@Overridepublic Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) throws BeansException { Object result = existingBean; for (BeanPostProcessor processor : getBeanPostProcessors()) { // 这里会遍历每一个 BeanPostProcessor 的子类,所以 BeanPostProcessor 的子类程序很重要 Object current = processor.postProcessAfterInitialization(result, beanName); // 如果返回的为 null ,前面的所有 BeanPostProcessor 的子类就跳过执行了 if (current == null) { return result; } result = current; } return result;}
从 resolveBeforeInstantiation() 办法的代码片段中,它的逻辑根本是这样:
- 遍历所有的 InstantiationAwareBeanPostProcessor 实现类,调用其 postProcessBeforeInstantiation() 办法。
- 如果 postProcessBeforeInstantiation() 办法返回值,那么就示意找到了代理类,那么就会完结遍历
- 如果步骤2没有找到代理类,那么 resolveBeforeInstantiation() 办法就根本执行完结,返回 null 值。
- 如果步骤2找到了代理类,就会遍历所有 BeanPostProcessor 的实现类,调用其 postProcessAfterInitialization() 办法。
- 如果 postProcessAfterInitialization() 办法返回的是 null , 那么就返回上一次遍历失去的后果,或者是代理类自身。
2. postProcessAfterInstantiation()
postProcessAfterInstantiation() 办法的返回值会影响 postProcessProperties() 是否会执行:
- false :不会执行
- true :执行
起因
下面曾经提及了 Spring 创立 Bean 是会调用 createBean() 办法,其中如果 postProcessBeforeInstantiation() 返回的值为 null 的话,就会执行 doCreateBean() 办法。
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException { // 疏忽下面代码 Object exposedObject = bean; try { populateBean(beanName, mbd, instanceWrapper); exposedObject = initializeBean(beanName, exposedObject, mbd); } // 疏忽上面代码}protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) { // 疏忽下面代码 if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) { // 遍历所有 InstantiationAwareBeanPostProcessor ,并调用其 postProcessAfterInstantiation() 办法,如果返回 false ,就不会执行后续步骤了。 if (!bp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) { return; } } } // 疏忽两头局部代码 if (hasInstantiationAwareBeanPostProcessors()) { if (pvs == null) { pvs = mbd.getPropertyValues(); } for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) { // 遍历所有 InstantiationAwareBeanPostProcessor ,并调用其 postProcessProperties() 办法,如果存在返回的值为 null ,就不会执行后续步骤了 PropertyValues pvsToUse = bp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName); if (pvsToUse == null) { return; } pvs = pvsToUse; } } boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE); if (needsDepCheck) { PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching); checkDependencies(beanName, mbd, filteredPds, pvs); } if (pvs != null) { // 依据调用所有 InstantiationAwareBeanPostProcessor 的 postProcessProperties() 办法所失去的值,来批改这个 bean 的属性 applyPropertyValues(beanName, mbd, bw, pvs); }}
从下面的代码片段中,doCreateBean() 办法会调用 populateBean() 办法,其中 populateBean() 办法它的次要逻辑是:
- 遍历所有 InstantiationAwareBeanPostProcessor ,调用 postProcessAfterInstantiation() 办法,如果返回值为 false 了,就不会执行后续步骤了
- 遍历所有 InstantiationAwareBeanPostProcessor ,调用 postProcessProperties() 办法,如果返回值为 null ,就不会执行后续的其余步骤了
- 如果 pvs 的值不为空,那么就去调用 applyPropertyValues() 办法来设置 bean 的属性
3. postProcessProperties()
postProcessProperties() 办法返回的 PropertyValues 会影响 bean 属性的设置。
论断
如果 PropertyValues 为 null ,PropertyValues 外面没有数据,就不会对 bean 的属性做任何批改。
否则,就会批改 Bean 的属性值。
验证
批改 CustomInstantiationAwareBeanPostProcessor 类的 postProcessProperties() 办法逻辑:
@Overridepublic PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException { if (isMatchClass(bean.getClass())) { System.out.println("调用 postProcessProperties 办法"); MutablePropertyValues mpvs = (MutablePropertyValues) pvs; // 这里批改 TestBean 的 field 字段值为 "update value" mpvs.add("field","update value"); } return pvs;}
输入后果:
调用 postProcessBeforeInstantiation 办法创立 TestBean 对象设置 field 属性调用 postProcessAfterInstantiation 办法调用 postProcessProperties 办法设置 field 属性调用 postProcessBeforeInitialization 办法调用初始化办法调用 postProcessAfterInitialization 办法TestBean{field=update value}
4. postProcessBeforeInitialization() 和 postProcessAfterInitialization()
postProcessBeforeInitialization() 和 postProcessAfterInitialization() 这2个办法是在 Bean 的属性设置完之后执行的,能够通过这2个办法来实现对 Bean 的属性进行批改。
当 Spring 在 AbstractAutowireCapableBeanFactory 的 doCreateBean() 办法中调用完了 populateBean() 的办法后,就会调用 initializeBean() 办法。
故 initializeBean() 办法是 Spring 调用 postProcessBeforeInitialization() 和 postProcessAfterInitialization() 的次要逻辑:
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) { invokeAwareMethods(beanName, bean); Object wrappedBean = bean; if (mbd == null || !mbd.isSynthetic()) { // 遍历所有 BeanPostProcessor 的子类,并调用 postProcessBeforeInitialization() 的办法 // 如果 postProcessBeforeInitialization() 返回 null ,则返回上一个 BeanPostProcessor 子类返回的对象, // 或者是 bean 对象自身(如果调用第一个 BeanPostProcessor 子类就返回 null 的话) wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); } try { // 调用 bean 指定的 init 办法,或者是实现 InitializingBean 的 afterPropertiesSet() 办法 invokeInitMethods(beanName, wrappedBean, mbd); } catch (Throwable ex) { throw new BeanCreationException( (mbd != null ? mbd.getResourceDescription() : null), beanName, ex.getMessage(), ex); } if (mbd == null || !mbd.isSynthetic()) { // 遍历所有 BeanPostProcessor 的子类,并调用 postProcessAfterInitialization() 的办法 // 如果 postProcessAfterInitialization() 返回 null ,则返回上一个 BeanPostProcessor 子类返回的对象, // 或者是 bean 对象自身(如果调用第一个 BeanPostProcessor 子类就返回 null 的话) wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); } return wrappedBean;}
参考博客/论坛
- Spring Boot –如何初始化Bean进行测试
- Spring之InstantiationAwareBeanPostProcessor接口介绍
- How to get a bean real class instead CGlib proxy?