原理
使用一个代理将对象包装起来,然后用该代理对象取代原始对象。任何对原始对象的调用都要通过代理。代理对象决定是否以及何时将方法调用转到原始对象上。
静态代理
package proxy;/*** 静态代理* 特点: 代理类和被代理类在编译期间就确定下来,,* 当需求改变时,不改变原本的代码 横向增强方法 类似aop*/interface ClothFactory {void produceCloth();}//代理类class ProxyClothFactory implements ClothFactory {private ClothFactory factory; //用被代理对象实例化public ProxyClothFactory(ClothFactory factory) {this.factory = factory;}@Overridepublic void produceCloth() {System.out.println("代理工厂做准备工作");factory.produceCloth();System.out.println("代理工厂结束");}}//被代理类class BeClothFactory implements ClothFactory {@Overridepublic void produceCloth() {System.out.println("被代理对象");}}public class StaticProxyTest {public static void main(String[] args) {//创建被代理对象BeClothFactory be = new BeClothFactory();//创建代理对象ProxyClothFactory proxyClothFactory = new ProxyClothFactory(be);proxyClothFactory.produceCloth();}}
动态代理
package proxy;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;//面向切面编程class HumanUtil {public void method1() {System.out.println("=======方法1=========")}public void method2() {System.out.println("=======方法2=========")}}/*** 动态代理举例*/interface Human {String getBelief();void eat(String food);}//被代理类class SuperMan implements Human {@Overridepublic String getBelief() {return "can fly";}@Overridepublic void eat(String food) {System.out.println("like" + food);}}//动态代理/*1.如何根据加载到内存中的类动态创建对象2.通过代理类的对象调用方法时,如何动态调用被代理类方法*/class ProxyFactory {//调用次方法,返回一个代理类的对象,解决问题一public static Object getProxyInstance(Object obj) {return Proxy.newProxyInstance(obj.getClass().getClassLoader(),obj.getClass().getInterfaces() ,new InvocationHandler(){//通过调用代理类的对象 调用方法a时,就会自动调用如下的方法@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {//增强方法//obj 被代理对象,args 参数,method方法HumanUtil util = new HumanUtile();util.method1();//横向增强Object interval = method.invoke(obj,args);System.out.println("动态代理方法的增强,被增强的方法具有一些统一的特性,");return interval;}});}}public class DynamicProxy {public static void main(String[] args) {Human human = new SuperMan();Human humanProxy = (Human) ProxyFactory.getProxyInstance(human);humanProxy.eat("啥啥啥"); //调用方法的时候 会执行上面invoke方法//System.out.println(humanProxy);System.out.println(humanProxy.getBelief());System.out.println("*******************");BeClothFactory be = new BeClothFactory();ClothFactory beProxy = (ClothFactory) ProxyFactory.getProxyInstance(be);beProxy.produceCloth();}}
cglib
public class Client {public static void main(String[] args) {//创建目标对象TeacherDao teacherDao = new TeacherDao();ProxyFactory proxyFactory = new ProxyFactory(teacherDao);//获取代理对象,并将目标对象传递给代理对象TeacherDao target = (TeacherDao) proxyFactory.getProxyInstance();//执行代理对象方法,触发intecept方法,从而实现对目标对象的调用target.teach();}}public class ProxyFactory implements MethodInterceptor {//维护一个目标对象private Object target;//构造器 传入一个被代理的对象public ProxyFactory(Object target) {this.target=target;}//返回一个代理对象 是target的代理对象public Object getProxyInstance(){//创建一个工具类Enhancer enhancer = new Enhancer();//设置父类enhancer.setSuperclass(target.getClass());//设置回调函数enhancer.setCallback(this);//创建子类对象 即代理对象return enhancer.create();}//重写 intercept方法 ,会调用目标对象的方法@Overridepublic Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {System.out.println("Cglib代理模式开始");Object returnval =method.invoke(target,objects);return returnval;}}public class TeacherDao {public void teach(){System.out.println("授课ing cglib代理不需要实现借口");}}
