Spring AOP demo 和获取被CGLIB代理的对象
2018-09-14 14:27
441 查看
本文分为两部分:1)给出Spring AOP的一个例子(会使用CGLIB代理);2)给出获取被CGLIB代理的原始对象。
1、Spring AOP Demo
这部分参考了博文(http://www.voidcn.com/blog/daguanjia11/article/p-4628090.html)
1.1添加maven依赖
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>4.0.5.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>4.0.5.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>4.0.5.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> <version>4.0.5.RELEASE</version> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.8.1</version> </dependency>
1.2添加测试类
public class SpringAopTest { public static class Car { public void go() { System.out.println("go go go!"); } } public static class CarLogger { public void beforeRun() { System.out.println("car is going to run"); } public void afterRun() { System.out.println("car is running"); } } public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("spring-aop-test.xml"); Car car = (Car) context.getBean("car"); System.out.println(car.getClass()); car.go(); } }
1.3添加spring配置文件
放置在classpath的根目录下,额,放在resources目录下也就行了。
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd"> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd" > <bean id="car" class="com.SpringAopTest.Car"/> <bean id="logger" class="com.SpringAopTest.CarLogger" /> <aop:config> <aop:aspect ref="logger"> <aop:pointcut expression="execution(* com.SpringAopTest.Car.go(..))" id="go"/> <aop:before pointcut-ref="go" method="beforeRun" /> <aop:after pointcut-ref="go" method="afterRun" /> </aop:aspect> </aop:config> </beans> </beans>
1.4运行main函数
得到如下结果:
car is going to run go go go! car is running
呐,你看go go go!前后都有后添加的动作吧。
2、获取被CGLIB代理的对象
这部分内容参考了博文(https://www.geek-share.com/detail/2634200485.html)
我们先通过debug看一下被代理对象被藏在哪里了
好,看完了,我们来写一下代码,如下:
import java.lang.reflect.Field; import org.springframework.aop.framework.AdvisedSupport; import org.springframework.aop.support.AopUtils; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; /** * Created by qm on 17/2/15. */ public class SpringAopTest { public static class Car { public void go() { System.out.println("go go go!"); } } public static class CarLogger { public void beforeRun() { System.out.println("car is going to run"); } public void afterRun() { System.out.println("car is running"); } } public static Object getTarget(Object beanInstance) { if (!AopUtils.isAopProxy(beanInstance)) { return beanInstance; } else if (AopUtils.isCglibProxy(beanInstance)) { try { Field h = beanInstance.getClass().getDeclaredField("CGLIB$CALLBACK_0"); h.setAccessible(true); Object dynamicAdvisedInterceptor = h.get(beanInstance); Field advised = dynamicAdvisedInterceptor.getClass().getDeclaredField("advised"); advised.setAccessible(true); Object target = ((AdvisedSupport) advised.get(dynamicAdvisedInterceptor)).getTargetSource().getTarget(); return target; } catch (NoSuchFieldException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } } return null; } public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("spring-aop-test.xml"); Car car = (Car) context.getBean("car"); Object target = getTarget(car); System.out.println(target == car); System.out.println(car.getClass()); System.out.println(target.getClass()); car.go(); } }
相关文章推荐
- Spring AOP demo 和获取被CGLIB代理的对象
- Spring 代理对象,cglib,jdk的问题思考,AOP 配置注解拦截 的一些问题.为什么不要注解在接口,以及抽象方法.
- 重温Spring之旅5——AOP代理对象、JDK动态代理、使用cglib生产代理
- Spring aop事务代理对象通过TransactionInterceptor处理目标方法事务过程,cglib方式
- Spring aop 通过获取代理对象实现事务切换
- Spring进阶之路(10)-Advice简介以及通过cglib生成AOP代理对象
- Spring aop 通过获取代理对象实现事务切换
- Spring—AOP两种代理机制对比(JDK和CGLib动态代理)
- Spring源码阅读4.2-Aspecjt AOP之代理对象的创建
- cglib动态代理例子和浅剖Spring Aop机制
- 利用CGLib实现动态代理实现Spring的AOP
- 在spring中获取代理对象代理的目标对象工具类
- Spring中AOP的两种代理方式(Java动态代理和CGLIB代理)
- Spring中AOP的两种代理方式(Java动态代理和CGLIB代理)
- spring aop的cglib代理
- spring aop获取目标对象的方法对象(包括方法上的注解)(转)
- Spring AOP 源码分析 - 创建代理对象
- 在spring中获取代理对象代理的目标对象工具类
- CGLIB实现AOP代理的测试类,与Spring分离,加深对面向切面编程的理解
- Spring中AOP实现的两种方式之JDK和cglib的动态代理