代理类是自己手工实现的,自己创建一个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(){ *** } }