首先配置文件内容如下:

<!--横切逻辑-->
	<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,主要进入AbstractAutowireCapableBeanFactorydoCreateBean方法,会完成实例创建。

 

往下走会完成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中执行最终通知。

 

 

posted on 2021-09-03 22:14  jeolyli  阅读(47)  评论(0编辑  收藏  举报