首先配置文件内容如下:
<!--横切逻辑--> <bean id="logUtils" class="com.test.circular.LogUtils"> </bean> <aop:config> <aop:aspect ref="logUtils"> <aop:before method="beforeMethod" pointcut="execution(public void com.test.aop.AopBean.test())"/> <aop:after method="alertMethod" pointcut="execution(public void com.test.aop.AopBean.test())"/> <aop:around method="aroundMethod" pointcut="execution(public void com.test.aop.AopBean.test())"/> <aop:after-returning method="afterReturning" pointcut="execution(public void com.test.aop.AopBean.test())"/> <aop:after-throwing method="afterThrowingMethod" pointcut="execution(public void com.test.aop.AopBean.test())"/> </aop:aspect> </aop:config>
public class LogUtils {
public void beforeMethod() {
System.out.println("前置通知");
}
public void alertMethod() {
System.out.println("最终通知");
}
public Object aroundMethod(ProceedingJoinPoint pjp) throws Throwable {
System.out.println("环绕通知-前");
Object proceed = pjp.proceed();
System.out.println("环绕通知-后");
return proceed;
}
public void afterThrowingMethod() {
System.out.println("异常通知");
}
public void afterReturning() {
System.out.println("后置通知");
}
}
public class AopBean implements AopBeanInf{
@Override
public void test() {
System.out.println("spring aop 测试");
}
}
通过SpringIOC源码中的源码分析过程,可以将切入点定位到如下图所示方法。

接着会遍历所有的初始化的bean,主要进入AbstractAutowireCapableBeanFactory的doCreateBean方法,会完成实例创建。

往下走会完成bean生命周期的管理,首先属性填充,调用初始化bean,重点分析这个方法。
1) 调用Bean中的BeanNameAware.setBeanName()方法,如果该Bean实现了BeanNameAware接口;调用Bean中的BeanFactoryAware.setBeanFactory()方法,如果该Bean实现了BeanFactoryAware接口,调用Bean中的BeanClassLoader.setBeanClassLoader()方法。
2)调用BeanPostProcessors.postProcessBeforeInitialization()方法
3)调用Bean中的afterPropertiesSet方法,如果该Bean实现了InitializingBean接口;
4)调用Bean中的init-method,通常是在配置bean的时候指定了init-method,例如:<beanclass="beanClass"init-method="init"></bean>
5)调用BeanPostProcessors.postProcessAfterInitialization()方法;

实现AOP主要在初始化后应用Bean后置处理器---在这一步生成代理对象

这个方法会遍历所有的后置处理器。

主要进入AbstractAutoProxyCreator类的postProcessAfterInitialization方法,如下红框所示对象进行包装即增强

将所有的通知拆分成数组。

如下图所示,通过createProxy方法创建代理对象。

进入的createProxy方法,该方法中主要有getProxy这个方法中会通过代理工厂生成对象

判断是否实现接口,用jdk还是cglib代理,默认采用jdk代理。
public Object getProxy(@Nullable ClassLoader classLoader) {
return createAopProxy().getProxy(classLoader);
}
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
Class<?> targetClass = config.getTargetClass();
if (targetClass == null) {
throw new AopConfigException("TargetSource cannot determine target class: " +
"Either an interface or a target is required for proxy creation.");
}
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
return new JdkDynamicAopProxy(config);
}
return new ObjenesisCglibAopProxy(config);
}
else {
return new JdkDynamicAopProxy(config);
}
}
创建代理对象后,这里采用JdkDynamicAopProxy,然后进入该类的getProxy执行代理方法

观察下JdkDynamicAopProxy这个类,本身实现了InvocationHandler,就是个代理对象,
作为Proxy对象的回调函数被触发,从而通过invoke()的具体实现来完成对目标对象的拦截或者说功能增强的工作。

执行代理对象的invoke方法。

得到拦截链。

递归进入了ReflectiveMethodInvocation类的proceed()

可以看到此时的methodName为beforeMethod

因此此时会执行MethodBeforeAdviceInterceptor类的invoke方法。

继续往下走,一直到AbstractAspectJAdvice类的如下方法:

通过反射执行Method

执行到DelegatingMethodAccessorImpl类的invoke方法。

执行到NativeMethodAccessorImpl类中invoke方法。

继续执行会到走到前置通知方法答应出具体内容。

返回,执行完前置通知后再调用mi.proceed()。

接着从执行链中再取一个执行。

进入AspectJAfterAdvice类执行最终通知

环绕通知,创建了连接点对象,执行到AspectJAroundAdvice类的invoke方法


进入proceed,执行后置通知

AfterReturningAdviceInterceptor

执行连接点之后进行后置通知,首先执行连接点方法

这时找到异常通知
在AspectJAfterThrowingAdvice类

执行目标方法


然后返回

执行后置通知


最后在finally中执行最终通知。

浙公网安备 33010602011771号