1.什么是代理?
1.代购,中介,换ip,商家等等
使用代理模式的作用:
1.功能增强:在你原有的功能上,增加了额外的功能,新增加的功能,叫做功能增强
2.控制访问:代理类不让你访问目标,例如商家不让用户访问厂家
实现代理的方式
1.静态代理:
代理类是自己手工实现的,自己创建一个java类。同时你所要代理的
目标类是确定的。
特点:1)实现简单 2)容易理解
当项目中目标类和代理类很多之后,代理类数量过多
3)当目标类增加了,代理类可能也需要成倍的增加,代理类数量过多
4)当你的接口功能增加了,或者修改了,会影响众多的实现类,厂家类,代理都需要
修改,影响比较多。
例子:模拟用户购买U盘的行为
用户是客户端类
商家:代理,代理某个品牌的U盘
厂家:目标类
三者的关系:用户(客户端)—–商家(代理)—厂家(目标)
商家和厂家都是卖U盘的,他们完成的功能都是一致的,都是卖U盘的
实现步骤
1.创建一个接口,定义卖U盘的方法,表示你的厂家和商家做的事情
2.创建厂家类,实现1步骤的接口
3.创建商家,就是代理类,也需要实现1步骤中的接口
4.创建客户类,
测试用例:
UserService接口
package com.wang.pojo; public interface UserService { public void add(); public void delete(); public void update(); public void query(); }
UserService接口实现类UserServiceImpl
package com.wang.pojo; public class UserServiceImpl implements UserService{ @Override public void add() { System.out.println("增加了一个用户"); } @Override public void delete() { System.out.println("删除了一个用户"); } @Override public void update() { System.out.println("修改了一个用户"); } @Override public void query() { System.out.println("查询了一个用户"); } }
UserService接口静态代理类
package com.wang.pojo; public class UserSericeProxy implements UserService{ private UserService service; public void setService(UserService service) { this.service = service; } @Override public void add() { beforeDoing(); service.add(); afterDoing(); } @Override public void delete() { beforeDoing(); service.delete(); afterDoing(); } @Override public void update() { beforeDoing(); service.update(); afterDoing(); } @Override public void query() { beforeDoing(); service.query(); afterDoing(); } private void beforeDoing(){ System.out.println("代理对象方法执行前"); } private void afterDoing(){ System.out.println("代理对象方法执行后"); } }
2.动态代理:
在静态代理中目标类很多时候,可以使用动态代理,避免静态代理的缺点。
动态代理中目标类即使很多,代理类数量可以很少。
当你修改了接口中的方法时,不会影响代理类
动态代理:
在程序执行过程中,使用jdk的反射机制,创建代理类对象,并动态指定要代理对象。
换句话说:动态代理是一种创建java对象的能力,让我不用创建taobao类就能创建
代理类对象。
在java中,要创建对象:
1.创建类文件,java文件编译为class
2.使用构造方法,创建类的对象
什么是动态代理?
使用jdk的反射机制,创建对象的能力,创建的时代理类的对象。而不是创建类文件,
不用写。
动态: 在程序执行时,调用jdk的方法才能创建代理类的对象
动态代理方式:
第一种,JDk动态代理(理解):使用java反射包中的类和接口实现动态代理的功能
反射包 java.lang.reflect,里面有三各类:InvocationHandler,Method,Proxy.
第二种,通过CGLB动态代理(了解):第三方的一个工具库,创建代理对象。
cglib的原理时继承,cglib通过继承目标类,创建它的子类,在子类中重写
父类中同名的方法,实现功能的修改
因为cglib是继承,重写方法,所以要求目标类不能是final,方法也不能是final.
cglib要求目标类比较宽松,只要能继承就可以了,cglib在很多框架中都可以使用
,比如mybatis,spring框架中都有使用。
cgLib代理
jdK动态代理
1.反射,Method类,表示方法,类中的方法。通过Method可以执行某个方法。
2.jdk动态代理的实现
反射包 java.lang.reflect,里面有三个类: InvocationHandler,Method,Proxy.
1)InvocationHandler(调用处理器) 接口:就一个方法invoke()
invoke():表示代理对象要执行的功能代码。你的代理类要完成的功能
就写在invoke()中
代理类完成的功能:
1.调用目标方法,执行目标方法的功能
2.功能增强,在目标方法调用时,增加功能
public Object invoke(Object proxy, Method method, Object[] args) //Object proxy:JDK创建的代理对象,无需赋值。 //Method method:目标类中的方法,jdk提供method对象的 // Object[] args:目标类中的方法参数
2)Method类:表示方法的,确切的说就是目标类中的方法
作用:通过Method可以执行某个目标类的方法,Method.invoke();
method.invoke(目标对象,方法的参数);
3)Proxy类:创建对象都是new 类的构造方法()
现在是使用Proxy类的方法,代表new的使用。
方法:静态方法 newProxyInstance() 作用是:创建代理对象,等同于静态代理中的 TaoBao tb=new TaoBao(); public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) //ClassLoader loader 类加载器,负责像内存中加载对象的, 使用反射 //获取对象的ClassLoader 举例 类a a.getClass().getClassLoader() //目标对象的类加载器 //Class<?>[] interfaces 目标对象所实现的接口,也是反射获取的 //InvocationHandler h:我们自己写的,代理类要完成的功能 //返回值 就是代理对象。
实现动态代理的步骤
//1.创建接口,定义目标类要完成的功能 //2.创建目标类实现接口 //3.创建IncovateHandler接口的实现类,在invoke方法中完成代理类的功能 //功能有二:1.调用目标方法 2.增加功能 //4.使用Proxy类的静态方法,创建代理对象,并把返回值转为接口类型 UsbShell proxy=(UsbShell)Proxy.newProxyInstance(UsbKingFactory.class.getClassLoader(),factory.getClass().getInterfaces(),handler ); //com.sun.proxy.$Proxy0 //通过代理对象执行方法调用,执行handler //proxy.sell(1),此时执行的是handler中的incoke方法
动态代理能做什么?
可以在不改变原来目标方法功能的前提下,可以在代理中增强自己的功能代理.
程序开发中的意义:
比如,你所在的项目中,有一个功能是其他人(公司的其他部门,其他小组的人)写好的,
你可以使用,
GoNong.class,
GoNong gn=new GoNong(),
gn.print();
你发现这个功能,现在还缺点,不能完全满足我项目的需求,我需要在gn.print()执行后,需要自己在增加代码,用代理实现gn.print()调用时,增加自己代理,而不用改原来的GoNong文件。
测试用例
代理类处理程序接口InvocationHandler实现类
package com.wang.pojo; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; //万能的invocationHandler实现类 public class MyInvocationHandler implements InvocationHandler { //被代理对象 private Object target; public void setTarget(Object target) { this.target = target; } //生成代理对象 public Object getProxy(){ return Proxy.newProxyInstance(this.getClass().getClassLoader(),target.getClass().getInterfaces(),this); } //处理代理实例 @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { //可以在此添加额外功能 /* * 额外功能 * */ // see(); return method.invoke(target,args); } private void see(){ System.out.println("房产中介参与租房业务"); } }
万能动态代理类实现模板
package com.wang.staticProxy.demo04; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; //万能的invocationHandler实现类 public class MyInvocationHandler implements InvocationHandler { //被代理对象 private Object target; public void setTarget(Object target) { this.target = target; } //生成代理对象 public Object getProxy(){ return Proxy.newProxyInstance(this.getClass().getClassLoader(),target.getClass().getInterfaces(),this); } //处理代理实例 @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { //可以在此添加额外功能 /* * 额外功能 * */ // someMethod();
Object o=method.invoke(target,args);
return 0;
}
private void someMethod(){ *** } }
推荐的动态代理相关文章
原创文章,作者:端木书台,如若转载,请注明出处:https://blog.ytso.com/tech/pnotes/268239.html