AOP代码简化及JDK代理与CGLib代理区别

  1. 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会生成代理类

在生成代理类时根据配置,有两种不同的代理类

  1. JDK
  2. 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)。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值