以BeanNameAutoProxyCreator为例,AOP源码解读 (4.1.14.RELEASE)
Demo如下
目标类
public interface HelloService {
void sayHello();
}
public class HelloServiceImpl implements HelloService{
public void sayHello() {
System.out.println("Hello");
}
}
拦截器
public class PrintInterceptor implements MethodInterceptor {
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
System.out.println("print before");
invocation.proceed();
System.out.println("print after");
return invocation;
}
}
public class PrintInterceptor2 implements MethodBeforeAdvice {
@Override
public void before(Method method, Object[] args, Object target) throws Throwable {
System.out.println("before");
}
}
配置
<bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
<property name="beanNames">
<list>
<value>helloService</value>
</list>
</property>
<property name="interceptorNames">
<list>
<value>printInterceptor</value>
<value>printInterceptor2</value>
</list>
</property>
<!-- <property name="optimize" value="true"/>-->
<!-- <property name="proxyTargetClass" value="true"/>-->
</bean>
<bean id="helloService" class="com.zww.spring.bean.HelloServiceImpl"/>
<bean id="printInterceptor" class="com.zww.spring.PrintInterceptor"/>
<bean id="printInterceptor2" class="com.zww.spring.PrintInterceptor2"/>
开始分析
分析之前先看核心类BeanNameAutoProxyCreator相关的UML图
BeanNameAutoProxyCreator 继承自AbstractAutoProxyCreator 从而实现了 InstantiationAwareBeanPostProcessor和BeanPostProcessor。在bean实例化之前和bean初始化之后有两次机会将其包装成代理对象。
具体是bean的实例化过程会走到AbstractAutowireCapableBeanFactory#createBean方法, 在此方法内会给后置处理器一次生成代理类bean代替原bean的机会, 另外在bean的初始化过程中doCreateBean方法内部也会提供一次初始化后置处理器生成代理类的机会。(本文引用代码均已删减)
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args){
// 第一次机会 实例化之前生成代理(自定义了TargetSource)
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean;
}
// 第二次机会 初始化之后生成代理
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
return beanInstance;
}
下面进正文源码分析
第一次机会
BeanNameAutoProxyCreator的动态代理类生成入口在AbstractAutoProxyCreator#postProcessBeforeInstantiation
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
// 如果自定义了TargetSource, 那么会在这里创建代理对象
if (beanName != null) {
TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
if (targetSource != null) {
this.targetSourcedBeans.add(beanName);
Object[] specificInterceptors