Spring Aop 与 AspectJ 有什么区别和联系?
Posted Java知音_
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring Aop 与 AspectJ 有什么区别和联系?相关的知识,希望对你有一定的参考价值。
点击关注公众号,实用技术文章及时了解
区别
AspectJ
AspectJ是一个面向切面的框架,它扩展了Java语言。AspectJ定义了AOP语法,所以它有一个专门的编译器用来生成遵守Java字节编码规范的Class文件。
spring aop
Spring提供了四种类型的Aop支持
基于经典的SpringAOP
纯POJO切面
@ASpectJ注解驱动的切面
注入式AspectJ切面(其实与Spring并无多大的关系,这个就是使用AspectJ这个框架实现Aop编程)
基于经典的SpringAop
其使用ProxyFactoryBean创建。
增强(通知)的类型有:
前置通知:
org.springframework.aop.MethodBeforeAdvice
后置通知:
org.springframework.aop.AfterReturningAdvice
环绕通知:
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;
//实现了MethodInterceptor的环绕增强类
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;
将每一个连接点都当做切点(拦截每一个方法)
<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
针对某些特定的方法进行拦截增强
<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">
<!--patterns,如果有多个指定的值的话,可以使用,隔开,例如value=".*add,.*delete"-->
<property name="patterns" value=".*add"/>
<property name="advice" ref="myadvice"/>
</bean>
<!--使用的时候使用这个id,而不是原始的那个id-->
<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
,显得很麻烦,所以我们引入自动代理,也就是自动创建代理对象
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">
<!--patterns,如果有多个指定的值的话,可以使用,隔开,例如value=".*add,.*delete"-->
<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">
<!--patterns,如果有多个指定的值的话,可以使用,隔开,例如value=".*add,.*delete"-->
<property name="patterns" value=".*add"/>
<property name="advice" ref="myadvice"/>
</bean>
<!--根据切面中生成信息生成代理-->
<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"/>
纯POJO切面,需要使用XML进行配置
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("后置通知"+",处理后的结果为:"+returnval);
public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable
System.out.println("环绕前置增强...");
Object o = proceedingJoinPoint.proceed();
System.out.println("环绕后置增强...");
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>
<!--通过设置returning来将返回值传递给通知-->
<aop:after-returning method="after" pointcut-ref="p" returning="returnval"/>
<aop:around method="around" pointcut-ref="p"/>
<!--通过设置returning来将异常对象传递给通知-->
<aop:after-throwing method="afterThrowing" pointcut-ref="p" throwing="e"/>
</aop:aspect>
</aop:config>
联系
我们借助于Spring Aop的命名空间可以将纯POJO转换为切面,实际上这些POJO只是提供了满足切点的条件时所需要调用的方法,但是,这种技术需要XML进行配置,不能支持注解。
所以spring借鉴了AspectJ
的切面,以提供注解驱动的AOP,本质上它依然是Spring基于代理的AOP,只是编程模型与AspectJ完全一致,这种风格的好处就是不需要使用XML进行配置。
使用@Aspect方式,你就可以在类上直接一个@Aspect
就搞定,不用费事在xml里配了。但是这需要额外的jar包(aspectjweaver.jar
)。因为spring直接使用AspectJ
的注解功能,注意只是使用了它 的注解功能而已,并不是核心功能 。
SpringAop的底层技术依然是Jdk动态代理和Cglib。
来源:blog.csdn.net/flyfeifei66/article/details/82784321
推荐
PS:因为公众号平台更改了推送规则,如果不想错过内容,记得读完点一下“在看”,加个“星标”,这样每次新文章推送才会第一时间出现在你的订阅列表里。点“在看”支持我们吧!
以上是关于Spring Aop 与 AspectJ 有什么区别和联系?的主要内容,如果未能解决你的问题,请参考以下文章