Spring使用AspectJ
AspectJ 是一个基于 Java 语言的 AOP 框架,它扩展了 Java 语言。Spring 2.0 以后,新增了对 AspectJ 方式的支持,新版本的 Spring 框架,建议使用 AspectJ 方式开发 AOP。
使用 AspectJ 开发 AOP 通常有两种方式:
- 基于 XML 的声明式。
- 基于 Annotation 的声明式
基于XML的声明式
基于 XML 的声明式是指通过 Spring 配置文件的方式定义切面、切入点及声明通知,而所有的切面和通知都必须定义在 aop:config 元素中。
下面通过案例演示 Spring 中如何使用基于 XML 的声明式实现 AOP 的开发。
导入 JAR 包
使用 AspectJ 除了需要导入 Spring AOP 的 JAR 包以外,还需要导入与 AspectJ 相关的 JAR 包。
- spring-aspects-x.x.xx.RELEASE.jar:Spring 为 AspectJ 提供的实现,在 Spring 的包中已经提供。
- com.springsource.org.aspectj.weaver-x.x.x.RELEASE.jar:是 AspectJ 提供的规范。
切面类
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
public class MyAspectJ {
/**
* 前置通知
*
* @param joinPoint
*/
public void before(JoinPoint joinPoint) {
System.out.println("前置通知:" + joinPoint.getTarget());
System.out.println("method:" + joinPoint.getSignature());
}
/**
* 后置通知
* @param joinPoint
*/
public void after(JoinPoint joinPoint){
System.out.println("后置通知:"+joinPoint.getSignature());
}
/**
* 环绕通知
* @param proceedingJoinPoint
* @return
* @throws Throwable
*/
public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
System.out.println("环绕开始");
Object proceed = proceedingJoinPoint.proceed();
return proceed;
}
/**
* 异常通知
* @param joinPoint
* @param e
*/
public void exception(JoinPoint joinPoint,Throwable e){
System.out.println("异常通知:"+e.getMessage());
}
/**
* 最终通知
*/
public void end(){
System.out.println("最终通知");
}
}
spring配置
<!--目标类 -->
<bean id="userServer" class="com.server.impl.UserServerImpl" />
<!--切面类 -->
<bean id="myAspectJ" class="com.aop.MyAspectJ"></bean>
<!--AOP 编程 -->
<aop:config>
<!-- 配置切入点,通知最后增强哪些方法 -->
<aop:pointcut expression="execution ( * com.server.impl.*.* (..))" id="myPointCut"/>
<aop:aspect ref="myAspectJ">
<!--前置通知,关联通知 Advice和切入点PointCut -->
<aop:before method="before" pointcut-ref="myPointCut"/>
<!--后置通知,在方法返回之后执行,就可以获得返回值returning 属性 -->
<aop:after-returning method="after" pointcut-ref="myPointCut"/>
<!--环绕通知 -->
<aop:around method="around" pointcut-ref="myPointCut"/>
<!--抛出通知:用于处理程序发生异常,可以接收当前方法产生的异常 -->
<!-- *注意:如果程序没有异常,则不会执行增强 -->
<!-- * throwing属性:用于设置通知第二个参数的名称,类型Throwable -->
<aop:after-throwing method="exception" pointcut-ref="myPointCut" throwing="e"/>
<!--最终通知:无论程序发生任何事情,都将执行 -->
<aop:after method="end" pointcut-ref="myPointCut"/>
</aop:aspect>
</aop:config>
基于注解的配置
在 Spring 中,尽管使用 XML 配置文件可以实现 AOP 开发,但是如果所有的相关的配置都集中在配置文件中,势必会导致 XML 配置文件过于臃肿,从而给维护和升级带来一定的困难。
为此,AspectJ 框架为 AOP 开发提供了另一种开发方式——基于 Annotation 的声明式。AspectJ 允许使用注解定义切面、切入点和增强处理,而 Spring 框架则可以识别并根据这些注解生成 AOP 代理。
| 名称 | 说明 |
|---|---|
| @Aspect | 用于定义一个切面。 |
| @Before | 用于定义前置通知,相当于 BeforeAdvice。 |
| @AfterReturning | 用于定义后置通知,相当于 AfterReturningAdvice。 |
| @Around | 用于定义环绕通知,相当于MethodInterceptor。 |
| @AfterThrowing | 用于定义抛出通知,相当于ThrowAdvice。 |
| @After | 用于定义最终final通知,不管是否异常,该通知都会执行。 |
| @DeclareParents | 用于定义引介通知,相当于IntroductionInterceptor(不要求掌握)。 |
切面类
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
@Aspect
@Component
public class MyAspectJ {
// 用于取代:<aop:pointcut expression="execution(*com.mengma.dao..*.*(..))" id="myPointCut"/>
// 要求:方法必须是private,没有值,名称自定义,没有参数
@Pointcut(value="execution ( * com.server.impl.*.*(..))")
private void myPointCut() {
}
/**
* 前置通知
*
* @param joinPoint
*/
@Before("myPointCut()")
public void before(JoinPoint joinPoint) {
System.out.println("前置通知:" + joinPoint.getTarget());
System.out.println("method:" + joinPoint.getSignature());
}
/**
* 后置通知
* @param joinPoint
*/
@AfterReturning(value = "myPointCut()")
public void after(JoinPoint joinPoint){
System.out.println("后置通知:"+joinPoint.getSignature());
}
/**
* 环绕通知
* @param proceedingJoinPoint
* @return
* @throws Throwable
*/
@Around(value = "myPointCut()")
public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
System.out.println("环绕开始");
Object proceed = proceedingJoinPoint.proceed();
return proceed;
}
/**
* 异常通知
* @param joinPoint
* @param e
*/
@AfterThrowing(value = "myPointCut()",throwing = "e")
public void exception(JoinPoint joinPoint,Throwable e){
System.out.println("异常通知:"+e.getMessage());
}
/**
* 最终通知
*/
@After(value = "myPointCut()")
public void end(){
System.out.println("最终通知");
}
}
spring配置
<!-- 使切面开启自动代理 -->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>

浙公网安备 33010602011771号