JDK代理机制
JDK代理
静态代理:由程序员创建或特定工具自动生成源代码,再对其编译。在程序运行前,代理类的.class文件就已经存在了。
动态代理:在程序运行时,运用反射机制动态创建而成。
JDK代理的是接口
JDK的动态代理依靠接口实现,如果有些类并没有实现接口,则不能使用JDK代理,这就要使用cglib动态代理了
接口BookFacade
public interface BookDao { public void addBook(); }
实现接口类
public class BookDaoImpl implements BookDao { public void addBook() { System.out.println("增加图书方法。。。"); } }
代理类
/** * JDK动态代理代理类 * 静态代理:由程序员创建或特定工具自动生成源代码,再对其编译。在程序运行前,代理类的.class文件就已经存在了。 * 动态代理:在程序运行时,运用反射机制动态创建而成。 * @author wwl * */ public class BookIntercept implements InvocationHandler { private Object target; public void setTarget(Object target) { this.target = target; } /** * 绑定委托对象并返回一个代理类 * * @param target * @return */ public Object bind(Object target) { this.target = target; // 取得代理对象 /** * ClassLoader loader:类加载器 * Class<?>[] interfaces:得到全部的接口 * InvocationHandler h:得到InvocationHandler接口的子类实例 */ return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this); // 要绑定接口(这是一个缺陷,cglib弥补了这一缺陷) } /** * 回调方法 * Object proxy:指被代理的对象。 * Method method:要调用的方法 * Object[] args:方法调用时所需要的参数 */ 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; } }
调用:
BookInterceptor bi = new BookInterceptor();//创建代理对象 BookDao bookDao=new BookDaoImpl(); bi.setTarget(bookDao);//设置代理目标对象 BookDao bookProxy=(BookDao) Proxy.newProxyInstance(bookDao.getClass().getClassLoader(), bookDao.getClass().getInterfaces(), bi); bookProxy.addBook(); //或者 BookDao bookProxy1 = (BookDao) proxy.bind(new BookDaoImpl()); bookProxy1.addBook();
总结:其实代理对象bookProxy是实现BookFacade接口的对象,其可以直接执行接口中方法,当执行其中的方法时,方法会通过proxy调用invoke方法执行,
当再每次执行某些方法时,进行执行特定操作时,应该如何实现?
1、通过实现原接口,进行重写方法,但如果有很多地方则不可行
2、通过继承原接口实现类,在方法中添加并通过super调用原实现类,需避免继承,如果一个对象需要包含多个原接口实现类的功能则不可以
3、通过组合模式(一般通过组合代替继承),注入多个原接口实现类到对象中,不灵活
4、动态代理,注意必须是接口