Spring Aop 與 AspectJ 有什么區(qū)別和聯(lián)系?
點(diǎn)擊關(guān)注公眾號,Java干貨及時送達(dá)
作者:ready? go!
來源:blog.csdn.net/flyfeifei66/article/details/82784321
先說下區(qū)別
AspectJ
AspectJ是一個面向切面的框架,它擴(kuò)展了Java語言。AspectJ定義了AOP語法,所以它有一個專門的編譯器用來生成遵守Java字節(jié)編碼規(guī)范的Class文件。
spring aop
Spring提供了四種類型的Aop支持
基于經(jīng)典的SpringAOP
純POJO切面
@ASpectJ注解驅(qū)動的切面
注入式AspectJ切面(其實(shí)與Spring并無多大的關(guān)系,這個就是使用AspectJ這個框架實(shí)現(xiàn)Aop編程)
基于經(jīng)典的SpringAop
其使用ProxyFactoryBean創(chuàng)建。
增強(qiáng)(通知)的類型有:
前置通知: org.springframework.aop.MethodBeforeAdvice后置通知: org.springframework.aop.AfterReturningAdvice環(huán)繞通知: org.aopalliance.intercept.MethodInterceptor異常通知: org.springframework.aop.ThrowsAdvice
public?interface?IBookDao?{
????public?int?add()
????public?int?delete();
}
?
public?class?BookDaoImpl?implements?IBookDao{
????public?int?add()?{
????????System.out.println("正在添加圖書...");
????????return?0;
????}
????public?int?delete()?{
????????System.out.println("正在刪除圖書...");
????????return?0;
????}
}
?
//實(shí)現(xiàn)了MethodInterceptor的環(huán)繞增強(qiáng)類
public?class?MyAdvice?implements?MethodInterceptor{
?
????public?Object?invoke(MethodInvocation?invocation)?throws?Throwable?{
????????System.out.println("Around?Advice?before?method?invocation");
????????Object?o?=?invocation.proceed();
????????System.out.println("Around?Advice?after?method?invocation");
????????return?o;
????}
}
將每一個連接點(diǎn)都當(dāng)做切點(diǎn)(攔截每一個方法)
<bean?id="bookDao"?class="com.njust.learning.spring.service.BookDaoImpl">bean>
????<bean?id="myadvice"?class="com.njust.learning.spring.aop.MyAdvice">bean>
????<bean?id="bookDaoProxy"?class="org.springframework.aop.framework.ProxyFactoryBean">
????????<property?name="target"?ref="bookDao"/>
????????<property?name="proxyInterfaces"?value="com.njust.learning.spring.service.IBookDao"/>
????????<property?name="interceptorNames"?value="myadvice"/>
bean>
使用RegexMethodPointcutAdvisor針對某些特定的方法進(jìn)行攔截增強(qiáng)
<bean?id="bookDao"?class="com.njust.learning.spring.service.BookDaoImpl">bean>
???<bean?id="myadvice"?class="com.njust.learning.spring.aop.MyAdvice">bean>
???<bean?id="rmpAdvisor"?class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
???????
???????<property?name="patterns"?value=".*add"/>
???????<property?name="advice"?ref="myadvice"/>
???bean>
???<bean?id="bookDaoProxy"?class="org.springframework.aop.framework.ProxyFactoryBean">
???????<property?name="target"?ref="bookDao"/>
???????<property?name="proxyInterfaces"?value="com.njust.learning.spring.service.IBookDao"/>
???????<property?name="interceptorNames"?value="rmpAdvisor"/>
???bean>
注意:
像上面這樣,每定義一個dao都需要定義一個ProxyFactoryBean,顯得很麻煩,所以我們引入自動代理,也就是自動創(chuàng)建代理對象
BeanNameAutoProxyCreator
<bean?id="bookDao"?class="com.njust.learning.spring.service.BookDaoImpl">bean>
????<bean?id="myadvice"?class="com.njust.learning.spring.aop.MyAdvice">bean>
????<bean?id="rmpAdvisor"?class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
????????
????????<property?name="patterns"?value=".*add"/>
????????<property?name="advice"?ref="myadvice"/>
????bean>
?
????<bean?class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
????????<property?name="beanNames"?value="*Dao">property>
????????<property?name="interceptorNames"?value="rmpAdvisor">property>
????bean>
DefaultAdvisorAutoProxyCreator
<bean?id="bookDao"?class="com.njust.learning.spring.service.BookDaoImpl">bean>
????<bean?id="myadvice"?class="com.njust.learning.spring.aop.MyAdvice">bean>
????<bean?id="rmpAdvisor"?class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
????????
????????<property?name="patterns"?value=".*add"/>
????????<property?name="advice"?ref="myadvice"/>
????bean>
?
????
????<bean?class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"/>
純POJO切面,需要使用XML進(jìn)行配置
public?interface?IBookDao?{
????public?int?add();
????public?int?delete();
}
?
public?class?BookDaoImpl?implements?IBookDao{
????public?int?add()?{
????????int?a?=?1/0;
????????System.out.println("正在添加圖書...");
????????return?0;
????}
?
????public?int?delete()?{
????????System.out.println("正在刪除圖書...");
????????return?0;
????}
}
public?class?PojoAdvice?{
????public?void?before(){
????????System.out.println("前置通知");
????}
????public?void?after(Object?returnval){
????????System.out.println("后置通知"+",處理后的結(jié)果為:"+returnval);
????}
????public?Object?around(ProceedingJoinPoint?proceedingJoinPoint)?throws?Throwable?{
????????System.out.println("環(huán)繞前置增強(qiáng)...");
????????Object?o?=?proceedingJoinPoint.proceed();
????????System.out.println("環(huán)繞后置增強(qiáng)...");
????????return?o;
????}
????public?void?afterThrowing(Throwable?e){
????????System.out.println("異常通知:"+e.getMessage());
????}
}
<bean?id="bookDao"?class="com.njust.learning.spring.service.BookDaoImpl">bean>
????<bean?id="pojoAdvice"?class="com.njust.learning.spring.pojoaop.PojoAdvice">bean>
????<aop:config>
????????<aop:pointcut?id="p"?expression="execution?(*?*.add(..))"/>
????????<aop:aspect?ref="pojoAdvice">
????????????<aop:before?method="before"?pointcut-ref="p">aop:before>
????????????
????????????<aop:after-returning?method="after"?pointcut-ref="p"?returning="returnval"/>
????????????<aop:around?method="around"?pointcut-ref="p"/>
????????????
????????????<aop:after-throwing?method="afterThrowing"?pointcut-ref="p"?throwing="e"/>
????????aop:aspect>
????aop:config>
再說說聯(lián)系
我們借助于Spring Aop的命名空間可以將純POJO轉(zhuǎn)換為切面,實(shí)際上這些POJO只是提供了滿足切點(diǎn)的條件時所需要調(diào)用的方法,但是,這種技術(shù)需要XML進(jìn)行配置,不能支持注解。
所以spring借鑒了AspectJ的切面,以提供注解驅(qū)動的AOP,本質(zhì)上它依然是Spring基于代理的AOP,只是編程模型與AspectJ完全一致,這種風(fēng)格的好處就是不需要使用XML進(jìn)行配置。
使用@Aspect方式,你就可以在類上直接一個@Aspect就搞定,不用費(fèi)事在xml里配了。但是這需要額外的jar包(aspectjweaver.jar)。因為spring直接使用AspectJ的注解功能,注意只是使用了它 的注解功能而已,并不是核心功能 。
SpringAop的底層技術(shù)依然是Jdk動態(tài)代理和Cglib。
? ? ?
往 期 推 薦
1、我在產(chǎn)品上線前不小心刪除了7 TB的視頻 2、程序員最硬大佬,你絕對想不到!??! 3、IntelliJ IDEA快捷鍵大全 + 動圖演示 4、打不過就加入?微軟強(qiáng)推“親兒子”上位,還是中國特供版 5、活久見!NVIDIA正式開源其Linux GPU內(nèi)核模塊 點(diǎn)分享
點(diǎn)收藏
點(diǎn)點(diǎn)贊
點(diǎn)在看





