- AOP代码简化
在之前的AOP简单介绍中https://blog.csdn.net/nairuozi/article/details/104678690
在AOP.java页面需要引用多种注释完成功能,现在在xml文件中配置以实现相同功能。
@Before("execution(public int com.jd.computer.service.ComputerService.*(..))")
public void before(JoinPoint jp) {
Object[] args=jp.getArgs();
Signature sg=jp.getSignature();
String name=sg.getName();
System.out.println(this.getClass().getName()+":the "+name+" method begins.");
System.out.println(this.getClass().getName()+":parameters of the "+name+" method["+args[0]+","+args[1]+"].");
}
@Before内的语句需要多次调用,可以采用以下两种方法进行简化
- 在同AOP内利用@Pointcut注释
- 在xml文件内利用<aop:pointcut>标签
在同AOP内利用@Pointcut注释
@Pointcut("execution(public int xxx.xx.xxxxx.xxxxx.ComputerService.*(..))")
public void t() {
}
//xxx ComputerService前的路径。它会自动寻找ComputerService中所有public int的方法
@Before("t()")
在xml文件内利用<aop:pointcut>标签
<aop:config>
<aop:pointcut expression="execution(public int xxx.xx.xxxxx.xxxxx.ComputerService.*(..))" id="pc"/>
</aop:config>
<!--aop:pointcut 用于定义一个aop表达式-->
<!--此时还未使用,使用见下-->
ComputerService前的@Aspect与@Component简化
<bean id="ma" class="xxx.xx.xxxxx.MethodAop"></bean>
<aop:config proxy-target-class="true">
<aop:pointcut expression="execution(public int xxx.xx.xxxxx.xxxxx.ComputerService.*(..))" id="pc"/>
<!--aop:aspect 用于设置一个切面类-->
<aop:aspect ref="ma">
<aop:before method="before" pointcut-ref="pc"/><!--before方法调用上面pointcut-->
</aop:aspect>
</aop:config>
2.JDK代理与CGLib代理区别
已知使用AOP会生成代理类
在生成代理类时根据配置,有两种不同的代理类
- JDK
- CGLib
在xml文件中,根据proxy-target-class是否打开,决定用哪一种代理类。
代理对象默认使用JDK动态代理,当配置为<aop:aspectj-autoproxy poxy-target-class="true"/>时,则使用CGLib动态代理。
JDK代理时
public class Test{
public static void main(String[] args) {
ClassPathXmlApplicationContext applicationContext=new ClassPathXmlApplicationContext("application.xml");
IComputerService computerServices=applicationContext.getBean(IComputerService.class);//1
Class clas=computerServices.getClass();
//JDK代理和目标没有继承关系,代理类实现了目标类的接口
for(Class c : clas.getInterfaces()) {
System.out.println(c.getName());
}
applicationContext.close();
}
}
执行结果如图
需要说明的是,在使用jdk代理时,注释1处必须使用目标类的接口类(IComputerService.class)。使用目标类(ComputerService.class)则报错。
CGLib代理时
public class Test{
public static void main(String[] args) {
ClassPathXmlApplicationContext applicationContext=new ClassPathXmlApplicationContext("application.xml");
IComputerService computerServices=applicationContext.getBean(IComputerService.class);//1
Class clas=computerServices.getClass();
//CGlib的代理类是目标类的子类
System.out.println(clas.getSuperclass().getName());
applicationContext.close();
}
}
执行结果如下
证实CGLib代理类的父类为ComputerSevice。
注释1处既可以使用目标类的接口类(IComputerService.class),也可以使用目标类(ComputerService.class)。