设计模式:计算机程序的设计总结 代码的编写 设计 为了提高代码的问题
-
1.解决资源共享问题 单例 工厂模式
-
2.代码的拓展问题 代理模式 装饰器模式 适配器模式
二次开发: -
3.解决依赖(对象)创建:工厂 建造者模式
-
代理模式:解决代码拓展问题 功能的增强/改变
代理人: 去做事的人
被代理人:委托代理人做事的人 -
代理类:
被代理类:
静态代理: 指代理类,对象都需要程序要手动编写代码
动态代理:代理类,对象都是由程序自动生成 不需要程序员手写代理类代码
静态代理:需要遵守以下条件
- 1.需要一个公共的接口
- 2…被代理类需要实现该接口
- 3.代理类也需要实现该接口
- 4.代理类必须保持一个被代理对象(被代理类的对象)
- 5.代理类中的方法必须调用被代理类中对应的方法
- 6.代理类中增强的代码需要在调用被代理类的方法的前后执行
静态代理
import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; //1.公共接口 interface UserService{ public void addUser(); } //2.被代理类 class UserServiceImpl implements UserService{ @Override public void addUser() { System.out.println("调用mapper执行sql"); } } //3.代理类 class UserServiceProxy implements UserService{ //4.保持一个被代理对象 private UserService userService; public UserServiceProxy(UserService userService) { super(); this.userService = userService; } @Override public void addUser() { //6.代理类中增强的代码需要在调用被代理类的方法的前后执行 System.out.println("开启事务"); //5.调用被代理对象的方法 try{ //代理类中的方法必须调用被代理类中对应的方法 userService.addUser(); System.out.println("提交事务"); }catch (Exception e){ e.printStackTrace(); System.out.println("回滚"); } } } public class Test { public static void main(String[] args) { //创建代理类对象 UserService userService = new UserServiceProxy( new UserServiceImpl()); //使用 userService.addUser(); } }
JDK实现动态代理
- JDK使用方法
- 1.需要一个公共的接口
- 2.被代理类需要实现该接口
- 3.创建一个代理类工厂
3.1.工厂需要保持一个被代理类对象
3.2.需要指定一个方法,该方法用来返回一个代理类对象
JDK代理生成的代理类是实现了被代理类上所有接口的子类,以下代码为例:
- 生成的$Proxy0类是OrderServiceImpl的代理类,该类实现了OrderService接口,当通过该类对象调用相关方法时,会自动调用InvocationHandler中的invoke方法,将代理类对象、要调用的方法及相关参数作为形参传递到invoke方法中来
import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; // 接口 interface OrderService{ public boolean delOrder(int id); } // 被代理类 class OrderServiceImpl implements OrderService{ @Override public boolean delOrder(int id) { System.out.println("执行SQL:" + id); return true; } } // 代理类工厂 class ProxyFactory{ // 保持一个被代理类对象 private Object target; public ProxyFactory(Object target) { super(); this.target = target; } // 提供方法,返回代理类对象 public Object getProxy() { // 调用API创建代理类对象 // 参数1:类加载器 // 参数2:被代理类实现的接口 // 参数3:调用处理器,编写增强的代码 return Proxy.newProxyInstance( ProxyFactory.class.getClassLoader(), target.getClass().getInterfaces(), new InvocationHandler() { // 参数1:代理类对象 // 参数2:即将被调用的方法 // 参数3:调用method方法的参数 @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("-------------------"); System.out.println(proxy.getClass()); System.out.println(method.getName()); // for (Object arg : args) { // System.out.println(arg); // } System.out.println("-------------------"); System.out.println("开启事务"); //调用被代理类对象的方法 Object result = method.invoke(target, args); System.out.println("提交事务"); // 返回被代理类对象对应方法的返回值 return result; } }); } } public class Test{ public static void main(String[] args) { // 创建被代理类对象 OrderService target = new OrderServiceImpl(); // 创建工厂 ProxyFactory factory = new ProxyFactory(target); // 得到代理类对象 Object proxy = factory.getProxy(); System.out.println(proxy.getClass()); // $Proxy0 JDK代理生成的类 if (proxy instanceof OrderService) { System.out.println("YES"); OrderService orderService = (OrderService)proxy; // System.out.println(orderService.delOrder(1002)); } } }`
CGLIB动态代理
cglib代理又称作子类代理
生成的类是被代理类的子类 自动生成一个代理类 该代理类继承了被代理类
只要代理类不是被final修饰 都可以通过cglib代理生成代理类,对象
- 1.需要非final修饰的代理类
- 2.创建一个工厂类,
2.1工厂类也需要保持一个代理类对象
2.2指定一个方法,该方法要返回代理类对象
------需要导入两个包
import net.sf.cglib.proxy.Enhancer; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy; import java.lang.reflect.Method; class AddressServiceImpl{ public boolean address(String address){ System.out.println("添加地址"); return true; } } //工厂 class CglibFactory{ //代理类对象 private Object target; public CglibFactory(Object target) { this.target = target; } //提供方法 public Object getProxy(){ //1.创建一个工具类对象 Enhancer enhancer = new Enhancer(); //2.设置代理类的父类 enhancer.setSuperclass(target.getClass()); //3.设置处理的方法 enhancer.setCallback(new MethodInterceptor() { //参数 @Override public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable { System.out.println("开启事务"); //调用被代理类的方法 Object result = method.invoke(target,args); System.out.println("提交事务"); return result; } }); //创建代理类对象 return enhancer.create(); } } public class Test { public static void main(String[] args) { //1.创建被代理对象 AddressServiceImpl addressServiceImpl = new AddressServiceImpl(); //2.创建工厂 CglibFactory factory = new CglibFactory(addressServiceImpl); //3.调方法创建代理类对象 Object proxy = factory.getProxy(); System.out.println(proxy.getClass());//$$EnhancerByCGLIB$b5f61aa CGLIB动态代理创建 if(proxy instanceof AddressServiceImpl){ System.out.println("YES"); addressServiceImpl = (AddressServiceImpl)proxy; //调方法 addressServiceImpl.address("地球村"); } } }
JDK代理和CGLIB代理的区别
- 1.一个是JDK自带的 一个是第三方的
- 2.JDK代理要求被代理类必须实现接口 而CGLIB不需要
- 3.JDK代理生成的代理类是被代理类实现接口的子类。代理类需要需要实现这些接口, 而CGLIB生成的代理是被代理类的子类,代理类直接继承被代理类
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)