文章目录
- 前言
- 一、Spring AOP基于注解的所有通知类型
- 1、前置通知
- 2、后置通知
- 3、环绕通知
- 4、最终通知
- 5、异常通知
- 二、Spring AOP基于注解之切面顺序
- 三、Spring AOP基于注解之通用切点
- 三、Spring AOP基于注解之连接点
- 四、Spring AOP基于注解之全注解开发
前言
通知类型包括:
- 前置通知:@Before目标方法执行之前的通知
- 后置通知:@AfterReturning目标方法执行之后的通知
- 环绕通知:@Around目标方法之前添加通知,同时目标方法执行之后添加通知
- 异常通知:@AfterThrowing发生异常之后执行的通知
- 最终通知:@After放在finally语句块中的通知 -
一、Spring AOP基于注解的所有通知类型
1、前置通知
//@Before(切点表达式 确定在哪里进行切入)标注的方法就是一个前置通知,在目标类的目标方法执行之前执行
@Before("execution(* com.powernode.spring.service.UserService.* (..))")
public void beforeAdvice(){
System.out.println("前置通知");
}
2、后置通知
//后置通知
@AfterReturning("execution(* com.powernode.spring.service.UserService.* (..))")
public void afterReturningAdvice(){
System.out.println("后置通知");
}
3、环绕通知
//环绕通知
@Around("execution(* com.powernode.spring.service.UserService.* (..))")
public void aroundAdvice(ProceedingJoinPoint joinPoint) throws Throwable {
//前面的代码
System.out.println("前环绕");
//执行目标
joinPoint.proceed();//执行目标
//后面的代码
System.out.println("后环绕");
}
注意:需要添加一个参数(ProceedingJoinPoint )去执行目标方法
4、最终通知
//最终通知
@After("execution(* com.powernode.spring.service.UserService.* (..))")
public void afterAdvice(){
System.out.println("最终通知");
}
5、异常通知
目标方法中设计异常:
@Service("userservice") //将这个类纳入spring容器管理
public class UserService { //目标类
public void login(){ //目标方法
System.out.println("系统正在进行身份认证....");
if(1==1){
throw new RuntimeException("运行时异常");
}
}
}
//异常通知
@AfterThrowing("execution(* com.powernode.spring.service.UserService.* (..))")
public void afterThrowing(){
System.out.println("异常通知");
}
发生异常后,后置通知以及后环绕都没有了
二、Spring AOP基于注解之切面顺序
再增加一个安全切面:
public class SecurityAspect { //安全切面
//通知+切点
@Before("execution(* com.powernode.spring.service.UserService.* (..))")
public void beforeAdvice(){
System.out.println("前置通知:安全……");
}
}
那么安全切面和日志切面的执行顺序如何来排呢?
@Order注解
@Order(1)
@Order(2)
谁的数字越小优先级越高
三、Spring AOP基于注解之通用切点
切面表达式写了多次,怎么解决?
@Pointcut("execution(* com.powernode.spring.service.UserService.* (..))")
public void 通用切点(){
//这个方法只是一个标记。方法名随意,方法体中也不需要写任何代码。
}
@Before("通用切点()")
public void beforeAdvice(){
System.out.println("前置通知");
}
跨类的话:
@Before("com.powernode.spring.service.LogAspect.通用切点()")
public void beforeAdvice(){
System.out.println("前置通知:安全……");
}
三、Spring AOP基于注解之连接点
JoinPoint在Spring容器调用这个方法的时候自动传过来
我们可以用它来获取目标方法的签名
@Before("通用切点()")
public void beforeAdvice(JoinPoint joinPoint){
System.out.println("前置通知");
System.out.println("目标方法的方法名:"+joinPoint.getSignature().getName());
}
四、Spring AOP基于注解之全注解开发
SpringConfig 代替spring.xml文件
@Configuration//代替spring.xml文件
@ComponentScan({"com.powernode.spring.service"}) //组件扫描
@EnableAspectJAutoProxy(proxyTargetClass = true) //开启aspectj的自动代理
public class SpringConfig {
}
测试程序:
@Test
public void testNoXml(){
ApplicationContext ac = new AnnotationConfigApplicationContext(SpringConfig.class);
UserService userservice = (UserService) ac.getBean("userservice");
userservice.login();
}