代理分为两种:静态代理 动态代理
静态代理:本质上会在硬盘上创建一个真正的物理类
动态代理:本质上是在内存中构建出一个类。
如果多个类需要进行方法增强,静态代理则需要创建多个物理类,占用磁盘空间。而动态代理则是在内存中创建,不会对磁盘进行影响。
静态代理和JDK动态代理需要有接口。 CGLIB动态代理无需有接口的情况下进行代理。实质:内存中构建出了目标类型的子类。
JDK动态代理是JDK提供的,CGLIB动态代理是Spring提供的。
代理模式的三个组件:抽象主题 真实主题 代理主题
静态代理:
接口(抽象主题)的代码:
//抽象主题 public interface Subject { public void request(); }
目标对象(真实主题)的代码:
//真实主题 public class RealSubject implements Subject{ @Override public void request() { System.out.println("Subject RealSubject"); } }
代理对象(代理主题)的代码:
package cn.Spring.Day09Staticporxy; //代理主题 public class ProxySubject implements Subject { //把真实主题当成代理主题的成员变量 private RealSubject rs=new RealSubject(); @Override public void request() { System.out.println("proxy");//在调用真实主题要增强的方法前进行增强 rs.request(); System.out.println("ProxySubject");//在调用真实主题要增强的方法后进行增强 } }
JDK动态代理:
接口:
package cn.Spring.Day14JDKproxy; public interface ISomeService { public void request(); }
目标对象:
package cn.Spring.Day14JDKproxy; public class SomeService implements ISomeService { @Override public void request() { System.out.println("977+7777"); } }
代理对象:
package cn.Spring.Day14JDKproxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; public class JdkProxy { public static void main(String[] args) { /* * 1.使用Proxy点出newProxyInstance方法 方法有三个参数 * ClassLoader loader, 类加载器类型的一个对象 * Class<?>[] interfaces,接口数组对象 * InvocationHandler h InvocationHandler 对象 * 2.实例化目标对象 目标对象去传入参数。 * 3.invoke方法中使用method.invoke传入目标对象,和参数数组。 * * * */ final SomeService ss=new SomeService(); ISomeService proxy = (ISomeService)Proxy.newProxyInstance(ss.getClass().getClassLoader(), ss.getClass().getInterfaces(), new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("我是增强666666"); method.invoke(ss,args); return null; } }); proxy.request(); } }
newProxyInstance要传的参数
invoke要传的参数
CGLIB动态代理:
目标对象:
package cn.Spring.Day10cglibProxy; public class Service { public void doSome(){ System.out.println("SSSSSService"); } }
代理对象:
package cn.Spring.Day10cglibProxy; 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 ServiceTest { public static void main(final String[] args) { final Service service=new Service(); Enhancer enhancer=new Enhancer(); enhancer.setSuperclass(Service.class); enhancer.setCallback(new MethodInterceptor() { @Override public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { System.out.println("写入日志"); Object invoke = methodProxy.invoke(service, args); return invoke; } }); Service o = (Service)enhancer.create(); o.doSome(); } }