代理模式的定义很简单:给某一对象提供一个代理对象,并由代理对象控制对原对象的引用
静态代理
静态代理为业务实现类和业务代理类两部分组成,业务实现类负责实现主要的业务方法,业务代理类负责对调用的业务方法预处理,调用业务时,不是直接通过业务实现类来调用的,而是通过业务代理类的同名方法来调用被代理类处理过的业务方法
public class UserDaoProxy implements IUserDao{ private IUserDao userDao; public UserDaoProxy(IUserDao userDao) { this.userDao = userDao; } @Override public void save() { System.out.println("开启事务");//扩展了额外功能 userDao.save(); System.out.println("提交事务"); } }
动态代理
在程序运行时运用反射机制动态创建而成
jdk动态代理
只能代理实现了接口的类,代理对象本身并不真正实现服务,而是通过调用委托类的对象相关方法,提供特定服务,通过接口中的方法名,在动态生成的代理类中调用委托实现类的同名方法
定义业务逻辑接口,实现业务逻辑接口创建业务实现类
public class BookFacadeProxy implements InvocationHandler { private Object target;//这其实业务实现类对象,用来调用具体的业务方法 /** * 绑定业务对象并返回一个代理类 */ public Object bind(Object target) { this.target = target; //接收业务实现类对象参数 //通过反射机制,创建一个代理类对象实例并返回,用户进行方法调用时使用,创建代理对象时,需要传递该业务类的类加载器、全部的接口、代理类实例 return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this); } /** * 包装调用方法:进行预处理、调用后处理 */ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object result=null; System.out.println("预处理操作——————"); //调用真正的业务方法 result=method.invoke(target, args); System.out.println("调用后处理——————"); return result; } }
cglib动态代理
针对类实现代理,通过字节码技术为一个类创建子类,并在子类中采用方法拦截的技术拦截所有父类方法的调用,顺势织入横切逻辑,通过继承业务类,生成的动态代理类是业务类的子类,通过重写业务方法进行代理
public class BookFacadeCglib implements MethodInterceptor { private Object target;//业务类对象,供代理方法中进行真正的业务方法调用 //相当于JDK动态代理中的绑定 public Object getInstance(Object target) { this.target = target; //给业务对象赋值 Enhancer enhancer = new Enhancer(); //创建加强器,用来创建动态代理类 enhancer.setSuperclass(this.target.getClass()); //为加强器指定要代理的业务类(即:为下面生成的代理类指定父类) //设置回调:对于代理类上所有方法的调用,都会调用CallBack,而Callback则需要实现intercept()方法进行拦截/预处理 enhancer.setCallback(this); // 创建动态代理类对象并返回 return enhancer.create(); } // 实现回调方法 public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { System.out.println("预处理——————"); proxy.invokeSuper(obj, args); //调用业务类(父类中)的方法 System.out.println("调用后操作——————"); return null; }