Jdk动态代理

优点:代理可以对被代理对象通过一个invoke 方法对被代理的对象实行统一的处理。Spring AOP 实现
缺点:只能对接口进行拦截
 
同一个类中方法调用会导致被调用方法动态代理失败。和spring事务失效原因类似。
 
// 服务提供者
public interface Subject{
    void doSomething();
}
 
public class RealSubject implements Subject{
 
    @Override
    void  doSomething(){
        System.out.println("真实服务!");
    }    
}
 
public class ProxyHandler implements InvocationHandler {
 
    private Object proxied;
 
    public ProxyHandler(Object proxied) {
        this.proxied = proxied;
    }
 
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
 
        //在转调具体目标对象之前,可以执行一些功能处理
        System.out.println("先干点");
        //转调具体目标对象的方法
 
        method.invoke( proxied, args);
 
        System.out.println("结束了,去喝酒");
        //在转调具体目标对象之后,可以执行一些功能处理
        return null;
    }
 
    public static void main(String[] args) {
        RealSubject real = new RealSubject();
        Subject proxySubject = (Subject) Proxy.newProxyInstance(Subject.class.getClassLoader(),
                new Class[]{Subject.class},
                new ProxyHandler(real));
        proxySubject.doSomething();
        Method[] methods = proxySubject.getClass().getDeclaredMethods();
 
        Field[] fields = proxySubject.getClass().getDeclaredFields();
    }
    
}
 
//生成的代理类
public class Proxy0 extends Proxy implements UserDao {
 
    //第一步, 生成构造器
    protected Proxy0(InvocationHandler h) {
        super(h);
    }
 
    //第二步, 生成静态域
    private static Method m1;   //hashCode方法
    private static Method m2;   //equals方法
    private static Method m3;   //toString方法
    private static Method m4;   //...
    
    //第三步, 生成代理方法
    @Override
    public int hashCode() {
        try {
            return (int) h.invoke(this, m1, null);
        } catch (Throwable e) {
            throw new UndeclaredThrowableException(e);
        }
    }
    
    @Override
    public boolean equals(Object obj) {
        try {
            Object[] args = new Object[] {obj};
            return (boolean) h.invoke(this, m2, args);
        } catch (Throwable e) {
            throw new UndeclaredThrowableException(e);
        }
    }
    
    @Override
    public String toString() {
        try {
            return (String) h.invoke(this, m3, null);
        } catch (Throwable e) {
            throw new UndeclaredThrowableException(e);
        }
    }
    
    @Override
    public void save(User user) {
        try {
            //构造参数数组, 如果有多个参数往后面添加就行了
            Object[] args = new Object[] {user};
            h.invoke(this, m4, args);
        } catch (Throwable e) {
            throw new UndeclaredThrowableException(e);
        }
    }
    
    //第四步, 生成静态初始化方法
    static {
        try {
            Class c1 = Class.forName(Object.class.getName());
            Class c2 = Class.forName(UserDao.class.getName());    
            m1 = c1.getMethod("hashCode", null);
            m2 = c1.getMethod("equals", new Class[]{Object.class});
            m3 = c1.getMethod("toString", null);
            m4 = c2.getMethod("save", new Class[]{User.class});
            //...
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
posted @ 2018-05-28 14:52  jason_moo  阅读(145)  评论(0编辑  收藏  举报