InstantiationAwareBeanPostProcessor
理解:InstantiationAwareBeanPostProcessor继承自BeanPostProcessor,常用于Bean实例化前生成代理对象,直接返回代理对象;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {
@Nullable default Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException { return null; }
default boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException { return true; }
@Nullable default PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
return null; }
@Deprecated @Nullable default PropertyValues postProcessPropertyValues( PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
return pvs; }
}
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| 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; }
}
|
调用流程
1.在实例化bean之前,给BeanPostProcessors一个机会返回代理对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException { try { 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; } catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) { throw ex; } catch (Throwable ex) { throw new BeanCreationException( mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex); } }
|
2.执行InstantiationAwareBeanPostProcessors的Before方法返回Bean对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) { Object bean = null; if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) { 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; }
|
代码案例
1 2 3 4 5 6
| public class BeforeInstantiation {
public void doSomeThing(){ System.out.println("执行do some thing ..."); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13
| import org.springframework.cglib.proxy.MethodInterceptor; import org.springframework.cglib.proxy.MethodProxy; import java.lang.reflect.Method;
public class MyMethodInterceptor implements MethodInterceptor { @Override public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { System.out.println("目标方法前:"+method); Object o1 = methodProxy.invokeSuper(o, objects); System.out.println("目标方法后:"+method); return o1; } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
| import org.springframework.beans.BeansException; import org.springframework.beans.PropertyValues; import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor; import org.springframework.cglib.proxy.Enhancer;
public class MyInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor {
@Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { System.out.print("beanName:"+beanName+"执行..postProcessBeforeInitialization\n");
return bean; }
@Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { System.out.print("beanName:"+beanName+"执行..postProcessAfterInitialization\n");
return bean; }
@Override public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException { System.out.print("beanName:"+beanName+"执行..postProcessAfterInstantiation\n");
return false; }
@Override public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException { System.out.print("beanName:"+beanName+"执行..postProcessBeforeInstantiation\n"); if(beanClass==BeforeInstantiation.class){ Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(beanClass); enhancer.setCallback(new MyMethodInterceptor()); BeforeInstantiation beforeInstantiation = (BeforeInstantiation)enhancer.create(); System.out.print("返回动态代理\n"); return beforeInstantiation; } return null; }
@Override public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException { System.out.print("beanName:"+beanName+"执行..postProcessProperties\n"); return pvs; } }
|
1 2 3 4 5 6 7 8
| <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="beforeInstantiation" class="com.lixiang.resolveBeforeInstantiation.BeforeInstantiation"></bean> <bean id="myInstantiationAwareBeanPostProcessor" class="com.lixiang.resolveBeforeInstantiation.MyInstantiationAwareBeanPostProcessor"></bean> </beans>
|
1 2 3 4 5 6 7 8 9 10
| import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test { public static void main(String[] args) { ApplicationContext ac = new ClassPathXmlApplicationContext("resolveBeforeInstantiation.xml"); BeforeInstantiation bean = ac.getBean(BeforeInstantiation.class); bean.doSomeThing(); } }
|