spring中使用動態代理(AOP)


spring是整合了BGLIB和JDK兩種動態代理

示例:使用CGLIB代理

public class MyCar {

    private String color = "blue";

    public void run() {
        System.out.println("我的汽車跑起來了" + color);
    }
}

測試

public class SpringProxy {

    public static void main(String[] args) {
	   //將代理類的class文件保存到本地
        System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "E:\\Java4IDEA\\comm_test\\com\\sun\\proxy");
        ProxyFactory proxyFactory = new ProxyFactory(new MyCar());
        //添加前后置通知
        addAdivce(proxyFactory);
        proxyFactory.setProxyTargetClass(true);
        MyCar proxy = (MyCar) proxyFactory.getProxy();
        proxy.run();
    }
}

使用JDK代理

被代理的對象需要實現接口

public interface Car {
    void run();
}

調用

public static void main(String[] args) throws Exception {
    System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles", "true");
    ProxyFactory proxyFactory = new ProxyFactory(new MyCar());
    addAdivce(proxyFactory);
    //        proxyFactory.setProxyTargetClass(true);
    Car proxy = (Car) proxyFactory.getProxy();
    proxy.run();
}

如果想添加前后置通知 如下

 private static void addAdivce(ProxyFactory proxyFactory) {
        proxyFactory.addAdvice(new MethodInterceptor() {
            @Override
            public Object invoke(MethodInvocation invocation) throws Throwable {
                Object aThis = invocation.getThis();
                System.out.println("MethodInterceptor前置:"+aThis);
                //執行被代理對象的方法,返回方法的返回值
                Object proceed = invocation.proceed();
                System.out.println("MethodInterceptor后置");
                return proceed;
            }
        });

        //可以添加多個方法前置或者后置通知
        proxyFactory.addAdvice(new AfterReturningAdvice() {
            @Override
            public void afterReturning(Object returnValue, Method method,
                                       Object[] args, Object target) throws Throwable {
                System.out.println("AfterReturningAdvice后置通知");

            }
        });

        proxyFactory.addAdvice(new MethodBeforeAdvice() {
            @Override
            public void before(Method method, Object[] args, Object target) throws Throwable {
                System.out.println("MethodBeforeAdvice前置通知");
            }
        });
    }

JDK生成的動態類

public final class $Proxy0 extends Proxy implements Car, SpringProxy, Advised, DecoratingProxy {
    ...
    public final void run() throws  {
        try {
            super.h.invoke(this, m3, (Object[])null);
        } catch (RuntimeException | Error var2) {
            throw var2;
        } catch (Throwable var3) {
            throw new UndeclaredThrowableException(var3);
        }
    }    
}

源碼與JDK的代理和CGLB的代理源碼大同小異,可以自行查閱
也可以參考 代理模式


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM