大家可能都聽說過spring的AOP編程,其實用java的反射機制也可以輕松實現(xiàn)。
我對AOP一個淺顯的理解就是,當(dāng)你在調(diào)用某個方法時,可以在調(diào)用之前或調(diào)用之后執(zhí)行一些預(yù)前操作或預(yù)后操作,而不用更改被調(diào)用方法把預(yù)前操作或預(yù)后操作硬編碼進去,你可以采用一種更靈活的方式,就是用代理模式來實現(xiàn)。
場景介紹:當(dāng)我們在吃水果的時候,我們并不是直接拿到水果就吃,而是1.先用水洗洗水果,再2.吃水果,3.吃完后再洗洗手,擦擦嘴
操作2是我們直接想做的事,而操作1和操作3則是預(yù)前和預(yù)后操作。
怎么做呢?
用組合方法簡單實現(xiàn)代理模式
實現(xiàn)1:
抽象一個Person接口,定義一個Person的實現(xiàn)類PersonA,再實現(xiàn)代理類
輸出結(jié)果:
washing:apple
person A is eating:apple
washing hands
用java原生java.lang.reflect.Proxy實現(xiàn)
實現(xiàn)2只適應(yīng)于特定接口的代理,如果我們想實現(xiàn)對任何接口的代理呢。
為什么現(xiàn)在只提到接口呢,可能你會問,為什么不直接對具體類進行代理呢?問的好,因為java.lang.reflect.Proxy類只能對接口進行代理,對具體類的代理要放到最后才講,所以為了由淺入深,先賣個關(guān)子。君莫急。
實現(xiàn)2:
輸出結(jié)果:
washing:apple
person A is eating:apple
washing hands
封裝實現(xiàn)2
有人可能會覺得,我還得再寫一個handler,再調(diào)用proxy.newInstance.好麻煩啊,能不能一次性搞定。好,給你。
雖然代理的是具體類,但需要具體類實現(xiàn)某個接口。但已經(jīng)能模擬直接代理具體類了。
如這里雖然直接代理PersonA,但還是需要Person接口。等到了實現(xiàn)4就可以去掉Person接口了。
我還加了點東西,至于是什么,你看看就知道了。
實現(xiàn)3
- public class ProxyBroker implements InvocationHandler {
- private Object delegate = null;
- private ProxyBroker(Object delegate) {
-
- this.delegate = delegate;
- }
- public static Object newProxy(Object obj) {
- ProxyBroker broker = new ProxyBroker(obj);
- Class[] interfaces = obj.getClass().getInterfaces();
- Class inteface = null;
- if (Pattern
- .compile("^java[x]{0,1}")
- .matcher(
- obj.getClass()
- .getCanonicalName()
- .subSequence(
- 0,
- obj.getClass().getCanonicalName()
- .length())).find()) {
- if (obj.getClass().getInterfaces().length > 0)
- inteface = obj.getClass().getInterfaces()[0];
- else
- System.err.println("no avaliable interface implemented by :"
- + obj.getClass().getCanonicalName());
- } else {
- for (Class interfacc : interfaces) {
- if (!Pattern
- .compile("^java[x]{0,1}")
- .matcher(
- interfacc.getCanonicalName().subSequence(0,
- interfacc.getCanonicalName().length()))
- .find()) {
- inteface = interfacc;
- }
- }
- }
- return Proxy.newProxyInstance(inteface.getClassLoader(),
- new Class[] { inteface }, broker);
- }
- @Override
- public Object invoke(Object proxy, Method method, Object[] args)
- throws Throwable {
-
- Object obj = null ;
- if(method.getName().equals("eat")){
- washFruit((String)args[0]) ;
- obj = method.invoke(delegate, args);
- clean();
- }else
- obj = method.invoke(delegate, args);
- return obj ;
-
- }
- public static void main(String[] args) {
- Person p = (Person) ProxyBroker.newProxy(new PersonA());
- p.eat("apple");
- Comparable intg = (Comparable) ProxyBroker.newProxy(new Integer(10));
- System.out.println(intg.compareTo(11));
- }
-
- private void washFruit(String fruit){
- System.out.println("washing:"+fruit);
- }
- private void clean(){
- System.out.println("washing hands");
- }
- }
washing:apple
person A is eating:apple
washing hands
-1 //看到這個就知道我加了什么了,我能對java.lang.Integer進行代理,但因為其實現(xiàn)的是Comparable<T>接口
//所以只能調(diào)用compareTo()方法
cglib實現(xiàn)
利器出現(xiàn)了,不需要你想代理的類實現(xiàn)莫個接口,是個類就行。所以在這里,可以去掉Person接口的定義了,不要再迷戀它了。很強大的吧
實現(xiàn)4
- public class CglibProxyBroker implements MethodInterceptor {
- private static CglibProxyBroker delegate = new CglibProxyBroker();
-
- private CglibProxyBroker() {
-
- }
- public static Object newInstance( Class clazz ){
- try{
- Enhancer e = new Enhancer();
- e.setSuperclass(clazz);
- e.setCallback(delegate);
- return e.create();
- }catch( Throwable e ){
- e.printStackTrace();
- throw new Error(e.getMessage());
- }
-
- }
-
- @Override
- public Object intercept(Object arg0, Method arg1, Object[] arg2,
- MethodProxy arg3) throws Throwable {
-
- Object obj = null;
- if(arg1.getName().equals("eat")){
- washFruit((String)arg2[0]);
- obj = arg3.invokeSuper(arg0, arg2);
- clean();
- }else
- obj = arg3.invokeSuper(arg0, arg2) ;
- return obj;
- }
-
-
- public static void main(String[] args) {
-
- Person p = (Person)CglibProxyBroker.newInstance(new PersonA().getClass());
- p.eat("apple");
-
- }
-
- private void washFruit(String fruit){
- System.out.println("washing:"+fruit);
- }
- private void clean(){
- System.out.println("washing hands");
- }
- }
washing:apple
person A is eating:apple
washing hands
本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請
點擊舉報。