java-动态代理

目前java动态代理的实现分为两种

1.基于JDK的动态代理  //此代理的实现方式是利用反射,反射的用法在:https://www.cnblogs.com/hellohero55/p/11973757.html

2.基于CGILB的动态代理

在业务中使用动态代理,一般是为了给需要实现的方法添加预处理或者添加后续操作,但是不干预实现类的正常业务,把一些基本业务和主要的业务逻辑分离。我们一般所熟知的Spring的AOP原理就是基于动态代理实现的。

(1)基于JDK的动态代理;需要一个接口类,一个实现类,一个代理类;测试;下面附上代码

  

//接口类
public interface Subject {
    
     void hello(String param);
}
//接口实现类
public class SubjectImpl implements Subject{

    @Override
    public void hello(String param) {
        
         System.out.println("hello  " + param);
    }

}
//接口代理类
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

public class SubjectProxy implements InvocationHandler{

    private Subject subject;
    
    public SubjectProxy(Subject subject) {
        super();
        this.subject = subject;
    }

    @Override
    public Object invoke(Object arg0, Method method, Object[] args) throws Throwable {
         System.out.println("--------------begin-------------");
         
         //反射  invoke 方法的返回值;如果没有返回null  ; method.invoke(subject, args); 利用反射调用类里的实际方法
         Object invoke = method.invoke(subject, args);
        
         System.out.println("--------------end-------------");
         
         return invoke;
    }

}
//测试
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;

public class SubjectMain {
    
    public static void main(String[] args) {
        
        Subject subject=new SubjectImpl();
        
        InvocationHandler subjectProxy =new SubjectProxy(subject);
         //subjectProxy.getClass().getClassLoader()代理类的加载器    subject.getClass().getInterfaces() :被代理类的接口 如果有多个,就是数组形式传入  subjectProxy:代理类实例
        Subject proxyInstance = (Subject)Proxy.newProxyInstance(subjectProxy.getClass().getClassLoader(), subject.getClass().getInterfaces(), subjectProxy);
        
        proxyInstance.hello("word");
        
    }
}

解析一下上面的代码,如果我们想在SubjectImpl  的方法增强一些功能 打印输出前的日志和输出后的日志,在不改源码的情况下,代理就很方便解决这个情况;先来看看再没有用代理之前的时候运行的;

    现在要在这个方法增加一个日志,在不改变源码的情况下我们就可以用刚才实现的方式了

 

 显然用了代理的方式增加了改方法

  (2)基于CGILB的动态代理:准备的工作:一个实体类,一个拦截器类,一个测试,ps :一下两个类是spring包的,并不是jdk的

       org.springframework.cglib.proxy.MethodInterceptor;

                      org.springframework.cglib.proxy.MethodProxy;      

         实现方式如下:

      

//被代理类
public class CGsubject {
    
     public void sayHello(String parm){
            System.out.println("hello "+parm);
        }
}

import java.lang.reflect.Method;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;

public class HelloInterceptor implements  MethodInterceptor{

    @Override  //arg0 被代理对象的实例
    public Object intercept(Object arg0, Method methods, Object[] arg2, MethodProxy methodProxy) throws Throwable {
        
        System.out.println("begin time -----> "+ System.currentTimeMillis());
                //methodProxy 代理方法 invokeSuper:调用拦截的方法 不要使用Invoke,会出现oom的情况  
        Object o1 = methodProxy.invokeSuper(arg0, arg2);
        
        System.out.println("end time -----> "+ System.currentTimeMillis());
        
        return o1;
 
    }


}

import org.springframework.cglib.proxy.Enhancer;

public class CGmain {
    
     public static void main(String[] args) {
            Enhancer enhancer = new Enhancer();
            enhancer.setSuperclass(CGsubject.class);
            enhancer.setCallback(new HelloInterceptor());
            CGsubject cGsubject = (CGsubject) enhancer.create();
            cGsubject.sayHello("帅哥美女们");
        }
}
 

    
 

原文地址:https://www.cnblogs.com/hellohero55/p/11976048.html