刘欣《码农翻身》之动态代理读后感

很生动地通过故事讲明白了Java动态代理这么个事,很棒:

为什么需要动态代理:人们希望在运行时动态修改类,但是,Java一个类一旦被装入方法区,就没法动态修改已经编译好的类了

解决方案:已经被加载或者正在运行的类既然不能被修改,就需要运行时动态生成一个代理类,达到“运行时动态修改类”的目的。

代理类是基于原来的类生成的新的类,具有运行时需要的功能,比如日志记录、事务支持、权限控制等。

如何实现功能的动态添加:

在看head first in Java时,有讲过接口的使用原则,符合has-a关系时使用接口,像是一个,当需要使用行为时使用接口,比如我想使用钢琴的发声功能,那我只需要实现钢琴的接口,接口里面有发声的功能,我是个人,我可以借助钢琴的接口发出钢琴的声音,但我不是钢琴,我是人。OK

所以在运行时需要动态添加的行为都可以认为是has-a关系,这样,新的类通过代理接口,就可以具有想要的功能了,下面详细说说代理接口:

public interface IHelloWorld{
    public void sayHello();
}
public class HelloWorld implements IHelloWorld{
    public void sayHello(){
        System.out.println("hello world!");
    }
}

现在是要在方法层面,给代理接口里的方法里添加功能,如何做这么细粒度的动态功能增强呢?(也可以说是织入,这个词,在国内是疯狂软件的李刚老师第一个提出来的,老师就真的很强,向走在前面的探路人,伟大的前辈们致敬!)

如何给代理接口中的这个目标方法,添加想要的功能呢?必须通过实现InvocationHandler接口,那么我们来看看这个接口里面有什么:

只有一个方法invoke!通过这个接口里的方法,写你需要动态增强的功能,比如日志记录等等。invoke中文:调用、引用,也就是说这个接口的功能,就是让你在运行期间动态增强时调用这个方法来代替原来的方法,达到在原方法基础上功能增强的目的。

public class LoggerHandler implements InvocationHandler {

	private Object target;

	public LoggerHandler(Object target) {
		this.target = target;
	}

	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                // 要增强的功能
		Logger.startLog();
                // 原来的方法
		Object result = method.invoke(target, args);
                // 要增强的功能
		Logger.endLog();
		return result;
	}

}

说说LoggerHandler,英文:处理日志记录的人,那么他就负责记录日志,代理类会调用它,并把真正的目标方法传给他(method变量)让他为目标方法添加日志记录的功能!

用Proxy.newProxyInstance(...)生成动态代理的类,这个类的代理方法(目标方法),包含了增强的功能!

IHelloWorld hw = new HelloWorld();
LoggerHandler handler = new LoggerHandler(hw);
IHelloWorld proxy = (IHelloWorld) Proxy.newProxyInstance(
    Thread.currentThread().getContextClassLoader(),
    hw.getClass().getInterface(),handler);
proxy.sayHello();

所以运行时其实是动态生成了代理类,并调用了LoggerHandler的invoke方法实现功能增强。

所以用面向对象的方式思考动态代理 ,总结下来就是:

我们要为一个对象的行为添加一个动作,比如啪啪啪前带套套的动作,此时我们需要把啪啪啪这个动作抽象出来,创建一个另我(代理对象),让全新的我实现这个啪啪啪的接口来执行啪啪啪动作,然后创建一个另一半,她拥有带套套的功能,它通过实现InvocationHandler接口,拥有invoke的功能,在这个功能里,可以设计她如何为我带套套,同时又可以拥有和我啪啪啪的行为(我把啪啪啪的method变量传递给她)。之后我在啪啪啪的时候(运行时),通过啪啪啪行为(面向接口编程)创建出来的全新的我,会把会带套套和我啪啪的另一半也融合进来,再调用啪啪啪行为时,就会有另一半为我带套套。实现了啪啪啪时才带套(运行时动态增加行为),而不是妹子还没约到就开始自己带套!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值