笔记:
Spring中的通知
@Before:前置通知(在目标代码执行前增强)
@AfterReturning:后置通知(在目标代码执行后增强,出现异常的时候不执行)
@AfterThrowing:异常通知(目标代码出现异常时通知)
@After:最终通知(目标方法有没有异常都会执行)
@Around:环绕通知(目标方法执行前后都会执行)
切入点表达式:
execution
execution(* demo.*.*.*(..))------demo包下的全部包的所有类的全部方法
注意:括号开头*跟包名之间必须有空格
@EnableAspectJAutoProxy:开启生成切面的代理对象
@Aspect:定义为切片类
练习1:
配置类
package demo.config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
@Configuration //将本类定义为配置类
@ComponentScan({"demo"}) //扫描注解
@EnableAspectJAutoProxy //开启动态代理
public class SpringConfig {
}
Service类
package demo.service;
import org.springframework.stereotype.Service;
@Service
public class UserService {
public void xm(){
System.out.println("方法1");
}
public void ok() {
System.out.println("方法2");
}
public void ko(){
System.out.println("方法3");
}
}
切片类
package demo.aspect;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
@Component //交给ioc容器管理
@Aspect //定义为切片类
public class LoggerAspect1 {
@Pointcut("execution(* demo.*.*.*(..))") //切入点表达式
private void pott(){}
//前置通知
@Before("pott()")
public void before(){
System.out.println("前置通知");
}
//后置通知
@AfterReturning("pott()")
public void post(){
System.out.println("后置通知");
}
//异常通知
@AfterThrowing("pott()")
public void anomaly(){
System.out.println("异常通知");
}
//最终通知
@After("pott()")
public void ultimately(){
System.out.println("最终通知");
}
}
测试类
package demo;
import demo.config.SpringConfig;
import demo.service.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class Test {
public static void main(String[] args) {
ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
UserService service = (UserService) context.getBean("userService");
service.xm();
service.ok();
service.ko();
}
}
练习2:
环绕通知
切片类
package demo.aspect;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
import java.util.Date;
@Component //交给ioc容器管理
@Aspect //定义为切片类
public class LoggerAspect{
@Pointcut("execution(* demo.*.*.*(..))")
private void pott(){}
@Around("pott()")
public Object aourd(ProceedingJoinPoint point){
Object result=null;
//执行前通知
long kTime=new Data().getTime();
//执行要增强的函数
//获得目标函数中的参数
Object[] args=point.getArgs();
try{
result=point.proceed();
} catch (Throwable e){
e.printStackTrace();
}
//执行后置通知
long jTime=new Date().getTime();
System.out.println("时间为"+(jTime-kTime)+"毫秒");
return result
}
}