标签:pat 参数 增强 种类型 ofo load 结果 cep strong
代理模式
在代理模式(Proxy Pattern)中:
①一个类代表另一个类的功能。这种类型的设计模式属于结构型模式。
②我们创建具有现有对象的对象,以便向外界提供功能接口。
介绍
作用:为其他对象提供一种代理以控制对这个对象的访问,举个例子来说明代理的作用:假设我们想邀请一位明星,那么并不是直接联系明星,而是联系明星的经纪人,来达到同样的目的.明星就是一个目标对象,他只要负责活动中的节目,而其他琐碎的事情就交给他的代理人(经纪人)来解决.这就是代理思想在现实中的一个例子。
主要解决:在直接访问对象时带来的问题,比如说:要访问的对象在远程的机器上。在面向对象系统中,有些对象由于某些原因(比如对象创建开销很大,或者某些操作需要安全控制,或者需要进程外的访问),直接访问会给使用者或者系统结构带来很多麻烦,我们可以在访问此对象时加上一个对此对象的访问层。
优点: 1、职责清晰 2、高扩展性 3、智能化。
缺点: 1、由于在客户端和真实主题之间增加了代理对象,因此有些类型的代理模式可能会造成请求的处理速度变慢。 2、实现代理模式需要额外的工作,有些代理模式的实现非常复杂。
一、静态代理
我们将创建一个SomeService接口和实现SomeService接口的实体类。ServiceProxy是一个代理类,减少ServiceSomeImpl对象加载的内存占用。proxyTest,我们的测试类使用ServiceProxy来获取加载的SomeService对象,并按需求进行打印输入。
实现步骤1
创建一个接口。
1 // 目标接口 2 public interface SomeService { 3 String doSome(); 4 }
步骤2
创建实现接口的实体类。
1 // 目标类 2 public class SomeServiceImpl implements SomeService{ 3 @Override 4 public String doSome() { 5 return "I come from China";6 } 7 }
步骤3
创建实现接口的代理类。
1 // 静态代理类,要实现和目标类一样的接口 2 public class ServiceProxy implements SomeService{ 3 SomeService target; 4 5 @Override 6 public String doSome() { 7 // 调用目标接口的方法,使方法输出的内容变为全部变为大写。 8 return target.doSome().toUpperCase(); 9 } 10 11 // 构造函数 12 public ServiceProxy() { 13 } 14 15 public ServiceProxy(SomeService target) { 16 super(); 17 this.target = target; 18 } 19 }
步骤4
创建测试类。
1 // 测试类 2 public class TestProxy { 3 public static void main(String[] args) { 4 // 定义目标对象 5 SomeService target = new SomeServiceImpl(); 6 // 定义目标对象的代理对象(通过代理对象对目标对象进行增强——输入内容变为大写) 7 SomeService proxy = new ServiceProxy(target); 8 // 代理对象调用目标接口中的方法 9 String result = proxy.doSome(); 10 System.out.println("输出结果:" + result); 11 } 12 }
步骤5
执行测试类的main方法,执行结果如下:
输出结果:I COME FROM CHINA
二、动态代理(不需要手动创建代理类。1.如果目标对象实现了接口,采用JDK动态代理,2.如果目标对象没有实现接口,必须采用CGLIB动态代理)
①JDK动态代理
1.java.lang.reflect.Proxy:生成动态代理类和对象;
2.java.lang.reflect.InvocationHandler(处理器接口):可以通过invoke方法实现对真实角色的代理访问。每次通过 Proxy 生成的代理类对象都要指定对应的处理器对象。3
3.我们将创建一个SomeService接口和实现SomeService接口的实体类,以及一个测试类。
实现步骤1
进行代码编写之前,必须得先引入cglib-nodep的jar包,本案例引入的jar包为 cglib-nodep-3.2.10.jar,在这给大家提供一个jar包的下载地址:https://mvnrepository.com/artifact/cglib/cglib-nodep/3.2.10
步骤2
创建一个接口。
1 // 目标接口 2 public interface SomeService { 3 String doSome(); 4 }
步骤3
创建实现接口的实体类。
1 // 目标类 2 public class SomeServiceImpl implements SomeService{ 3 @Override 4 public String doSome() { 5 return "I come from China"; } 6 }
步骤4
创建测试类。
1 // 测试类 2 public class TestProxy { 3 public static void main(String[] args) { 4 // 定义目标对象 5 final SomeService target = new SomeServiceImpl(); 6 // 定义目标对象的代理对象 7 // 参数1——目标类的类加载器:target.getClass().getClassLoader() 8 // 参数2——目标类实现的所有接口:target.getClass().getInterfaces() 9 // 参数3——调用处理器:new InvocationHandler() 10 SomeService proxy = (SomeService)Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), 11 new InvocationHandler() { 12 // 参数1——proxy:代理对象 13 // 参数2——method:目标方法 14 // 参数3——args:目标方法的参数 15 @Override 16 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { 17 // 调用目标方法 18 String result1 = (String) method.invoke(target, args); 19 return result1.toUpperCase(); 20 } 21 }); 22 // 代理对象调用目标接口中的方法 23 String result2 = proxy.doSome(); 24 System.out.println("输出结果:" + result2); 25 } 26 }
步骤5
执行测试类的main方法,执行结果如下:
输出结果:I COME FROM CHINA
②CGLIB动态代理
1.CGLIB动态代理是针对代理的类, 动态生成一个子类, 然后子类覆盖代理类中的方法, 如果是private或是final类修饰的方法,则不会被重写。
2.CGLIB是一个功能强大,高性能的代码生成包。它为没有实现接口的类提供代理,为JDK的动态代理提供了很好的补充。通常可以使用Java的动态代理创建代理,但当要代理的类没有实现接口或者为了更好的性能,CGLIB是一个好的选择。
3.作为一个开源项目,其代码托管在github,地址为:https://github.com/cglib/cglib
实现步骤1
在进行代码编写之前,必须导入cglib-nodep的jar包,本案例导入的jar包为 cglib-nodep-3.2.10.jar,在这给大家提供一个该jar包的下载地址:https://mvnrepository.com/artifact/cglib/cglib-nodep/3.2.10
步骤2
创建目标实体类。
1 // 目标类 2 public class SomeServiceImpl { 3 4 public String doSome() { 5 return "I come from China"; 6 } 7 }
步骤3
创建cglib动态代理工厂。
1 // cglib动态代理工厂 2 public class CglibProxyFactory implements MethodInterceptor{ 3 4 // 创建目标对象 5 private SomeServiceImpl target; 6 // 创建构造器 7 public CglibProxyFactory() { 8 super(); 9 } 10 public CglibProxyFactory(SomeServiceImpl target) { 11 super(); 12 this.target = target; 13 } 14 15 // 创建cglib代理对象的方法 16 public SomeServiceImpl proxyCreator() { 17 // 创建增强器 18 Enhancer enhancer = new Enhancer(); 19 // 指定父类(指定目标类) 20 enhancer.setSuperclass(SomeServiceImpl.class); 21 // 指定回调接口对象 22 enhancer.setCallback(this); 23 // 创建cglib代理对象并返回该对象 24 return (SomeServiceImpl) enhancer.create(); 25 } 26 27 @Override 28 public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { 29 // 反射调用目标对象方法,实现增强操作 30 String result1 = (String) method.invoke(target, args); 31 return result1.toUpperCase(); 32 } 33 }
步骤4
创建测试类。
1 // 测试类 2 public class TestProxy { 3 public static void main(String[] args) { 4 // 定义目标对象 5 SomeServiceImpl target = new SomeServiceImpl(); 6 // 定义目标对象的代理对象(通过cglib代理对象的方法进行创建) 7 SomeServiceImpl proxy = new CglibProxyFactory(target).proxyCreator(); 8 // 调用目标对象方法 9 String result2 = proxy.doSome(); 10 System.out.println("输出结果:" + result2); 11 } 12 }
步骤5
执行测试类的main方法,执行结果如下:
输出结果:I COME FROM CHINA
通过以上的简单案例演示,相信你能很快的掌握代理模式的使用。
标签:pat 参数 增强 种类型 ofo load 结果 cep strong
原文地址:https://www.cnblogs.com/fy0206/p/10707320.html