zoukankan      html  css  js  c++  java
  • Spring AOP demo 和获取被CGLIB代理的对象

    本文分为两部分: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代理的对象

    这部分内容参考了博文(http://blog.csdn.net/liufeng520/article/details/43563161

    我们先通过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();
        }
    }
  • 相关阅读:
    二分LIS模板
    NYOJ16 矩形嵌套 【DAG上的DP/LIS】
    动态规划题库
    洛谷 P1616 疯狂的采药【裸完全背包】
    洛谷 P1049 装箱问题【正难则反/01背包】
    洛谷 P1048 采药【裸01背包】
    洛谷 P1064 金明的预算方案【有依赖的分组背包】
    洛谷 P1064 金明的预算方案【DP/01背包-方案数】
    洛谷 P1060 开心的金明【DP/01背包】
    51nod 1202 不同子序列个数 [计数DP]
  • 原文地址:https://www.cnblogs.com/toSeeMyDream/p/9646380.html
Copyright © 2011-2022 走看看