程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> 深刻淺析Spring 的aop完成道理

深刻淺析Spring 的aop完成道理

編輯:關於JAVA

深刻淺析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完成道理 ,願望對年夜家有所贊助!

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved