spring中使用动态代理(AOP)

Posted qiaozhuangshi

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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的代理源码大同小异,可以自行查阅

以上是关于spring中使用动态代理(AOP)的主要内容,如果未能解决你的问题,请参考以下文章

Spring5学习笔记 — “Spring AOP底层原理(动态代理)”

Spring AOP动态代理实现,解决Spring Boot中无法正常启用JDK动态代理的问题

Spring_AOP的实现机制-动态代理

从动态代理到Spring AOP(上)

Spring AOP详解 JDK动态代理CGLib动态代理

转载Spring AOP详解 JDK动态代理CGLib动态代理