一文撸明白 静态代理和动态代理
先直接上代码干货
创建一个Speak接口和ZhangSan实体类
Speaker接口: public interface Speaker { void speak(); } ZhangSan类: public class ZhangSan implements Speaker { @Override public void speak() { System.out.println("张三: 哈哈哈哈哈"); } }
这个时候,如果我们需要ZhangSan在speak之前或者之后干点啥,,,就需要使用代理类来增强目标类实现
1.采用静态代理类实现
ZhangSan代理类(增强类): public class ZhangSanProxyer implements Speaker { //注入ZhangSan对象 private ZhangSan zs = new ZhangSan(); @Override public void speak() { System.out.println("嘻嘻嘻嘻"); zs.speak(); System.out.println("呵呵呵呵"); } }
此时,通过如下代码调用,即可实现增强
//静态代理 Speaker speaker = new ZhangSanProxyer(); speaker.speak();
2.采用 jdk动态代理实现
创建一个代理抽象层: public class Proxyer implements InvocationHandler { private Object obj; public Proxyer(Object obj) { this.obj = obj; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { if ("speak".equals(method.getName())){ System.out.println("嘻嘻嘻嘻"); method.invoke(obj,args); System.out.println("呵呵呵呵"); } return null; } }
此时,通过如下代码调用,即可实现增强
//jdk动态代理 Proxyer proxyer = new Proxyer(new ZhangSan()); Speaker speaker1 = (Speaker) Proxy.newProxyInstance(Demo.class.getClassLoader(),new Class[]{Speaker.class},proxyer); speaker1.speak();
3.采用 cglib动态代理实现
创建Lisi实体类(不实现接口): public class Lisi { public void speak() { System.out.println("李四: 哈哈哈哈哈"); } } 创建代理增强类实现增强: public class Interceptor implements MethodInterceptor { private Object obj; public Interceptor(Object obj) { this.obj = obj; } @Override public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable { if ("speak".equals(method.getName())){ System.out.println("嘻嘻嘻嘻"); method.invoke(obj,args); System.out.println("呵呵呵呵"); } return null; } }
此时,通过如下代码调用,即可实现增强
//cglib动态代理 Interceptor interceptor = new Interceptor(new Lisi()); Lisi lisi = (Lisi) Enhancer.create(Lisi.class, interceptor); lisi.speak();
总结:
代理模式:
代理模式可以在不修改被代理对象的基础上,通过扩展代理类,进行一些功能的附加与增强。值得注意的是,代理类和被代理类应该共同实现一个接口,或者是共同继承某个类。
静态代理和动态代理,都是基于代理模式实现的一种对于类的方法的增强。
静态代理:
所谓静态代理,其实就是在编译期完成代理(程序运行前就已经存在代理类的字节码文件)
动态代理:
动态代理是利用反射机制在运行时创建代理类, 其实是对代理类做了进一步抽象和封装,提高其复用性
jdk动态代理:
两个核心对象: invocationHandler接口, Proxy类
1.被代理类需要实现某个接口(自己定义的接口也可以)。
2.实现invocationHandler
接口的类作为代理类的参数,invocationHandler
接口有一个invoke
抽象方法需要实现
3.使用jdk中的Proxy
类的静态方法newProxyInstance()
方法,生成一个代理类
cglib动态代理:
两个核心对象:
MethodInterceptor接口 ,Enhancer类
1.被代理类没有实现接口
2.创建自己的方法拦截处理器Interceptor 实现 MethodInterceptor 接口, 接口中有一个intercept方法需要实现
3.使用Enhancer.create方法创建代理增强类