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();
        }
    }
    

转载于:https://www.cnblogs.com/xzn-smy/p/9100153.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值