Ⅰ 什麼是面向切面編程
Aspect Oriented Programming(AOP),面向切面編程,是一個比較熱門的話題。AOP主要實現的目的是針對業務處理過程中的切面進行提取,它所面對的是處理過程中的某個步驟或階段,以獲得邏輯過程中各部分之間低耦合性的隔離效果。比如我們最常見的就是日誌記錄了,舉個例子,我們現在提供一個查詢學生信息的服務,但是我們希望記錄有誰進行了這個查詢。如果按照傳統的OOP的實現的話,那我們實現了一個查詢學生信息的服務介面(StudentInfoService)和其實現 類 (StudentInfoServiceImpl.java),同時為了要進行記錄的話,那我們在實現類(StudentInfoServiceImpl.java)中要添加其實現記錄的過程。這樣的話,假如我們要實現的服務有多個呢?那就要在每個實現的類都添加這些記錄過程。這樣做的話就會有點繁瑣,而且每個實現類都與記錄服務日誌的行為緊耦合,違反了面向對象的規則。那麼怎樣才能把記錄服務的行為與業務處理過程中分離出來呢?看起來好像就是查詢學生的服務自己在進行,但卻是背後日誌記錄對這些行為進行記錄,並且查詢學生的服務不知道存在這些記錄過程,這就是我們要討論AOP的目的所在。AOP的編程,好像就是把我們在某個方面的功能提出來與一批對象進行隔離,這樣與一批對象之間降低了耦合性,可以就某個功能進行編程。
Ⅱ Java編程中的AOP和IOC分別是什麼呢,什麼時候用呢
控制反轉(IOC)
(理解好Ioc的關鍵是要明確「誰控制誰,控制什麼,為何是反轉(有反轉就應該有正轉了),哪些方面反轉了」)
1、Ioc—Inversion of Control:即「控制反轉」,不是什麼技術,而是一種設計思想。在Java開發中,Ioc意味著將你設計好的對象交給容器控制,而不是傳統的在你的對象內部直接控制。
2、誰控制誰,控制什麼:傳統Java SE程序設計,我們直接在對象內部通過new進行創建對象,是程序主動去創建依賴對象;而IoC是有專門一個容器來創建這些對象即由Ioc容器來控制對象的創建。
誰控制誰?當然是IoC 容器控制了對象。
控制什麼?那就是主要控制了外部資源獲取(不只是對象包括比如文件等)。
3、為何是反轉,哪些方面反轉了: 有反轉就有正轉,傳統應用程序是由我們自己在對象中主動控制去直接獲取依賴對象,也就是正轉;而反轉則是由容器來幫忙創建及注入依賴對象。
為何是反轉?因為由容器幫我們查找及注入依賴對象,對象只是被動的接受依賴對象,所以是反轉。
哪些方面反轉了?依賴對象的獲取被反轉了。
還是不明白沒事,下面搞個簡單案例來說就懂啦 !!!
例子:當我們在任何一個有實際開發意義的程序項目中,我們會使用很多類來描述他們特有的功能,並且通過類與類之間的相互協作來完成特定的業務邏輯。這個時候,每個類都需要負責管理與自己有交互的類的引用和依賴,代碼將會變的異常難以維護和極高的高耦合。而IOC的出現正是用來解決這個問題,我們通過IOC將這些依賴對象的創建、協調工作交給spring容器去處理,每個對象值需要關注其自身的業務邏輯關系就可以了。在這樣的角度上來看,獲得依賴的對象的方式,進行了反轉,變成了由spring容器控制對象如何獲取外部資源(包括其他對象和文件資料等)。
總的來說:IOC就是通過在Xml配置文件里依賴注入來解決代碼問題。
IOC的注入類型有幾種?主要可以劃分為三種:構造函數注入、屬性注入和介面注入。Spring支持構造函數注入和屬性注入
面向切面(AOP)
(面向切面編程,AOP其實只是OOP的補充而已,AOP基本上是通過代理機制實現的。)
我們管切入到指定類指定方法的代碼片段稱為切面,而切入到哪些類、哪些方法則叫切入點。有了AOP,我們就可以把幾個類共有的代碼,抽取到一個切片中,等到需要時再切入對象中去,從而改變其原有的行為。
我們都知道 Java 是 OOP-面向對象編程的,它有自己的優勢,也有自己的不足。比如說:在我們開發中,都會有一條業務主線(即客戶的需求)。而我們要做的就是實現這個主線上的需求。我們在實現這些功能的時候,經常要干一些額外的不可避免的事情,比如事務的管理,日誌的記錄等,就很繁雜且代碼量增多,所以 Spring 提供了另一種角度來思考程序結構,也就是把這一些事情剝離出來,然後適時適地的把它們加入到我們的代碼中,比如說 聲明式事務管理的時候,我們在 service 層檢測到save*、update*這些方法要被調用的時候,我們先進行開啟事務什麼的,這就是AOP,面向編程的思想。
AOP的術語:
1、通知(Advice):就是你想要的功能,也就是上面說的 安全,事物,日誌等。你給先定義好把,然後在想用的地方用一下
2、連接點(JoinPoint):這個更好解釋了,就是spring允許你使用通知的地方,那可真就多了,基本每個方法的前,後(兩者都有也行),或拋出異常時都可以是連接點,spring只支持方法連接點.其他如aspectJ還可以讓你在構造器或屬性注入時都行,不過那不是咱關注的,只要記住,和方法有關的前前後後(拋出異常),都是連接點。
3、切入點(Pointcut):上面說的連接點的基礎上,來定義切入點,你的一個類里,有15個方法,那就有幾十個連接點了對把,但是你並不想在所有方法附近都使用通知(使用叫織入,以後再說),你只想讓其中的幾個,在調用這幾個方法之前,之後或者拋出異常時干點什麼,那麼就用切點來定義這幾個方法,讓切點來篩選連接點,選中那幾個你想要的方法。
4、切面(Aspect):切面是通知和切入點的結合。現在發現了吧,沒連接點什麼事情,連接點就是為了讓你好理解切點,搞出來的,明白這個概念就行了。通知說明了干什麼和什麼時候干(什麼時候通過方法名中的before,after,around等就能知道),而切入點說明了在哪干(指定到底是哪個方法),這就是一個完整的切面定義。
5、引入(introction):允許我們向現有的類添加新方法屬性。這不就是把切面(也就是新方法屬性:通知定義的)用到目標類中嗎
6、目標(target):引入中所提到的目標類,也就是要被通知的對象,也就是真正的業務邏輯,他可以在毫不知情的情況下,被咱們織入切面。而自己專注於業務本身的邏輯。
7、代理(proxy):怎麼實現整套aop機制的,都是通過代理,這個一會給細說。
8、織入(weaving):把切面應用到目標對象來創建新的代理對象的過程。有3種方式,spring採用的是運行時,為什麼是運行時,後面解釋。
Ⅲ Java核心技術:Spring是什麼
從簡單性、可測試性和松耦合的角度而言,任何Java應用都可以從Spring中受益。 簡單來說,Spring就是一個輕量級的控制反轉(IoC)和面向切面(AOP)的容器框架。 下面從整體上認識一下Spring的主要特徵: *輕量:從大小與開銷兩方面而言Spring都是輕量的。此外,Spring是非侵入式的:使用Spring,我們的類還是pojo類,完全不用繼承和實現Spring的類和介面等。 也就是說,使用Spring的應用中的對象不依賴於Spring的特定類。 *IoC:Spring通過控制反轉技術促進了松耦合。當應用了IoC,一個對象依賴的其它對象會通過被動的方式傳遞進來,而不是這個對象自己創建或者查找依賴對象。可以認為IoC與JNDI相反--不是我們自己控制對象從容器中查找依賴,而是容器在對象初始化時不等對象請求就主動將依賴傳遞給它,這就是DI--依賴注入。 基本上就是對象不用自己動手管理和創建。完全由容器管理,我們只管用就行。 *AOP:Spring提供了面向切面的編程支持,AOP將與程序業務無關的內容分離提取,應用對象只實現它們應該做的--完成業務邏輯--僅此而已。它們並不負責其它的系統級關注點,例如日誌或事務支持。 AOP將與業務無關的邏輯橫切進真正的邏輯中。 *框架:Spring可以將簡單的組件配置、組合成為復雜的應用。在Spring中,應用對象被聲明式地組合,典型地是在一個XML文件里。Spring也提供了很多基礎功能(事務管理、持久化框架集成等等),而用戶就有更多的時間和精力去開發應用邏輯。 所有Spring的這些特徵都能幫助我們夠編寫更干凈、更可管理、並且更易於測試的代碼。它們也為Spring中的各種模塊提供了基礎支持。 *藉助Spring,榮國依賴注入,AOP應用,面向介面編程,來降低業務組件之間的耦合度,增強系統的擴展性。 * 讓已有的技術和框架更加易用。 *利用其對hibernate的SessionFactory、事務管理的封裝,更簡潔的應用hibernate. *Spring並不完全依賴於Spring,開發者可自由選用Spring框架的部分或全部 *利用AOP思想,集中處理業務邏輯,減少重復代碼,構建優雅的解決方案。 *低侵入式設計,代碼污染極低。 Spring致力於J2EE應用的各層的解決方案,而不是僅僅專注於某一層的方案。可以說Spring是企業應用開發的"一站式"選擇,並貫穿表現層、業務層及持久層。 雖然Spring可以一站式解決整個項目問題,但是Spring並不想取代那些已有的框架,而是與它們無縫地整合。Spring可以降低各種框架的使用難度,他提供了對各種優秀框架(如Struts、Hibernate、Hessian、Quartz等)的直接支持。 使用Spring的主要目的是使J2EE易用和促進好的編程習慣,Spring的目標就是讓已有的技術更加易用。 所以Spring的一個重要思想就是整合和兼容。
Ⅳ Spring中的AOP概念
spring的APO是指面向切面編程,它的主要實現原理主要兩種。
1.通過Java動態代理(反射)機制,在要執行的方法前後,加上事務控制或日誌。
2.通過修改Java位元組碼的方式,修改你編譯好的類,在要執行的方法前後,加上事務控制或日誌。
通知、切入點等其實就是用來配置在什麼類、什麼位置來執行、執行什麼方法等。
掘塵
舉個列子:
給下面的方法加孫散皮上日誌記錄:
publicvoidsave(Objectdata){
//保存到資料庫邏輯
}
通過SpringAOP的方式配置日誌後,最終程序執行時(也許是反射,也許是修改class),實則差際上在執行save(obj)時,執行了下面的邏輯:
log.info("開始保存");
save(obj);
log.info("結束保存");
Ⅳ java中的Spring裡面的ioc和aop有什麼區別他們都有什麼用
IOC的基本概念是:不創建對象,但是描述創建它們的方式。在代碼中不直接與對象和服務連接,但在配置文件中描述哪一個組件需要哪一項服務。Spring容器負責將這些聯系在一起。也就是說,Spring的IOC負責管理各種對象的創建、清除以及它們之間的聯系。AOP是指面向切面編程(也叫面向方面),可以通過預編譯方式和運行期動態代理實現在不修改源代碼的情況下給程序動態統一添加功能的一種技術。一般用於事務管理、許可權控制、錯誤處理等各種業務中共同性的東西。
Ⅵ 使用java語言,如何對一個類中的靜態方法做切面編程
packagecom.classloader.test;
importjava.lang.reflect.InvocationTargetException;
importjava.lang.reflect.Method;
importjava.lang.reflect.Modifier;
{
privateCallBackcallBack;
publicAOPCallStaticMehtod(CallBackcallBack){
this.callBack=callBack;
}
publicstaticinterfaceCallBack{
voidbefore(Methodmethod);
voidafter(Methodmethod,Objectresult);
}
@SuppressWarnings({"unchecked","rawtypes"})
publicObjectcallMethod(Classclazz,StringmethodName,Class[]parameterTypes,Object[]parameters){
Objectresult=null;
try{
Methodmethod=null;
if(parameterTypes==null||parameterTypes.length==0){
method=clazz.getMethod(methodName);
if(Modifier.isStatic(method.getModifiers())){
callBack.before(method);
result=method.invoke(null);
callBack.after(method,result);
}else{
System.out.println("這不是一個靜態方法");
}
}else{
method=clazz.getMethod(methodName,parameterTypes);
if(Modifier.isStatic(method.getModifiers())){
callBack.before(method);
result=method.invoke(null,parameters);
callBack.after(method,裂亮result);
}else{
System.out.println("這不是一個靜態方法");
}
}
}catch(NoSuchMethodException|SecurityException|IllegalAccessException|IllegalArgumentException
|InvocationTargetExceptione){
if()肆消寬{
System.out.println("沒有這個方法");
}else{
System.out.println("calliserror!");
}
}
returnresult;
}
publicstaticvoidmain(String[]args){
CallBackcallBack=newCallBack(){
@Override
publicvoidbefore(Methodmethod){
if(method.getName().equals("test1")||method.getName().equals("test2")){
System.out.println(method.getName()+"方法在調用之前被攔橋大截,可以在這里切面編程");
}
}
@Override
publicvoidafter(Methodmethod,Objectresult){
if(method.getName().equals("test1")||method.getName().equals("test2")){
System.out.println(method.getName()+"方法調用以後被攔截,可以在這里切面編程");
System.out.println(method.getName()+"執行結果是:"+result);
System.out.println("-----------------------------------------");
}
}
};
=newAOPCallStaticMehtod(callBack);
AOPCallStaticMehtod.callMethod(Test.class,"test1",newClass[]{String.class},newObject[]{"ppppppppppp"});
AOPCallStaticMehtod.callMethod(Test.class,"test2",null,null);
}
}
classTest{
publicstaticvoidtest1(Stringaa){
System.out.println(aa);
}
publicstaticStringtest2(){
System.out.println("fffffffffffffffff");
return"test2result";
}
}
Ⅶ aspect java
aspect java是臘頌一個面向切面的框架,它擴展了Java語言。AspectJ定義了AOP語法所以它有一個專門的編譯器用輪裂鄭來生成遵守Java位元組編碼規范的Class文件。
首先是幾個概念:
aspect(層面)
pointcut(切入點)
advice(建議)
weave(織入)
LTW(載入期織入 load time weave)
按照aspectj的語法規則,一個aspect就是很多pointcut和advice的集合,也就是一個*.aj的文件。
一個pointcut就是對target class的切入點定義,類似Java class定義中的field。
一個advice就是對target class的行為改變,類似Java class中的method。
weave就是aspectj runtime庫把aspect織入到target class的行為。
LTW就是指運行期間動態織入aspect的行為,它是相對靜態織入行為(包括對源文件、二進制文件的修改)。
一般來講,從運行速度上來說,源跡靜態織入比動態織入要快些。因為LTW需要使用aspectj本身的classloader,它的效率要低於jdk的classloader,因此當需要load的class非常多時,就會很慢的。
舉個例子來說明aspectj的使用:
scenario: Example工程需要使用一個類Line存在於第三方庫Line.jar中,但是Line本身沒有實現Serializable介面,並且其toString方法輸出也不完善。因此這兩點都需要修改。
Line的實現:
package bean; public class Line {undefined protected int x1 = 0; protected int x2 = 0; public int getX1(){undefined return x1; } public int getX2(){undefined return x2; } public void setLength(int newX, int newY){undefined setX1(newX); setX2(newY); } public void setX1(int newX) {undefined x1 = newX; } public void setX2(int newY) {undefined x2 = newY; } public String toString(){undefined return "(" + getX1() + ", " + getX2() + ")" ; } } Main entry : public class MyExample {undefined private Line line = null; public MyExample() {undefined line = new Line(); System.err.println("Line implement serializable interface : " + (line instanceof Serializable)); } public void showMe() {undefined System.out.println("Show all about me ..."); System.out.println(line.toString()); } public static void main(String[] args) {undefined MyExample demo = new MyExample(); // i want to change the action of show me, but i cannot get line source. // so i will trying load-time weaving demo.showMe(); } } output : Line implement serializable interface : true Show all about me ... (0, 0)Ⅷ Java中的@Aspect
這個面向切面編程,@Aspect 就是註解方式來注冊切面的