深刻淺析Spring 的aop完成道理。本站提示廣大學習愛好者:(深刻淺析Spring 的aop完成道理)文章只能為提供參考,不一定能成為您想要的結果。以下是深刻淺析Spring 的aop完成道理正文
甚麼是AOP
AOP(Aspect-OrientedProgramming,面向方面編程),可以說是OOP(Object-Oriented Programing,面向對象編程)的彌補和完美。OOP引入封裝、繼續和多態性等概念來樹立一種對象條理構造,用以模仿公共行動的一個聚集。當我們須要為疏散的對象引入公共行動的時刻,OOP則顯得力所不及。也就是說,OOP許可你界說從上到下的關系,但其實不合適界說從左到右的關系。例如日記功效。日記代碼常常程度地分布在一切對象條理中,而與它所分布到的對象的焦點功效毫有關系。關於其他類型的代碼,如平安性、異常處置和通明的連續性也是如斯。這類分布在遍地的有關的代碼被稱為橫切(cross-cutting)代碼,在OOP設計中,它招致了年夜量代碼的反復,而晦氣於各個模塊的重用。
簡介
前段時光寫的java設計形式--署理形式,比來在看Spring Aop的時刻,認為於署理形式應當有親密的接洽,因而決議懂得下Spring Aop的完成道理。
說起AOP就不能不說下OOP了,OOP中引入封裝、繼續和多態性等概念來樹立一種對象條理構造,用以模仿公共行動的一個聚集。然則,假如我們須要為部門對象引入公共部門的時刻,OOP就會引入年夜量反復的代碼。例如:日記功效。
AOP技巧應用一種稱為“橫切”的技巧,剖解封裝的對象外部,並將那些影響了多個類的公共行動封裝到一個可重用模塊,如許就可以削減體系的反復代碼,下降模塊間的耦合度,並有益於將來的可操作性和可保護性。AOP把軟件體系分為兩個部門:焦點存眷點和橫切存眷點。營業處置的重要流程是焦點存眷點,與之關系不年夜的部門是橫切存眷點。橫切存眷點的一個特色是,他們常常產生在焦點存眷點的多處,而遍地都根本類似。好比權限認證、日記、事務處置。
完成道理
後面在進修署理形式的時刻,懂得到署理形式分為靜態署理和靜態署理。如今我們就以署理形式為基本先完成我們本身的AOP框架,再來研討Spring的AOP的完成道理。
先以靜態署理完成,靜態署理症結是在署理對象和目的對象完成配合的接口,而且署理對象持有目的對象的援用。
公共接口代碼:
public interface IHello { /** * 營業辦法 * @param str */ void sayHello(String str); } 目的類代碼: public class Hello implements IHello{ @Override public void sayHello(String str) { System.out.println("hello "+str); } }
署理類代碼,我們給它添加日記記載功效,在辦法開端前後履行特定的辦法,是否是和AOP特殊像呢?
public class ProxyHello implements IHello{ private IHello hello; public ProxyHello(IHello hello) { super(); this.hello = hello; } @Override public void sayHello(String str) { Logger.start();//添加特定的辦法 hello.sayHello(str); Logger.end(); } }
日記類代碼:
public class Logger { public static void start(){ System.out.println(new Date()+ " say hello start..."); } public static void end(){ System.out.println(new Date()+ " say hello end"); } }
測試代碼:
public class Test { public static void main(String[] args) { IHello hello = new ProxyHello(new Hello());//假如我們須要日記功效,則應用署理類 //IHello hello = new Hello();//假如我們不須要日記功效則應用目的類 hello.sayHello("今天"); } }
如許我們就完成了一個最簡略的AOP,然則如許會存在一個成績:假如我們像Hello如許的類許多,那末,我們是否是要去寫許多個HelloProxy如許的類呢。其實也是一種很費事的事。在jdk1.3今後,jdk跟我們供給了一個API java.lang.reflect.InvocationHandler的類, 這個類可讓我們在JVM挪用某個類的辦法時靜態的為些辦法做些甚麼事。上面我們就來完成靜態署理的完成。
靜態署理完成重要是完成InvocationHandler,而且將目的對象注入到署理對象中,應用反射機制來履行目的對象的辦法。
接話柄現與靜態署理雷同,署理類代碼:
public class DynaProxyHello implements InvocationHandler{ private Object target;//目的對象 /** * 經由過程反射來實例化目的對象 * @param object * @return */ public Object bind(Object object){ this.target = object; return Proxy.newProxyInstance(this.target.getClass().getClassLoader(), this.target.getClass().getInterfaces(), this); } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object result = null; Logger.start();//添加額定的辦法 //經由過程反射機制來運轉目的對象的辦法 result = method.invoke(this.target, args); Logger.end(); return result; } }
測試類代碼:
public class DynaTest { public static void main(String[] args) { IHello hello = (IHello) new DynaProxyHello().bind(new Hello());//假如我們須要日記功效,則應用署理類 //IHello hello = new Hello();//假如我們不須要日記功效則應用目的類 hello.sayHello("今天"); } }
看完下面的代碼能夠和Spring AOP比擬有一個成績,日記類只能在辦法前後打印,然則AOP應當是可以在知足前提便可以履行,一切能否可以將DynaPoxyHello對象和日記操尴尬刁難象(Logger)解耦呢?
看上面代碼完成,將將DynaPoxyHello對象和日記操尴尬刁難象(Logger)解耦:
我們要在被署理對象的辦法後面或許前面去加上日記操作代碼(或許是其它操作的代碼),那末,我們可以籠統出一個接口,這個接口裡就只要兩個辦法:一個是在被署理對象要履行辦法之前履行的辦法,我們取名為start,第二個辦法就是在被署理對象履行辦法以後履行的辦法,我們取名為end。
Logger的接口:
public interface ILogger { void start(Method method); void end(Method method); }
Logger的接話柄現:
public class DLogger implements ILogger{ @Override public void start(Method method) { System.out.println(new Date()+ method.getName() + " say hello start..."); } @Override public void end(Method method) { System.out.println(new Date()+ method.getName() + " say hello end"); } }
靜態署理類:
public class DynaProxyHello implements InvocationHandler{ //挪用對象 private Object proxy; //目的對象 private Object target; public Object bind(Object target,Object proxy){ this.target=target; this.proxy=proxy; return Proxy.newProxyInstance(this.target.getClass().getClassLoader(), this.target.getClass().getInterfaces(), this); } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object result = null; //反射獲得操作者的實例 Class clazz = this.proxy.getClass(); //反射獲得操作者的Start辦法 Method start = clazz.getDeclaredMethod("start", new Class[]{Method.class}); //反射履行start辦法 start.invoke(this.proxy, new Object[]{this.proxy.getClass()}); //履行要處置對象的本來辦法 method.invoke(this.target, args); //反射獲得操作者的end辦法 Method end = clazz.getDeclaredMethod("end", new Class[]{Method.class}); //反射履行end辦法 end.invoke(this.proxy, new Object[]{method}); return result; } }
測試代碼:
public class DynaTest { public static void main(String[] args) { IHello hello = (IHello) new DynaProxyHello().bind(new Hello(),new DLogger());//假如我們須要日記功效,則應用署理類 //IHello hello = new Hello();//假如我們不須要日記功效則應用目的類 hello.sayHello("今天"); } }
經由過程下面例子,可以發明經由過程靜態署理和發射技巧,曾經根本完成了AOP的功效,假如我們只須要在辦法履行前打印日記,則可以不完成end()辦法,如許便可以掌握打印的機會了。假如我們想讓指定的辦法打印日記,我們只須要在invoke()辦法中加一個對method名字的斷定,method的名字可以寫在xml文件中,如許我們便可以完成以設置裝備擺設文件停止解耦了,如許我們就完成了一個簡略的spring aop框架。
以上內容是小編給年夜家引見的Spring 的aop完成道理 ,願望對年夜家有所贊助!