SpringAop动态代理和AspectJ静态代理

169 阅读2分钟

一、SpringAop动态代理(运行时增强)

SpringAop如何使用代理取决于代理的对象是否实现了接口,如果实现接口,则默认使用jdk动态代理,当然也可以让其强制使用cglib代理。如果没有实现了接口,则必须使用cglib代理。总之spring会自动在JDK动态代理和CGLIB之间进行转换转换。通过注解@EnableAspectJAutoProxy设置是使用jdk代理还是cglib代理。

1、jdk代理

package com.example.springboottest.proxy;

public interface ProxyService {
    public abstract void targetMethod();
}
package com.example.springboottest.proxy;

public class JdkProxyServiceImpl implements ProxyService {
    @Override
    public void targetMethod() {
        System.out.println("目标方法执行");
    }
}
package com.example.springboottest.proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class ProxyHandler implements InvocationHandler {

    private Object proxyObj;

    public ProxyHandler(Object proxyObj) {
        this.proxyObj = proxyObj;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Object returnParam = null;
        try{
            System.out.println("before前置通知");
            returnParam =  method.invoke(proxyObj,args);
            System.out.println("afterReturning返回通知");
        }catch (Exception e){
            System.out.println("afterThrowing异常通知");
        }finally {
            System.out.println("after后置通知");
        }
        return returnParam;
    }

    public static void main(String[] args) {
        ProxyService jdkProxyService = new JdkProxyServiceImpl();
        ProxyService proxyService = (ProxyService) Proxy.newProxyInstance(
                jdkProxyService.getClass().getClassLoader(),
                jdkProxyService.getClass().getInterfaces(),
                new ProxyHandler(jdkProxyService));
        proxyService.targetMethod();
    }
}

1.png

2、cglib代理

public class CglibServiceImpl {

    public void targetMethod(){
        System.out.println("CglibServiceImpl目标方法执行");
    }
}
package com.example.springboottest.proxy;

import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

public class CglibProxyHandler implements MethodInterceptor {

    private Object proxyObj;

    public CglibProxyHandler(Object proxyObj) {
        this.proxyObj = proxyObj;
    }

    @Override
    public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
        Object returnParam = null;
        try{
            System.out.println("before前置通知");
            returnParam =  method.invoke(proxyObj,args);
            System.out.println("afterReturning返回通知");
        }catch (Exception e){
            System.out.println("afterThrowing异常通知");
        }finally {
            System.out.println("after后置通知");
        }
        return returnParam;
    }

    public static void main(String[] args) {
        CglibServiceImpl cglibService = new CglibServiceImpl();
        CglibProxyHandler cglibProxyHandler = new CglibProxyHandler(cglibService);
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(cglibService.getClass());
        enhancer.setCallback(cglibProxyHandler);
        CglibServiceImpl proxyService = (CglibServiceImpl)enhancer.create();
        proxyService.targetMethod();
    }
}

1.jpg

二、Aspectj静态代理(编译时增强)

AspectJ的底层技术是静态代理 ,即用一种 AspectJ 支持的特定语言编写切面,通过一个命令来编译,生成一个新的 代理类,该代理类增强了业务类,这是在编译时增强,相对于上面的运行时增强,编译时增强的性能更好。

三、区别

  • 静态代理在编译期就确定了代理类,而动态代理需要靠反射机制动态生成代理类,即AspectJ在编译时就增强了目标对象,Spring AOP的动态代理则是在每次运行时动态的增强,生成AOP代理对象。
  • 生成代理对象的时机不同,相对来说AspectJ的静态代理方式具有更好的性能,但是AspectJ需要特定的编译器进行处理,而Spring AOP则无需特定的编译器处理。 blog.csdn.net/xiaojin21ce… www.cnblogs.com/banmoon/p/1… blog.csdn.net/kfepiza/art…