本文共 4423 字,大约阅读时间需要 14 分钟。
代理就是在不修改源代码的情况下,对该类的方法进行扩展(增强)。
interface ClothFactory{ void productCloth();}//代理类class ProxyClothFactory implements ClothFactory{ private ClothFactory factory; public ProxyClothFactory(ClothFactory factory) { this.factory = factory; } @Override public void productCloth() { System.out.println("我是衣服代理类"); factory.productCloth(); System.out.println("代理工厂后续工作"); }}//被代理类class NickClothFactory implements ClothFactory{ @Override public void productCloth() { System.out.println("Nick工厂生产衣服"); }}public class StaticProxy { public static void main(String[] args) { //创建被代理类 NickClothFactory nickClothFactory=new NickClothFactory(); //创建代理类 ProxyClothFactory proxyClothFactory = new ProxyClothFactory(nickClothFactory); proxyClothFactory.productCloth(); }}
动态代理主要是通过Proxy创建接口代理对象,所以首要问题就是如何通过Proxy创建接口代理对象。
创建接口代理对象主要使用的方法是:
第一个参数:我们可以填写接口实现类的类加载器
第二个参数:实现类的实现接口 第三个参数:创建一个InvocationHandler接口的实现子类(增强方法在该子类里面)public static Object newProxyInstance(ClassLoader loader, Class [] interfaces, InvocationHandler h)
这里通过一个demo学习:
OneDao:
public interface OneDao { public int add(int a,int b);}
OneDaoImpl:
public class OneDaoImpl implements OneDao { @Override public int add(int a, int b) { return a+b; }}
我们的目的就是增强OneDaoImpl的add方法。
创建InvocationHandler 的实现子类:
class MyHandler implements InvocationHandler{ //传入被代理的实现类 private Object object; public MyHandler(Object object){ this.object=object; } //增强方法逻辑 /** * * @param proxy :当前代理对象 * @param method:当前执行方法名称 * @param args :执行方法参数 * @return * @throws Throwable */ @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { //方法前 System.out.println("方法前...."+method.getName()); //获得方法的第一个参数 System.out.println(args[0]); //执行方法 Object res=method.invoke(object,args); //方法后 System.out.println("方法后...."+method.getName()); return res; }}
获得代理对象:
@Test public void method(){ OneDaoImpl oneDao=new OneDaoImpl(); OneDao dao = (OneDao) Proxy.newProxyInstance(OneDaoImpl.class.getClassLoader(), OneDaoImpl.class.getInterfaces(), new MyHandler(oneDao)); int add = dao.add(1, 2); System.out.println(add); }
interface Human{ int getAge(); String getName();}//被代理类class GDPeople implements Human{ private int age; private String name; public GDPeople(int age, String name) { this.age = age; this.name = name; } @Override public int getAge() { return age; } @Override public String getName() { return name; }}/** 要想实现动态代理,需要解决的问题: 1,如果根据加载到内存中的被代理类,动态创建一个代理类及其对象 2,当通过代理类的对象调用方法时,如何动态的去调用被代理类中的同名方法 */class ProxyFactory{ //调用此方法,返回一个代理类的对象。解决问题一 public static Object getProxyInstance(Object obj){ //obj:被代理类的对象 MyInvocationHandler handler=new MyInvocationHandler(); handler.bind(obj); return Proxy.newProxyInstance(obj.getClass().getClassLoader(),obj.getClass().getInterfaces(),handler); }}class MyInvocationHandler implements InvocationHandler { private Object object;//需要使用被代理类的对象进行赋值 public void bind(Object object){ this.object=object; } //当我们通过代理类的对象,调用方法a时,就会自动调用如下的方法:invoke() //当被代理类要执行的方法a功能就声明在invoke()中 @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { //method:即为代理类对象调用的方法,此方法也就作为了被代理类对象要调用的方法 System.out.println("代理之前"); //obj:被代理类的对象 Object invoke = method.invoke(object, args); //上述方法的返回值就作为当前类中invoke()的返回值 System.out.println("代理之后"); return invoke; }}public class ProxyTest { public static void main(String[] args) { GDPeople gdPeople=new GDPeople(15,"Tom"); Human proxyInstance = (Human) ProxyFactory.getProxyInstance(gdPeople); //当通过代理类对象调用方法时,会自动的调用被代理类中同名的方法 int age = proxyInstance.getAge(); String name = proxyInstance.getName(); System.out.println("name:"+name+"-----age:"+age); }}
转载地址:http://chca.baihongyu.com/