目前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("帅哥美女们"); } }