JDK动态代理[1]---静态代理和动态代理

静态代理

  • 定义接口

public interface Subject {
    void visit();
}
  • 创建真正实现的类

public class RealSubject implements Subject {
    private String name = "proxy.state";

    @Override
    public void visit() {
        System.out.println(name);
    }
}
  • 创建静态代理类
public class ProxySubject implements Subject {

    private Subject subject;

    public ProxySubject(Subject subject) {
        this.subject = subject;
    }

    @Override
    public void visit() {
        subject.visit();
    }
}
  • 使用例子
public class Client {

    public static void main(String[] args) {
        ProxySubject subject = new ProxySubject(new RealSubject());
        subject.visit();
        RealSubject realSubject = new RealSubject();
        realSubject.visit();
    }
}

静态代理类优缺点

代理类接受一个Subject接口的对象,任何实现该接口的对象,都可以通过代理类进行代理,增加了通用性。
但是也有缺点,每一个代理类都必须实现一遍委托类(也就是realsubject)的接口,
如果接口增加方法,则代理类也必须跟着修改。
其次,代理类每一个接口对象对应一个委托对象,
如果委托对象非常多,则静态代理类就非常臃肿,难以胜任。

动态代理类

  • 定义接口

public interface Subject {
    void visit();
}
  • 创建真正实现的类

public class RealSubject implements Subject {
    private String name = "proxy.dynamic";

    @Override
    public void visit() {
        System.out.println(name);
    }
}
  • 创建动态代理类
public class DynamicProxy implements InvocationHandler {
    private Object object;

    public DynamicProxy(Object object) {
        this.object = object;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        String methodName = method.getName();
        before(methodName);
        Object result = method.invoke(object, args);
        after(methodName);
        return result;
    }

    /**
     * 前置通知
     * @param method
     */
    public void before(String method){
        System.out.println("before the method of "+method);

    }

    /**
     * 后置通知
     * @param method
     */
    public void after(String method){
        System.out.println("after the method of "+method);
    }
}
  • 使用例子
public class Client {

    public static void main(String[] args) {
        Subject realSubject = new RealSubject();
        DynamicProxy proxy = new DynamicProxy(realSubject);
        ClassLoader classLoader = realSubject.getClass().getClassLoader();
        Subject subject = (Subject) Proxy.newProxyInstance(classLoader, new Class[]{Subject.class}, proxy);
        subject.visit();
    }

}

动态代理总结

之前我们发现了静态代理会产生许多重复代码,不能很好的进行代码复用,而动态代理能够很好的解决这个问题,代理类TransactionHandler实现了InvocationHandler接口,并且它持有的目标对象类型是Object,因此事务控制代理类TransactionHandler能够代理任意的对象,为任意的对象添加事务控制的逻辑。因此动态代理才真正的将代码中横向切面的逻辑剥离了出来,起到代码复用的目的。但是动态代理也有缺点,一是它的实现比静态代理更加复杂也不好理解;二是它存在一定的限制,例如它要求需要代理的对象必须实现了某个接口;三是它不够灵活,动态代理会为接口中的声明的所有方法添加上相同的代理逻辑。当然,这只是JDK动态代理所存在的一些缺陷,动态代理还有另外的实现如使用CGLIB库

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值