在Spring中使用AspectJ实现AOP
2020-12-13 05:43
标签:turn 一个 div yaf 返回值 目标 信息 注解 repo 在Spring中,最常用的AOP框架是AspectJ,使用AspectJ实现AOP有2种方式: 基于XML的声明式AspectJ 基于注解的声明式AspectJ 1、在项目中添加包spring-aspects.jar(spring自带)、aspectjweaver.jar(需要自己下载添加)。 2、新建包user,包下新建类User User可实现接口。 3、新建包my_aspect,包下新建切面类MyAspect。注意是新建Class,不是新建Aspect。 根据需要,写通知。函数名是自定义的,但不能使用aspectj的关键字。 可使用形参 JoinPoint joinPoint ,通过 joinPoint.getSignature().getName() 获取增强的方法名。 4、在xml中配置 配置的是全局切入点(所有通知都可引用),可在通知中使用pointcut-ref属性引用。也可以在单个通知中使用pointcut属性配置自己的切入点。 method属性指定这个通知对应的切面类中的方法。如果方法使用了参数JoinPoint(切入点),不用额外传参,pointcut/point-ref传递的就是切入点。 切入点指的就是目标方法。 后置通知可使用returning属性指定指定一个参数,这个参数表示目标方法的返回值,会被传递给后置通知的方法。returning属性只有后置通知能使用。 环绕方法的参数 ProceedingJoinPoint proceedingJoinPoint 是JoinPoint的子类,不用额外传参。 如果同时使用前置/后置通知、环绕通知,则先执行环绕前,再执行前置(如果有),执行目标方法,执行后置(如果有),然后执行环绕后。 异常方法需要一个参数 Throwable e ,需要用throwing属性传递参数。 异常通知在目标方法发生异常、抛出异常时自动执行,throwing表示的就是目标方法抛出的异常。 目标方法发生异常时,会先执行异常方法,然后在控制台打印错误信息。 最终通知是在目标方法执行后、后置方法执行后/环绕方法执行后(如果有),才执行的。 如果之前的代码(目标方法)发生异常或者被异常中止,后置通知以及环绕通知的后半部分是不会执行的。 最终通知,就算前面代码发生异常、被异常中止,也会执行,除非退出JVM。所以常在最终方法中做一些断开连接、关闭资源的操作。 5、新建包test,包下新建测试类Test 基于代理类的AOP很繁琐,基于xml的声明式AspectJ便捷很多,但如果要配置的切面很多,xml文件会很臃肿。基于注解的声明式AspectJ可解决此问题。 基于注解的声明式AspectJ是最常用的,简便、xml文件也比较简洁。 1、在项目中添加包spring-aspects.jar(spring自带)、aspectjweaver.jar(需要自己下载添加)。 2、新建包user,包下新建类User(可实现接口) 原本要在xml中配置目标类的Bean,这里使用注解自动装配。@Repository("user")是Dao层的注解,因为添加用户一般要操作数据库,这里只是写了一个模拟。 我们显式指定Bean的id/name为user,其实@Repository默认id/name就是类名的camel写法。 3、新建包my_aspect,包下新建切面类MyAspect 原本要在xm中配置切面Bean,这里使用@Aspect(使用aspectj配置,相当于元素)、 @Component(配置为Bean,相当于 需要使用注解把要使用的方法标注为对应的通知方法,需要指定切入点。 可先配置全局切入点: 然后在注解中通过 "方法名()" 引用: 如果只配置切入点这一个参数,可简写: 也可以自行配置: 异常通知比较特殊,需要传递一个异常参数: 只有使用了注解标注的方法才会作为通知自动调用。 其实就是把xml中的配置转换为相应的注解配置。 4、在xml中配置 5、新建包test,包下新建测试类Test 在Spring中使用AspectJ实现AOP 标签:turn 一个 div yaf 返回值 目标 信息 注解 repo 原文地址:https://www.cnblogs.com/chy18883701161/p/11144903.html
基于XML的声明式AspectJ
1 public class User{
2 public void addUser(){
3 System.out.println("正在添加用户");
4 System.out.println("添加用户成功");
5 }
6 }
1 public class MyAspect {
2 //前置通知
3 public void myBefore(){
4 System.out.println("正在检查权限");
5 System.out.println("权限已够");
6 }
7
8 //后置通知
9 public void myAfterReturning(){
10 System.out.println("正在记录日志");
11 System.out.println("日志记录完毕");
12 }
13
14 //环绕通知,同时在前后增强。
15 public Object myAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
16 myBefore();
17 Object object=proceedingJoinPoint.proceed();
18 myAfterReturning();
19 return object;
20 }
21
22 //异常通知
23 public void myAfterThrowing(Throwable e){
24 System.out.println("出错了:"+e.getMessage());
25 }
26
27 //最终通知
28 public void myAfter(){
29 System.out.println("正在释放资源");
30 System.out.println("资源释放完毕");
31 }
32 }
1 public class Test {
2 public static void main(String[] args) {
3 ApplicationContext applicationContext=new ClassPathXmlApplicationContext("applicationContext.xml");
4 User user=applicationContext.getBean("user", User.class);
5 user.addUser();
6 }
7 }
基于注解的声明式AspectJ
1 @Repository("user")
2 public class User{
3 public void addUser(){
4 System.out.println("正在添加用户");
5 System.out.println("添加用户成功");
6 }
7 }
1 @Aspect
2 @Component
3 public class MyAspect {
4 //全局切入点
5 @Pointcut("execution(void user.User.*())")
6 private void myPointCut(){}
7
8 //前置通知
9 @Before("myPointCut()")
10 public void myBefore(){
11 System.out.println("正在检查权限");
12 System.out.println("权限已够");
13 }
14
15 //后置通知
16 @AfterReturning("execution(void user.User.*())")
17 public void myAfterReturning(){
18 System.out.println("正在记录日志");
19 System.out.println("日志记录完毕");
20 }
21
22 //环绕通知,同时在前后增强。
23 public Object myAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
24 myBefore();
25 Object object=proceedingJoinPoint.proceed();
26 myAfterReturning();
27 return object;
28 }
29
30 //异常通知
31 public void myAfterThrowing(Throwable e){
32 System.out.println("出错了:"+e.getMessage());
33 }
34
35 //最终通知
36 public void myAfter(){
37 System.out.println("正在释放资源");
38 System.out.println("资源释放完毕");
39
40 }
41 }
//全局切入点
@Pointcut("execution(void user.User.*())")
private void myPointCut(){}
//前置通知
@Before(value = "myPointCut()")
//前置通知
@Before("myPointCut()")
//后置通知
@AfterReturning("execution(void user.User.*())")
//异常通知
@AfterThrowing(value = "myPointCut()",throwing = "e")
1 public class Test {
2 public static void main(String[] args) {
3 ApplicationContext applicationContext=new ClassPathXmlApplicationContext("applicationContext.xml");
4 User user=applicationContext.getBean("user", User.class);
5 user.addUser();
6 }
7 }
上一篇:禁用win7自动配置ipv4地址
下一篇:js ==和===