AOP bean 准备
1 AOP sample
1.1 创建切面
package com.gientech.aop.xml.util;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import java.util.Arrays;
public class LogUtil {
public void myPointCut(){}
public void myPointCut1(){}
private int start(JoinPoint joinPoint){
// 获取方法签名
Signature signature = joinPoint.getSignature();
// 获取参数信息
Object[] args = joinPoint.getArgs();
System.out.println("log----" + signature.getName() + " start execute");
return 100;
}
public static void stop(JoinPoint joinPoint, Object result){
Signature signature = joinPoint.getSignature();
System.out.println("log----" + signature.getName() + " execute stop" + result);
}
public static void logException(JoinPoint joinPoint, Exception e){
Signature signature = joinPoint.getSignature();
System.out.println("log----" + signature.getName() + "throw new excepttion " + e.getMessage());
}
public static void logFinally(JoinPoint joinPoint){
Signature signature = joinPoint.getSignature();
System.out.println("log----" + signature.getName() + " execute over");
}
public Object around(ProceedingJoinPoint pjp) throws Throwable{
Signature signature = pjp.getSignature();
Object[] args = pjp.getArgs();
Object result = null;
try {
System.out.println("log----环绕通知 start: " + signature.getName() + " method start execute, parameter is " + Arrays.asList(args));
//通过反射的方式调用目标的方法,相当于执行method.invoke(),可以自己修改结果值
result = pjp.proceed(args);
System.out.println("log----环绕通知 stop: " + signature.getName() + " method execute over ");
}catch (Throwable throwable){
System.out.println("log----环绕异常通知 stop: " + signature.getName() + " 出现异常 ");
throw throwable;
}finally {
System.out.println("log----环绕返回通知 stop: " + signature.getName() + " 方法返回结果是: " + result);
}
return result;
}
}
1.2 创建业务类
package com.gientech.aop.xml.service;
import org.springframework.stereotype.Service;
public class MyCalculator /* implements Calculator */{
public Integer add(Integer i, Integer j) throws NoSuchMethodException{
Integer result = i + j;
return result;
}
public Integer sub(Integer i, Integer j) throws NoSuchMethodException{
Integer result = i - j;
return result;
}
public Integer mul(Integer i, Integer j) throws NoSuchMethodException{
Integer result = i * j;
return result;
}
public Integer div(Integer i, Integer j) throws NoSuchMethodException{
Integer result = i / j;
return result;
}
public Integer show(Integer i){
System.out.println("show ......");
return i;
}
}
1.3 创建配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd">
<bean id="logUtil" class="com.gientech.aop.xml.util.LogUtil"></bean>
<bean id="myCalculator" class="com.gientech.aop.xml.service.MyCalculator"></bean>
<aop:config>
<aop:aspect ref="logUtil">
<aop:pointcut id="myPoint"
expression="execution(Integer com.gientech.aop.xml.service.MyCalculator.* (..))"/>
<aop:around method="around" pointcut-ref="myPoint"></aop:around>
<aop:around method="start" pointcut-ref="myPoint"></aop:around>
<aop:before method="start" pointcut-ref="myPoint"></aop:before>
<aop:after method="logFinally" pointcut-ref="myPoint"></aop:after>
<aop:after-returning method="stop" pointcut-ref="myPoint" returning="result"></aop:after-returning>
<aop:after-throwing method="logException" pointcut-ref="myPoint" throwing="e"></aop:after-throwing>
</aop:aspect>
</aop:config>
</beans>
1.4 创建启动类
package com.gientech.aop.xml;
import com.gientech.aop.xml.service.MyCalculator;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestAop {
public static void main(String[] args) throws Exception {
ApplicationContext ac = new ClassPathXmlApplicationContext("aop.xml");
MyCalculator bean = ac.getBean(MyCalculator.class);
Integer result = bean.add(1,2);
System.out.println(result);
}
}
解析过程中注册 AspectJAwareAdvisorAutoProxyCreator。
在registerBeanPostProcessors方法中创建 AnnotationAwareAspectJAutoProxyCreator(自动代理创建器)对象。
logutil是切面对象,切面对象不需要被代理,所以logutil不需要被代理。
运行结果如下:
2 AOP BeanDefinition加载过程
当使用spring的aop的时候,需要进行N多个对象的创建,但是在创建过程中需要做很多判断,判断当前对象是否需要被代理,而代理之前,需要的advisor对象必须要提前创建好,才能进行后续的判断。
Aop 标签对应的类如下:
- AspectJMethodBeforeAdvice.java: aop:before 标签对应类
- AspectJAfterAdvice.java: aop:after 标签对应类
- AspectJAfterReturningAdvice.java: after-returning 标签对应类
- AspectJAfterThrowingAdvice.java:after-throwing 标签对应类
- AspectJAroundAdvice.java: aop:around 标签对应类
- AspectJExpressionPointcut.java: 表达式对应的类对象,eg:"execution(Integer com.gientech.aop.xml.service.MyCalculator.* (..))"
AOP BeanDefinition加载过程如图,
- 1 创建AspectJPointAdvisor#0-4,先使用器带参的构造函数进行对象的创建,但是需要将参数对象准备好,因此要创建内置包含的对象AspectJAroundAdvice
- 2 创建AspectJAroundAdvice,也需要使用带参的构造函数进行创建,也需要提前准备好具体的参数对象,包含3个参数对象,分别是MethodLocatingFactoryBean, AspectJExpressionPointcut, SimpleBeanFactoryAwareAspectInstanceFactory。
- 3 分别创建上述3个对象,上述3个对象的创建过程都是调用无参的构造函数,直接反射生成即可。
自动代理创建器
切面对象不需要被代理
MyCalculator是被代理对象
某个对象需要被动态代理,此对象对应的普通实例对象也是需要被创建的,只是在后续过程中普通实例对象会被替换。
标签:创建,AOP,result,signature,println,Integer,解析,public From: https://www.cnblogs.com/zgcy123456/p/18115042