本博中關于spring的文章:Spring IOC和AOP原理,Spring事務原理探究宇弛,Spring配置文件屬性詳解鸡典,Spring中的代理模式
Spring提供了很多輕量級應用開發(fā)實踐的工具集合,這些工具集以接口枪芒、抽象類彻况、或工具類的形式存在于Spring中谁尸。通過使用這些工具集,可以實現(xiàn)應用程序與各種開源技術及框架間的友好整合纽甘。比如有關jdbc封裝的數(shù)據(jù)訪問工具Spring JDBC良蛮,有關編寫單元測試的spring test包以及spring-mock,有關訪問動態(tài)腳本語言的Spring Script悍赢,另外還有發(fā)送郵件的工具Spring Mail决瞳、日程及任務處理工具Spring scheduling等。 可以這么說泽裳,大多數(shù)企業(yè)級應用開發(fā)中經(jīng)常涉及到的一些通用的問題瞒斩,都可以通過Spring提供的一些實用工具包輕松解決
依賴注入的三種方式:(1)接口注入(2)Construct注入(3)Setter注入
控制反轉(IoC)與依賴注入(DI)是同一個概念,引入IOC的目的:(1)脫開涮总、降低類之間的耦合胸囱;(2)倡導面向接口編程、實施依賴倒換原則瀑梗;?(3)提高系統(tǒng)可插入烹笔、可測試、可修改等特性抛丽。
具體做法:(1)將bean之間的依賴關系盡可能地抓換為關聯(lián)關系谤职;
(2)將對具體類的關聯(lián)盡可能地轉換為對Javainterface的關聯(lián),而不是與具體的服務對象相關聯(lián)亿鲜;
(3)Bean實例具體關聯(lián)相關javainterface的哪個實現(xiàn)類的實例允蜈,在配置信息的元數(shù)據(jù)中描述;
(4)由IoC組件(或稱容器)根據(jù)配置信息蒿柳,實例化具體bean類饶套、將bean之間的依賴關系注入進來。
org.springframework.beans及org.springframework.context包是Spring IoC容器的基礎垒探。BeanFactory提供的高級配置機制妓蛮,使得管理任何性質(zhì)的對象成為可能。ApplicationContext是BeanFactory的擴展圾叼,功能得到了進一步增強蛤克,比如更易與Spring AOP集成、消息資源處理(國際化處理)夷蚊、事件傳遞及各種不同應用層的context實現(xiàn)(如針對web應用的WebApplicationContext)构挤。 簡而言之,BeanFactory提供了配制框架及基本功能撬码,而ApplicationContext則增加了更多支持企業(yè)核心內(nèi)容的功能儿倒。ApplicationContext完全由BeanFactory擴展而來,因而BeanFactory所具備的能力和行為也適用于ApplicationContext。
IoC容器負責容納bean夫否,并對bean進行管理彻犁。在Spring中,BeanFactory是IoC容器的核心接口凰慈。它的職責包括:實例化汞幢、定位、配置應用程序中的對象及建立這些對象間的依賴微谓。Spring為我們提供了許多易用的BeanFactory實現(xiàn)森篷,XmlBeanFactory就是最常用的一個。該實現(xiàn)將以XML方式描述組成應用的對象以及對象間的依賴關系豺型。XmlBeanFactory類將持有此XML配置元數(shù)據(jù)仲智,并用它來構建一個完全可配置的系統(tǒng)或應用。
實現(xiàn)化容器:
[java]view plaincopy
Resource?resource?=newFileSystemResource("beans.xml");
BeanFactory?factory?=newXmlBeanFactory(resource);
...?或...
ClassPathResource?resource?=newClassPathResource("beans.xml");
BeanFactory?factory?=newXmlBeanFactory(resource);
...?或...
ApplicationContext?context?=newClassPathXmlApplicationContext(
newString[]?{"applicationContext.xml","applicationContext-part2.xml"});
//?of?course,?an?ApplicationContext?is?just?a?BeanFactory
BeanFactory?factory?=?(BeanFactory)?context;
將XML配置文件分拆成多個部分是非常有用的姻氨。為了加載多個XML文件生成一個ApplicationContext實例钓辆,可以將文件路徑作為字符串數(shù)組傳給ApplicationContext構造器。而bean factory將通過調(diào)用bean defintion reader從多個文件中讀取bean定義肴焊。
通常情況下前联,Spring團隊傾向于上述做法,因為這樣各個配置并不會查覺到它們與其他配置文件的組合娶眷。另外一種方法是使用一個或多個的元素來從另外一個或多個文件加載bean定義似嗤。所有的元素必須放在元素之前以完成bean定義的導入。 讓我們看個例子:
在上面的例子中届宠,我們從3個外部文件:services.xml烁落、messageSource.xml及themeSource.xml來加載bean定義。這里采用的都是相對路徑豌注,因此顽馋,此例中的services.xml一定要與導入文件放在同一目錄或類路徑,而messageSource.xml和themeSource.xml的文件位置必須放在導入文件所在目錄下的resources目錄中幌羞。正如你所看到的那樣,開頭的斜杠‘/’實際上可忽略竟稳。因此不用斜杠‘/’可能會更好一點属桦。
根據(jù)Spring XML配置文件的Schema(或DTD),被導入文件必須是完全有效的XML bean定義文件他爸,且根節(jié)點必須為元素聂宾。
BeanFactory和FactoryBean的區(qū)別,簡而言之诊笤,BeanFactory是加載的容器系谐,加載一切的BEAN,而FactoryBean用于創(chuàng)建代理類
===============================================================上面已講到
BeanFactory它的職責包括:實例化、定位纪他、配置應用程序中的對象及建立這些對象間的依賴鄙煤。
FactoryBean(通常情況下,bean無須自己實現(xiàn)工廠模式茶袒,Spring容器擔任工廠角色梯刚;但少數(shù)情況下,容器中的bean本身就是工廠薪寓,其作用是產(chǎn)生其它bean實例),作用是產(chǎn)生其他bean實例亡资。通常情況下,這種bean沒有什么特別的要求向叉,僅需要提供一個工廠方法锥腻,該方法用來返回其他bean實例。由工廠bean產(chǎn)生的其他bean實例母谎,不再由Spring容器產(chǎn)生瘦黑,因此與普通bean的配置不同,不再需要提供class元素销睁。
ProxyFactoryBean用于創(chuàng)建代理(根據(jù)Advisor生成的Bean供璧,也就是TargetBean的代理)
我們的Advisor,PointCut等等冻记,其最終目的都是為了創(chuàng)建這個代理睡毒。
===============================================================下面將講到
AOP全名Aspect-Oriented Programming,中文直譯為面向切面(方面)編程冗栗,當前已經(jīng)成為一種比較成熟的編程思想演顾,可以用來很好的解決應用系統(tǒng)中分布于各個模塊的交叉關注點問題。在輕量級的J2EE中應用開發(fā)中隅居,使用AOP來靈活處理一些具有橫切性質(zhì)的系統(tǒng)級服務钠至,如事務處理、安全檢查胎源、緩存棉钧、對象池管理等,已經(jīng)成為一種非常適用的解決方案涕蚤。 AOP中比較重要的概念有:Aspect宪卿、JoinPoint、PonitCut万栅、Advice佑钾、Introduction、Weave烦粒、Target Object休溶、Proxy Object等
引介(Introduction)是指給一個現(xiàn)有類添加方法或字段屬性,引介還可以在不改變現(xiàn)有類代碼的情況下,讓現(xiàn)有的Java類實現(xiàn)新的接口兽掰,或者為其指定一個父類從而實現(xiàn)多重繼承芭碍。相對于增強(Advice)可以動態(tài)改變程序的功能或流程來說,引介(Introduction)則用來改變一個類的靜態(tài)結構禾进。比如我們可以讓一個現(xiàn)有為實現(xiàn)java.lang.Cloneable接口豁跑,從而可以通過clone()方法復制這個類的實例。
攔截器是用來實現(xiàn)對連接點進行攔截泻云,從而在連接點前或后加入自定義的切面模塊功能艇拍。在大多數(shù)JAVA的AOP框架實現(xiàn)中圆恤,都是使用攔截器來實現(xiàn)字段訪問及方法調(diào)用的攔截(interception)扫尖。所用作用于同一個連接點的多個攔截器組成一個連接器鏈(interceptor chain),鏈接上的每個攔截器通常會調(diào)用下一個攔截器截驮。Spring AOP及JBoos AOP實現(xiàn)都是采用攔截器來實現(xiàn)的婆瓜。
面向對象編程(OOP)解決問題的重點在于對具體領域模型的抽象快集,而面向切面編程(AOP)解決問題的關鍵則在于對關注點的抽象。也就是說廉白,系統(tǒng)中對于一些需要分散在多個不相關的模塊中解決的共同問題个初,則交由AOP來解決;AOP能夠使用一種更好的方式來解決OOP不能很好解決的橫切關注點問題以及相關的設計難題來實現(xiàn)松散耦合猴蹂。因此院溺,面向方面編程 (AOP) 提供另外一種關于程序結構的思維完善了OOP,是OOP的一種擴展技術磅轻,彌補補了OOP的不足珍逸。
AOP概念詳解:注意以下實例
—方面(Aspect):一個關注點的模塊化,這個關注點實現(xiàn)可能另外橫切多個對象聋溜。事務管理是一個很好的橫切關注點例子谆膳。方面用Spring的Advisor或攔截器實現(xiàn),然后可以通過@Aspect標注或在applictionContext.xml中進行配置:
—連接點(Joinpoint):程序執(zhí)行過程中的行為撮躁,如方法的調(diào)用或特定的異常被拋出漱病,在代碼上有JoinPoint類和ProceedingJoinPoint類,如下所示把曼,可以通過JoinPoint獲取很多參數(shù)缨称,JoinPoint一般用在Advice實現(xiàn)方法中作為參數(shù)傳入,ProceedingJoinPoint用于實現(xiàn)圍繞Advice的參數(shù)傳入祝迂。通過下面JoinPoint的接口可以看出通過JoinPoint可以得到代理對象和Target對象。
[java]view plaincopy
packageorg.aspectj.lang;
importorg.aspectj.lang.reflect.SourceLocation;
publicinterfaceJoinPoint?{
String?toString();//連接點所在位置的相關信息
String?toShortString();//連接點所在位置的簡短相關信息
String?toLongString();//連接點所在位置的全部相關信息
Object?getThis();//返回AOP代理對象
Object?getTarget();//返回目標對象
Object[]?getArgs();//返回被通知方法參數(shù)列表
Signature?getSignature();//返回當前連接點簽名
SourceLocation?getSourceLocation();//返回連接點方法所在類文件中的位置
String?getKind();//連接點類型
StaticPart?getStaticPart();//返回連接點靜態(tài)部分
}
publicinterfaceProceedingJoinPointextendsJoinPoint?{
publicObject?proceed()throwsThrowable;
publicObject?proceed(Object[]?args)throwsThrowable;
}
—切入點(Pointcut):指定一個Adivce將被引發(fā)的一系列連接點的集合器净。AOP框架必須允許開發(fā)者指定切入點型雳,例如,使用正則表達式。
xml中配置:
或使用Annoation:@pointcut("execution?*?transfer(..)")并用一個返回值為void纠俭,方法體為空的方法來命名切入點如:privatevoidanyOldTransfer(){}
之后就可以在Advice中引用沿量,如:@AfterReturning(pointcut="anyOldTransfer()",?returning="reVal")
[java]view plaincopy
packageorg.springframework.aop;
publicinterfacePointcut?{
ClassFilter?getClassFilter();
MethodMatcher?getMethodMatcher();
Pointcut?TRUE?=?TruePointcut.INSTANCE;
}
packageorg.springframework.aop;
publicinterfaceClassFilter?{
booleanmatches(Class?clazz);//如果clazz與我們關注的現(xiàn)象相符時返回true,負責返回false
ClassFilter?TRUE?=?TrueClassFilter.INSTANCE;//靜態(tài)參數(shù)?如果類型對于要撲捉的Pointcut來說無所謂,可將此參數(shù)傳遞給Pointcut
}
packageorg.springframework.aop;
publicinterfaceMethodMatcher?{
booleanmatches(Method?method,?Class?targetClass);
/**
*?是否對參數(shù)值敏感
*?如果為false表明匹配時不需要判斷參數(shù)值(參數(shù)值不敏感)冤荆,稱之為StaticMethodMatcher朴则,這時只有
*?matches(Method?method,?Class?targetClass);?被執(zhí)行,執(zhí)行結果可以緩存已提高效率钓简。
*?如果為true表明匹配時需要判斷參數(shù)值(參數(shù)值敏感)乌妒,稱之為DynamicMethodMatcher,這時先執(zhí)行
*?matches(Method?method,?Class?targetClass);如果返回true,然后再執(zhí)行
*?boolean?matches(Method?method,?Class?targetClass,?Object[]?args);已做進一步判斷
*
*/
booleanisRuntime();
booleanmatches(Method?method,?Class?targetClass,?Object[]?args);
MethodMatcher?TRUE?=?TrueMethodMatcher.INSTANCE;
}
關于PointCut中使用的execution的說明:
execution(modifiers-pattern??ret-type-pattern?declaring-type-pattern??name-pattern(param-pattern)throws-pattern?)
modifiers-pattern:方法的操作權限
ret-type-pattern:返回值
declaring-type-pattern:方法所在的包
name-pattern:方法名
parm-pattern:參數(shù)名
throws-pattern:異常
記憶法則就是Java定義一個方法時的樣子:public boolean produceValue(int oo) throws Exception, 只要在方法名前加上包名就可以了。
其中外邓,除ret-type-pattern和name-pattern之外撤蚊,其他都是可選的。上例中损话,execution(* com.spring.service.*.*(..))表示com.spring.service包下侦啸,返回值為任意類型;方法名任意丧枪;參數(shù)不作限制的所有方法光涂。
常見的PointCut結構圖:
—通知(Advice):在特定的連接點,AOP框架執(zhí)行的動作拧烦。各種類型的通知包括“around”忘闻、“before”和“throws”通知。通知類型將在下面討論屎篱。許多AOP框架包括Spring都是以攔截器做通知模型服赎,維護一個“圍繞”連接點的攔截器鏈。Advice中必須用到PointCut
在xml中配置交播,配置中的method為Aspect實現(xiàn)類中的方法名重虑,使用pointcut自定義或pointcut-ref進行引用已有pointcut
或使用Annoation:
@Before("execution(*?com.wicresoft.app.service.impl.*.*(..))")
@AfterReturning(returning="rvt",?pointcut="execution(*?com.wicresoft.app.service.impl.*.*(..))")
@AfterThrowing(throwing="ex",?pointcut="execution(*?com.wicresoft.app.service.impl.*.*(..))")
@After("execution(*?com.wicresoft.app.service.impl.*.*(..))")
@Around("execution(*?com.wicresoft.app.service.impl.*.*(..))")
注意
AfterReturning?增強處理處理只有在目標方法成功完成后才會被織入。
After 增強處理不管目標方法如何結束(保存成功完成和遇到異常中止兩種情況)秦士,它都會被織入缺厉。
使用方法攔截器的around通知,需實現(xiàn)接口MethodInterceptor:
public interface MethodInterceptor extends Interceptor {
Object invoke(MethodInvocation invocation) throws Throwable;
}
invoke()方法的MethodInvocation 參數(shù)暴露將被調(diào)用的方法隧土、目標連接點提针、AOP代理和傳遞給被調(diào)用方法的參數(shù)。 invoke()方法應該返回調(diào)用的結果:連接點的返回值曹傀。
一個簡單的MethodInterceptor實現(xiàn)看起來如下:
[java]view plaincopy
publicclassDebugInterceptorimplementsMethodInterceptor?{
publicObject?invoke(MethodInvocation?invocation)throwsThrowable?{
System.out.println("Before:?invocation=["+?invocation?+"]");
Object?rval?=?invocation.proceed();
System.out.println("Invocation?returned");
returnrval;
}
}
注意MethodInvocation的proceed()方法的調(diào)用辐脖。這個調(diào)用會應用到目標連接點的攔截器鏈中的每一個攔截器。大部分攔截器會調(diào)用這個方法皆愉,并返回它的返回值嗜价。但是艇抠, 一個MethodInterceptor,和任何around通知一樣久锥,可以返回不同的值或者拋出一個異常家淤,而不調(diào)用proceed方法。但是瑟由,沒有好的原因你要這么做絮重。
Before通知:需實現(xiàn)MethodBeforeAdvice接口
public interface MethodBeforeAdvice extends BeforeAdvice {
void before(Method m, Object[] args, Object target) throws Throwable;
}
Throw通知,需實現(xiàn)ThrowsAdvice接口
After Returning通知須直線AfterReturningAdvice接口
public interface AfterReturningAdvice extends Advice {
void afterReturning(Object returnValue, Method m, Object[] args, Object target)
throws Throwable;
}
—引入(Introduction):添加方法或字段到被通知的類歹苦,引入新的接口到任何被通知的對象青伤。例如,你可以使用一個引入使任何對象實現(xiàn)IsModified接口暂氯,來簡化緩存潮模。使用introduction要有三個步驟(1)聲明新接口(2)創(chuàng)建自己的IntrouductionInterceptor通過Implements IntroductionInterceptor或extends DelegatingIntroductionInterceptor 并同時implements(1)中聲明的接口 (3)將新接口和自定義的IntroductionInterceptor配置到DefaultIntroductionAdvisor中,然后將前三者配置到ProxyFactoryBean中痴施。
[java]view plaincopy
publicinterfaceIOtherBean?{
publicvoiddoOther();
}
publicclassSomeBeanIntroductionInterceptorimplementsIOtherBean,?IntroductionInterceptor?{
publicvoiddoOther()?{
System.out.println("doOther!");
}
publicObject?invoke(MethodInvocation?invocation)throwsThrowable?{
//判斷調(diào)用的方法是否為指定類中的方法
if(?implementsInterface(invocation.getMethod().getDeclaringClass())?)?{
returninvocation.getMethod().invoke(this,?invocation.getArguments());
}
returninvocation.proceed();
}
/**
*?判斷clazz是否為給定接口IOtherBean的實現(xiàn)
*/
publicbooleanimplementsInterface(Class?clazz)?{
returnclazz.isAssignableFrom(IOtherBean.class);
}
}
[html]view plaincopy
undefinedundefined
undefinedundefined
introductionAdvisor
—攔截器(Advisor )常用的有PointCutAdvisor和IntroudtionAdvisor擎厢。前者Advisor有PointCut和Advice組成,滿足Poincut(指定了哪些方法需要增強)辣吃,則執(zhí)行相應的Advice(定義了增強的功能)动遭,后者由Introduction構成。PointCutAdvisor主要是根據(jù)PointCut中制定的Target Objects的方法在調(diào)用(前神得,后厘惦,around,throws, after-return等)時引入新的Aspect中的methods, 而IntroductionAdvisor主要是引入新的接口到Targets對象中。
[java]view plaincopy
publicinterfacePointcutAdvisor?{
Pointcut?getPointcut();
Advice?getAdvice();
}
1哩簿、 PointcutAdvisor:?Advice和Pointcut宵蕉,默認實現(xiàn)為DefaultPointcutAdvisor, 還有NameMatchMethodPointcutAdvisor节榜,RegexpMethodPointcutAdvisor等羡玛。
其中NameMacthMethodPointCutAdvisor、RegexpMethodPointCutAdvisor 可以對比常用的PointCut類有NameMatchedMethodPointCut和JdkRegexMethodPointCut宗苍。
前者需要注入mappedName和advice屬性稼稿,后者需要注入pattern和advice屬性。其中mappedName和pattern是直接配置的值讳窟,而advice需要自己實現(xiàn)具體的advice让歼,可見實現(xiàn)advisor的時候,不需要實現(xiàn)PointCut丽啡,一般PointCut只需要配置就好了谋右,不需要具體實現(xiàn)類
mappedName指明了要攔截的方法名,pattern按照正則表達式的方法指明了要攔截的方法名补箍,advice定義了一個增強(需要自己實 現(xiàn)MethodBeforeAdvice倚评、 ?MethodAfterAdvice浦徊、ThrowsAdvice、MethodInterceptor接口之 一)天梧。然后在ProxyFactoryBean的攔截器(interceptorNames)中注入這個PointCutAdvisor即可,如上面這個ProxyFactoryBean是一個靜態(tài)代理霞丧,只能代理一個類給加上AOP呢岗,那么這個靜態(tài)代理需要注入有目標對象,目標對象的接口蛹尝,和interceptorsNames
2后豫、 IntroductionAdvisor :默認實現(xiàn)為DefaultIntroductionAdvisor,這個主要與Introduction有關突那,可以參考上面的例子
— 目標對象(Target Object):包含連接點的對象挫酿,也被稱作被通知或被代理對象。
—AOP代理(AOP Proxy):AOP框架創(chuàng)建的對象愕难,包含通知早龟。在Spring中,AOP代理可以是JDK動態(tài)代理或CGLIB代理猫缭。如ProxyFactory,ProxyFactoryBean, 下面會進行詳細說明
—編織(Weaving):組裝方面來創(chuàng)建一個被通知對象葱弟。這可以在編譯時完成(例如使用AspectJ編譯器),也可以在運行時完成猜丹。Spring和其他純Java AOP框架一樣芝加,在運行時完成織入。將Aspect加入到程序代碼的過程射窒,對于Spring AOP藏杖,由ProxyFactory或者ProxyFactoryBean負責織入動作。
通過ProxyFactory可以將對符合條件的類調(diào)用時添加上Aspect脉顿。
或者可使用XML聲明式 ProxyFactoryBean:需要設定 target蝌麸,interceptorNames(可以是Advice或者Advisor,注意順序, 對接口代理需設置proxyInterfaces
注意:一個ProxyFactoryBean只能指定一個代理目標弊予,不是很方便祥楣,這就產(chǎn)生了自動代理。通過自動代理汉柒,可以實現(xiàn)自動為多個目標Bean實現(xiàn)AOP代理误褪、避免客戶端直接訪問目標Bean(即getBean返回的都是Bean的代理對象)。spring的自動代理是通過BeanPostProcessor實現(xiàn)的碾褂,容器載入xml配置后會修改bean為代理Bean兽间,而id不變。
ApplicationContext可以直接檢測到定義在容器中的BeanPostProcessor正塌,BeanFactory需要手動添加嘀略。
有2種常用的BeanPostProcessor:
1.BeanNameAutoProxyCreator故名思議恤溶,BeanName需要注入的兩個屬性有BeanNames和interceptorNames
[html]view plaincopy
loginBeforeAdvisor
loginThrowsAdvisor
2.DefaultAdvisorAutoProxyCreator:DefaultAdvisorAutoProxyCreator和BeanNameAutoProxyCreator不同的是,前者只和Advisor 匹配帜羊,?該類實現(xiàn)了BeanPostProcessor接口咒程。當應用上下文讀入所有的Bean的配置信息后,該類將掃描上下文讼育,尋找所有的Advisor帐姻,他將這些Advisor應用到所有符合切入點的Bean中。所以下面的xml中沒有綁定也無需綁定DefaultAdvisorAutoProxyCreator與Advisor的關系奶段。
[html]view plaincopy
undefinedundefined
5000
.*buy.*
class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"/>
在使用Aonnotation的時候饥瓷,需要進行在ApplicationContext.xml中進行配置:
[java]view plaincopy
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/beans/spring-aop-3.0.xsd">
綜上,Spring下AOP的配置與實現(xiàn)痹籍,BeanNameAutoProxyCreator,DefaultAdvisorAutoProxyCreator已經(jīng)部分簡化了AOP配置呢铆,然而還是很繁瑣:首先要編寫xxxAdvice類(需要自己實現(xiàn)MethodBeforeAdvice、MethodAfterAdvice蹲缠、 ThrowsAdvice棺克、MethodInterceptor接口之一),然后還要在xml中配置Advisor吼砂,還要在Advisor中注入 Advice逆航,最后還要將Advisor加入ProxyFactoryBean、BeanNameAutoProxyCreator或者 DefaultAdvisorAutoProxyCreator中
渔肩。
實際上AOP不止Spring進行了實現(xiàn)因俐,還有AspectJ,后者對AOP中的概念實現(xiàn)比較徹底周偎,可以看上面抹剩,而Spring中對AOP的方方面面進行簡化,拿上面定義的regexpFilterPointcutAdvisor是一種Advisor包含了PointCut和Advice蓉坎,而此處的PointCut就是pattern屬性的值了澳眷,沒有特定的PointCut Bean定義,而advice定義了Bean蛉艾。而其他概念Aspect, JoinPoint都融匯于Advice的實現(xiàn)中即Advisor(MethodBeforeAdvice等和MethodIntector接口的實現(xiàn)類)或IntroductionInterceptor了钳踊。
較詳細的介紹AOPhttp://blog.chinaunix.net/uid-21547257-id-97998.html
利用Spring Interceptor 來緩存指定方法結果:http://www.blogjava.net/kapok/archive/2005/04/17/3388.html
Advice的類型及實現(xiàn)細節(jié):http://blog.csdn.net/saintlu/article/details/3340190
http://www.cnblogs.com/tazi/articles/2306160.html
http://blog.csdn.net/a906998248/article/details/7514969
http://sishuok.com/forum/blogPost/list/2466.html;jsessionid=AC7C2BDCBF5B19BE4327AD26D40C3CFF