原理:
使用一个代理将对象包装起来, 然后用该代理对象取代原始对象.
任何对原始对象的调用都要通过代理. 代理对象决定是否以及何时将方法调用转到原始对象上
1,静态代理
特征是代理类和目标对象的类都是在编译期间确定下来,不利于程序的扩展。
同时,每一个代理类只能为一个接口服务,这样一来程序开发中必然产生过多的代理。
以下为静态代理例子
package com.atguigu.java1; //静态代理模式 //接口 interface ClothFactory{ void productCloth(); } //被代理类 class NikeClothFactory implements ClothFactory{ @Override public void productCloth() { System.out.println("Nike工厂生产一批衣服"); } } //代理类 class ProxyFactory implements ClothFactory{ ClothFactory cf; //创建代理类的对象时,实际传入一个被代理类的对象 public ProxyFactory(ClothFactory cf){ this.cf = cf; } @Override public void productCloth() { System.out.println("代理类开始执行,收代理费$1000"); cf.productCloth(); } } public class TestClothProduct { public static void main(String[] args) { NikeClothFactory nike = new NikeClothFactory();//创建被代理类的对象 ProxyFactory proxy = new ProxyFactory(nike);//创建代理类的对象 proxy.productCloth(); } }
2,动态代理
package com.atguigu.java1; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; //动态代理的使用,体会反射是动态语言的关键 interface Subject { void action(); } // 被代理类 class RealSubject implements Subject { public void action() { System.out.println("我是被代理类,记得要执行我哦!么么~~"); } } class MyInvocationHandler implements InvocationHandler { Object obj;// 实现了接口的被代理类的对象的声明 // ①给被代理的对象实例化②返回一个代理类的对象 public Object blind(Object obj) { this.obj = obj; return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj .getClass().getInterfaces(), this); } //当通过代理类的对象发起对被重写的方法的调用时,都会转换为对如下的invoke方法的调用 @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { //method方法的返回值时returnVal Object returnVal = method.invoke(obj, args); return returnVal; } } public class TestProxy { public static void main(String[] args) { //1.被代理类的对象 RealSubject real = new RealSubject(); //2.创建一个实现了InvacationHandler接口的类的对象 MyInvocationHandler handler = new MyInvocationHandler(); //3.调用blind()方法,动态的返回一个同样实现了real所在类实现的接口Subject的代理类的对象。 Object obj = handler.blind(real); Subject sub = (Subject)obj;//此时sub就是代理类的对象 sub.action();//转到对InvacationHandler接口的实现类的invoke()方法的调用 //再举一例 NikeClothFactory nike = new NikeClothFactory(); ClothFactory proxyCloth = (ClothFactory)handler.blind(nike);//proxyCloth即为代理类的对象 proxyCloth.productCloth(); } }