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();
    }
}






發佈了42 篇原創文章 · 獲贊 19 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章