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、动态代理,注意必须是接口

posted @ 2015-09-09 00:01  W&L  阅读(153)  评论(0)    收藏  举报