1.什么是代理模式? 为对象提供一种代理以控制对这个对象的访问。代理模式相当于:中介或者经纪人 ,代理类可以在被代理类的基础之上增加功能(扩展功能),比如日志记录和权限控制 ,这样被代理类隐藏起来了,比较安全。
1.代理模式实现方式有哪些?
静态代理和动态代理
2.静态代理是:需要程序员人为创建好代理类,缺点;如果被代理类很多的话,需要手写很多个代理类,代码会变得非常冗余。
3.静态代理实现方式有哪些?
1.通过继承2.实现接口
1.通过实现接口方式实现静态代理
1.定义共同接口
package com.mayikt.service; public interface OrderService { /** * 共同抽象的方法 */ void order(); }
2.定义被代理类实现共同的接口
package com.mayikt.service.impl; import com.mayikt.service.OrderService; public class OrderServiceImpl implements OrderService { public void order() { System.out.println("执行订单业务逻辑代码"); } }
3.手写代理类OrderServiceProxy
package com.mayikt.service.proxy; import com.mayikt.service.OrderService; import com.mayikt.service.impl.OrderServiceImpl; public class OrderServiceProxy implements OrderService { /** * 被代理对象 */ private OrderService orderService; public OrderServiceProxy(OrderService orderService) { this.orderService = orderService; } public void order() { System.out.println(">>>打印订单日志开始"); orderService.order(); System.out.println(">>>打印订单日志结束"); } }
4.测试
package com.mayikt.service; import com.mayikt.service.cglib.proxy.CglibMethodInterceptor; import com.mayikt.service.impl.OrderServiceImpl; import com.mayikt.service.jdk.proxy.JdkInvocationHandler; import com.mayikt.service.proxy.OrderServiceProxy; import net.sf.cglib.core.DebuggingClassWriter; import net.sf.cglib.proxy.Enhancer; public class Client { public static void main(String[] args) { OrderService orderService = new OrderServiceProxy(new OrderServiceImpl()); orderService.order(); } }
通过继承的方式实现静态代理
1.定义共同接口
package com.mayikt.service; public interface OrderService { /** * 共同抽象的方法 */ void order(); }
2.定义被代理类
package com.mayikt.service.impl; import com.mayikt.service.OrderService; public class OrderServiceImpl implements OrderService{ public void order() { System.out.println("执行订单业务逻辑代码"); } }
3.手写代理类
package com.mayikt.service.proxy; import com.mayikt.service.OrderService; import com.mayikt.service.impl.OrderServiceImpl; public class OrderServiceProxy extends OrderServiceImpl { public void order() { System.out.println(">>>打印订单日志开始"); super.order();// 执行父类的order 方法OrderServiceImpl System.out.println(">>>打印订单日志结束"); } }
4、测试
package com.mayikt.service; import com.mayikt.service.cglib.proxy.CglibMethodInterceptor; import com.mayikt.service.impl.OrderServiceImpl; import com.mayikt.service.jdk.proxy.JdkInvocationHandler; import com.mayikt.service.proxy.OrderServiceProxy; import net.sf.cglib.core.DebuggingClassWriter; import net.sf.cglib.proxy.Enhancer; public class Client { public static void main(String[] args) { OrderService orderService = new OrderServiceProxy(); orderService.order(); } }
动态代理
1.动态代理:不需要关心代理类, jvm运行的时候自动创建代理类,不需要手动创建。
2.动态代理实现方式有哪些?
jdk动态代理和cglib原理
3.jdk动态代理:jdk动态生成的代理类都是实现接口形式,所以被代理类必须实现接口(通过反射的方式实现)
cglib代理:通过asm字节码技术实现动态生成代理类,运行时动态的生成一个被代理类的子类
4.jdK动态代理要求被代理的类必须实现接口,当需要被代理的类没有实现接口时cglib代理是一个很好的选择
5.spring默认会使用JDK的动态代理,但是如果目标对象没有实现接口,则默认会采用CGLIB代理;
jdk实现动态代理
1.定义共同接口
package com.mayikt.service; public interface OrderService { /** * 共同抽象的方法 */ void order(); }
2.定义被代理类实现共同的接口
package com.mayikt.service.impl; import com.mayikt.service.OrderService; public class OrderServiceImpl implements OrderService { public void order() { System.out.println("执行订单业务逻辑代码"); } }
3.创建生成动态代理类的类:JdkInvocationHandler
package com.mayikt.service.jdk.proxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; public class JdkInvocationHandler implements InvocationHandler { /** * 被代理类对象 目标代理对象 */ private Object target; public JdkInvocationHandler(Object target) { this.target = target; } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { //执行方法前打印日志 System.out.println(">>>jdk打印订单日志开始:proxy:"+proxy.getClass().toString()); Object reuslt = method.invoke(target, args);// java的反射机制执行方法 执行目标对象的方法 //执行方法后打印日志 System.out.println(">>>jdk打印订单日志结束"); return reuslt; } /** * 使用jdk动态代理创建代理类 * * @param <T> * @return */ public <T> T getProxy() { return (T) Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this); } }
4.测试
package com.mayikt.service; import com.mayikt.service.cglib.proxy.CglibMethodInterceptor; import com.mayikt.service.impl.OrderServiceImpl; import com.mayikt.service.jdk.proxy.JdkInvocationHandler; import com.mayikt.service.proxy.OrderServiceProxy; import net.sf.cglib.core.DebuggingClassWriter; import net.sf.cglib.proxy.Enhancer; public class Client { public static void main(String[] args) { // 1.使用jdk动态代理 System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles", "true");//可以动态生成.class文件 OrderService proxy = new JdkInvocationHandler(new OrderServiceImpl()).getProxy(); proxy.order(); } }
使用cglib实现动态代理
<dependency> <groupId>cglib</groupId> <artifactId>cglib</artifactId> <version>3.2.12</version> </dependency>
2.定义被代理类
package com.mayikt.service.impl; import com.mayikt.service.OrderService; public class OrderServiceImpl { public void order() { System.out.println("执行订单业务逻辑代码"); } }
3.创建生成动态代理类的类:CglibMethodInterceptor
package com.mayikt.service.cglib.proxy; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy; import java.lang.reflect.Method; public class CglibMethodInterceptor implements MethodInterceptor { public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { System.out.println(">>>>cglib日志收集开始...."); Object reuslt = proxy.invokeSuper(obj, args); System.out.println(">>>>cglib日志收集结束...."); return reuslt; } }
4.测试
package com.mayikt.service; import com.mayikt.service.cglib.proxy.CglibMethodInterceptor; import com.mayikt.service.impl.OrderServiceImpl; import com.mayikt.service.jdk.proxy.JdkInvocationHandler; import com.mayikt.service.proxy.OrderServiceProxy; import net.sf.cglib.core.DebuggingClassWriter; import net.sf.cglib.proxy.Enhancer; public class Client { public static void main(String[] args) { // 使用cglib动态代理 System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "D:\code");//可以动态生成class文件 CglibMethodInterceptor cglibMethodInterceptor = new CglibMethodInterceptor(); Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(OrderServiceImpl.class); enhancer.setCallback(cglibMethodInterceptor); OrderServiceImpl orderServiceImpl = (OrderServiceImpl) enhancer.create(); orderServiceImpl.order(); } }