大家可能都听说过spring的AOP编程,其实用java的反射机制也可以轻松实现。
我对AOP一个浅显的理解就是,当你在调用某个方法时,可以在调用之前或调用之后执行一些预前操作或预后操作,而不用更改被调用方法把预前操作或预后操作硬编码进去,你可以采用一种更灵活的方式,就是用代理模式来实现。
场景介绍:当我们在吃水果的时候,我们并不是直接拿到水果就吃,而是1.先用水洗洗水果,再2.吃水果,3.吃完后再洗洗手,擦擦嘴
操作2是我们直接想做的事,而操作1和操作3则是预前和预后操作。
怎么做呢?
用组合方法简单实现代理模式
实现1:
抽象一个Person接口,定义一个Person的实现类PersonA,再实现代理类
输出结果:
washing:apple
person A is eating:apple
washing hands
用java原生java.lang.reflect.Proxy实现
实现2只适应于特定接口的代理,如果我们想实现对任何接口的代理呢。
为什么现在只提到接口呢,可能你会问,为什么不直接对具体类进行代理呢?问的好,因为java.lang.reflect.Proxy类只能对接口进行代理,对具体类的代理要放到最后才讲,所以为了由浅入深,先卖个关子。君莫急。
实现2:
输出结果:
washing:apple
person A is eating:apple
washing hands
封装实现2
有人可能会觉得,我还得再写一个handler,再调用proxy.newInstance.好麻烦啊,能不能一次性搞定。好,给你。
虽然代理的是具体类,但需要具体类实现某个接口。但已经能模拟直接代理具体类了。
如这里虽然直接代理PersonA,但还是需要Person接口。等到了实现4就可以去掉Person接口了。
我还加了点东西,至于是什么,你看看就知道了。
实现3
washing:apple
person A is eating:apple
washing hands
-1 //看到这个就知道我加了什么了,我能对java.lang.Integer进行代理,但因为其实现的是Comparable<T>接口
//所以只能调用compareTo()方法
cglib实现
利器出现了,不需要你想代理的类实现莫个接口,是个类就行。所以在这里,可以去掉Person接口的定义了,不要再迷恋它了。很强大的吧
实现4
washing:apple
person A is eating:apple
washing hands