文章目录
Spring里的Aop实质上是对动态代理的“封装”
搭建Spring Aop
第一步:
新建java工程:
在CalculatorService类中定义计算两数相乘或相除的方法:
package com.jd.calculator;
@Service
public class CalculatorService implements ICalculatorService {
@Override
public int mul(int a, int b) {
System.out.println(this.getClass().getName()+":The mul method begins.");
System.out.println(this.getClass().getName()+":Parameters of the mul method: ["+a+","+b+"]");
int result = a*b;
System.out.println(this.getClass().getName()+":Result of the mul method:"+result);
System.out.println(this.getClass().getName()+":The mul method ends.");
return result;
}
@Override
public int div(int a, int b) {
System.out.println(this.getClass().getName()+":The div method begins.");
System.out.println(this.getClass().getName()+":Parameters of the div method: ["+a+","+b+"]");
int result = a/b;
System.out.println(this.getClass().getName()+":Result of the div method:"+result);
System.out.println(this.getClass().getName()+":The div method ends.");
return result;
}
}
此类实现ICalculatorService接口:
package com.jd.calculator;
public interface ICalculatorService {
int mul(int a,int b);
int div(int a,int b);
}
下面用Spring AOP技术提高代码的重用性:
第二步:新建Calculator类并添加@Aspect和@Component注解:
在此类中新建 before(JoinPoint jd)和after(JoinPoint jd)方法并分别添加@Before("execution(int mul(int, int))")
和@After("execution(int mul(int, int))")
注解,将CalculatorService类中对int result = a*b;
此段代码的前置加强和后置加强分别交给新建的这两个方法。
具体代码代码如下:
package com.jd.calculator;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
@Aspect
@Component
public class Calculator {
@Before("execution(int mul(int, int))")
public void before(JoinPoint jd) {
Object obj = jd.getTarget();
Object [] args = jd.getArgs();
String name = jd.getSignature().getName();
System.out.println(obj.getClass().getName()+":The "+name+" method begins.");
System.out.println(obj.getClass().getName()+":Parameters of the "+name+" method: ["+args[0]+","+args[1]+"]");
}
@After("execution(int mul(int, int))")
public void after(JoinPoint jd) {
Object obj = jd.getTarget();
String name = jd.getSignature().getName();
System.out.println(obj.getClass().getName()+":The "+name+" method ends.");
}
}
第三步:配置javaSpring:新建application.xml文件并进行如下配置:
<context:component-scan base-package="com.jd"></context:component-scan>
<aop:aspectj-autoproxy proxy-target-class="false"></aop:aspectj-autoproxy>
proxy-target-class="false"为默认值:指定JDK生成代理对象;为true时指定CGLib生成代理对象。
注意拷入相关jar包并建立路径:
第四步:写一个测试类运行结果:
package com.jd.test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.jd.calculator.ICalculatorService;
public class Test {
public static void main(String[] args) {
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("application.xml");
ICalculatorService calculatorService = applicationContext.getBean(ICalculatorService.class);
int result = calculatorService.mul(1,1);
System.out.println("-->"+result);
}
}
输出结果:
com.jd.calculator.CalculatorService:The mul method begins.
com.jd.calculator.CalculatorService:Parameters of the mul method: [1,1]
com.jd.calculator.CalculatorService:The mul method ends.
-->1
实现及执行过程
1,在第三步中,配置<context:component-scan base-package="com.jd"></context:component-scan>
是为了让spring扫描在com.jd包中添加@Service
和@Component
注解的类;配置<aop:aspectj-autoproxy proxy-target-class="false"></aop:aspectj-autoproxy>
则是让spring扫描添加@Aspect
注解的类中的方法,当其扫描到方法中的@Before("execution(int mul(int, int))")
注解时会寻找到spring曾经扫描过的类中有int mul(int, int)方法的类并为此类创建一个代理对象;此代理对象会在测试类中调用。
2,在第四步中,ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("application.xml");
用于生成一个spring容器;ICalculatorService calculatorService = applicationContext.getBean(ICalculatorService.class);
则生成了一个代理对象;int result = calculatorService.mul(1,1);
调用了代理对象中的mul方法执行:1,前置加强(before()方法);2,目标类中的mul方法;3,后置加强(after()方法);