【java】关于JDK与cglib的动态代理

基于JDK:

    委托类必须实现一个接口,再调用 Proxy.newProxyInstance() 时 ,

    JDK会根据InvocationHandler实现类的invoke方法  动态生成一个class字节码文件(这个类会跟委托类实现相同的接口),加载到虚拟机,

    

基于cglib:

    通过继承委托类,重写委托类的方法 实现增强,需要依赖asm包,也是通过动态生成字节码实现;

优劣:

  前者要求委托类必须实现接口

  后者要求委托类不能为final类

/************************************************************************************/

public class MyProxy2<T> {
    
    public <T>T getProxy(Class<?>clazz){
        //初始化被代理对象
        Object target = clazz.newInstance();
        //初始化代理对象的处理逻辑
        InvocationHandler handler=new InvocationHandler(){
            //obj 表示代理对象,method 被代理对象的方法,args 方法的参数
           
       @Override
public Object invoke(Object obj, Method method, Object[] args) throws Throwable { System.out.println(obj.getClass()); Object result=null; try{ //调用target的方法前 result=method.invoke(target, args); //调用target的方法后 }catch(Exception e){ //调用arget的方法发生异常 }finally{ //后置通知 } return result; } }; return (T) Proxy.newProxyInstance(clazz.getClassLoader(), clazz.getInterfaces(), handler); //根据调用处理者的逻辑生成一个代理对象 } }
public class CglibProxyDemo implements MethodInterceptor {
    
    private Enhancer enhancer = new Enhancer();
    
    public <T>T getProxy(Class<T> clazz){
        enhancer.setSuperclass(clazz);
        enhancer.setCallback(this);
        return (T) enhancer.create();
    }
    
    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
        System.out.println(method.getName());
        System.out.println("后置代理");
        Object result = proxy.invokeSuper(obj, args);
        System.out.println("后置代理");
        Matcher matcher = Pattern.compile("^set\w+").matcher(method.getName());
        if(matcher.find()){
            System.out.println(proxy);
            return proxy;
        }
        return result;
    }
}

    

  

  

原文地址:https://www.cnblogs.com/LightChan/p/7450673.html