Spring基于注解配置AOP

  1.准备环境

pom.xml
<!--配置解析切入点表达式的jar包-->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.7</version>
</dependency>

spring配置文件
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"

http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd

http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd

<!--配置扫描路径-->
<context:component-scan base-package="com.aiitec"></context:component-scan>
<!--配置Spring开启注解AOP的支持,如果不写可以在增强类中使用@EnableAspectJAutoProxy注解来开启此功能-->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
2.增强类中配置注解
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.stereotype.Component;

import java.sql.SQLException;
@Component("transactionManager")
@Aspect//表示当前类是一个切面类
//@EnableAspectJAutoProxy配置Spring开启注解AOP的支持
public class TransactionManager {

//定义切入点表达式(引用时一定要带上'()')
@Pointcut("execution(* com.aiitec.service.impl.*.*(..))")
private void pointCut(){}

@Autowired
private ConnectionUtils connectionUtils;


//@Before("pointCut()")
public void beginTransaction(){
try {
connectionUtils.getConnection().setAutoCommit(false);
System.out.println("前置通知开始。。。");
} catch (SQLException e) {
e.printStackTrace();
}
}

// @AfterReturning("pointCut()")
public void commit(){
try {
connectionUtils.getConnection().commit();
System.out.println("后置通知开始。。。");
} catch (SQLException e) {
e.printStackTrace();
}
}
//@AfterThrowing("pointCut()")
public void rollback(){
try {
connectionUtils.getConnection().rollback();
System.out.println("异常通知开始。。。");
} catch (SQLException e) {
e.printStackTrace();
}
}
//@After("pointCut()")
public void relese(){
try {
//此时并不是断开连接,只是还回连接池中
connectionUtils.getConnection().close();
connectionUtils.removeConnection();
System.out.println("最终通知开始。。。");
} catch (SQLException e) {
e.printStackTrace();
}
}
@Around("pointCut()")
public Object arundAdvice(ProceedingJoinPoint pjp){
Object result=null;
try {
Object[] args=pjp.getArgs();
beginTransaction();//前置通知
result=pjp.proceed(args);//执行目标方法
commit();//后置通知
} catch (Throwable throwable) {
rollback();//异常通知
throwable.printStackTrace();
}finally {
relese();//最终通知
}
return result;
}
}
注意:使用注解的方式使用AOP建议使用环绕通知,因为spring有个bug,如果不使用环绕通知的方式,最终通知会先于后置通知和异常通知,从而打断业务逻辑(啥时候修复了,还请告知一下,我再修改,谢谢)。

猜你喜欢

转载自www.cnblogs.com/zou-rong/p/12002832.html