AOP的底層實現-CGLIB動態代理和JDK動態代理
cglib的實現原理 :在內存爲目標對象創建一個子類對象,通過覆寫父類的方法 ,實現功能增強。
AOP是目前Spring框架中的核心之一,在應用中具有非常重要的作用,也是Spring其他組件的基礎。它是一種面向切面編程的思想。關於AOP的基礎知識,相信多數童鞋都已經瞭如指掌,我們就略過這部分,來講解下AOP的核心功能的底層實現機制:如何用動態代理來實現切面攔截。
- package jdkproxy;
- /**
- * 該類是所有被代理類的接口類,jdk實現的代理要求被代理類基於統一的接口
- *
- * @author typ
- *
- */
- public interface Service {
- /**
- * add方法
- */
- public void add();
- /**
- * update方法
- */
- public void update();
- }
- package jdkproxy;
- /**
- * 被代理類,即目標類target
- *
- * @author typ
- *
- */
- public class AService implements Service {
- /*
- * (non-Javadoc)
- *
- * @see jdkproxy.Service#add()
- */
- public void add() {
- System.out.println("AService add>>>>>>>>>>>>>>>>>>");
- }
- /*
- * (non-Javadoc)
- *
- * @see jdkproxy.Service#update()
- */
- public void update() {
- System.out.println("AService update>>>>>>>>>>>>>>>");
- }
- }
- package jdkproxy;
- import java.lang.reflect.InvocationHandler;
- import java.lang.reflect.Method;
- /**
- * @author typ
- *
- */
- public class MyInvocationHandler implements InvocationHandler {
- private Object target;
- MyInvocationHandler() {
- super();
- }
- MyInvocationHandler(Object target) {
- super();
- this.target = target;
- }
- public Object invoke(Object proxy, Method method, Object[] args)
- throws Throwable {
- // 程序執行前加入邏輯,MethodBeforeAdviceInterceptor
- System.out.println("before-----------------------------");
- // 程序執行
- Object result = method.invoke(target, args);
- // 程序執行後加入邏輯,MethodAfterAdviceInterceptor
- System.out.println("after------------------------------");
- return result;
- }
- }
- package jdkproxy;
- import java.lang.reflect.Proxy;
- /**
- * @author typ
- *
- */
- public class Test {
- public static void main(String[] args) {
- Service aService = new AService();
- MyInvocationHandler handler = new MyInvocationHandler(aService);
- // Proxy爲InvocationHandler實現類動態創建一個符合某一接口的代理實例
- Service aServiceProxy = (Service) Proxy.newProxyInstance(aService
- .getClass().getClassLoader(), aService.getClass()
- .getInterfaces(), handler);
- // 由動態生成的代理對象來aServiceProxy 代理執行程序,其中aServiceProxy 符合Service接口
- aServiceProxy.add();
- System.out.println();
- aServiceProxy.update();
- // 以下是對B的代理
- // Service bService = new BService();
- // MyInvocationHandler handler = new MyInvocationHandler(bService);
- // Service bServiceProxy = (Service) Proxy.newProxyInstance(bService
- // .getClass().getClassLoader(), bService.getClass()
- // .getInterfaces(), handler);
- // bServiceProxy.add();
- // System.out.println();
- // bServiceProxy.update();
- }
- }
可以看到,在目標類AService的add和update方法前後已經加入了自定義的切面邏輯,AOP攔截機制生效了。
- package cglibproxy;
- /**
- * 被代理類,即目標對象target
- *
- * @author typ
- *
- */
- public class Base {
- /**
- * 一個模擬的add方法
- */
- public void add() {
- System.out.println("add ------------");
- }
- }
- package cglibproxy;
- import java.lang.reflect.Method;
- import net.sf.cglib.proxy.MethodInterceptor;
- import net.sf.cglib.proxy.MethodProxy;
- /**
- * 此爲代理類,用於在pointcut處添加advise
- *
- * @author typ
- *
- */
- public class CglibProxy implements MethodInterceptor {
- public Object intercept(Object object, Method method, Object[] args,
- MethodProxy proxy) throws Throwable {
- // 添加切面邏輯(advise),此處是在目標類代碼執行之前,即爲MethodBeforeAdviceInterceptor。
- System.out.println("before-------------");
- // 執行目標類add方法
- proxy.invokeSuper(object, args);
- // 添加切面邏輯(advise),此處是在目標類代碼執行之後,即爲MethodAfterAdviceInterceptor。
- System.out.println("after--------------");
- return null;
- }
- }
- package cglibproxy;
- import net.sf.cglib.proxy.Enhancer;
- /**
- * 工廠類,生成增強過的目標類(已加入切入邏輯)
- *
- * @author typ
- *
- */
- public class Factory {
- /**
- * 獲得增強之後的目標類,即添加了切入邏輯advice之後的目標類
- *
- * @param proxy
- * @return
- */
- public static Base getInstance(CglibProxy proxy) {
- Enhancer enhancer = new Enhancer();
- enhancer.setSuperclass(Base.class);
- //回調方法的參數爲代理類對象CglibProxy,最後增強目標類調用的是代理類對象CglibProxy中的intercept方法
- enhancer.setCallback(proxy);
- // 此刻,base不是單純的目標類,而是增強過的目標類
- Base base = (Base) enhancer.create();
- return base;
- }
- }
- package cglibproxy;
- /**
- * @author typ
- *
- */
- public class Test {
- public static void main(String[] args) {
- CglibProxy proxy = new CglibProxy();
- // base爲生成的增強過的目標類
- Base base = Factory.getInstance(proxy);
- base.add();
- }
- }