02-面向切面AOP

爱被打了一巴掌 2021-09-23 14:02 427阅读 0赞

Spring-02面向切面AOP
欢迎大家访问学习:
Spring学习:https://how2j.cn/k/spring/spring-ioc-di/87.html?p=36286
在这里插入图片描述

一、介绍

1、面向切面编程,

2、AOP让一组类共享相同的方法。

3、Spring支持AspectJ的注解式切面编程。

二、需求

演示模拟记录日志的操作系统。基于注解拦截和方法规则拦截两种方式。

三、演示

添加pom文件(基于Spirng01之后的添加,可参考前面文章Spring01)

  1. <dependency>
  2. <groupId>org.springframework</groupId>
  3. <artifactId>spring-aop</artifactId>
  4. <version>4.1.6.RELEASE</version>
  5. </dependency>
  6. <!-- aspectj支持 -->
  7. <dependency>
  8. <groupId>org.aspectj</groupId>
  9. <artifactId>aspectjrt</artifactId>
  10. <version>1.8.6</version>
  11. </dependency>
  12. <dependency>
  13. <groupId>org.aspectj</groupId>
  14. <artifactId>aspectjweaver</artifactId>
  15. <version>1.8.5</version>
  16. </dependency>

1、基于注解拦截

a.编写可以用于拦截规则的注解
  1. package com.eleven.aop;
  2. import java.lang.annotation.Documented;
  3. import java.lang.annotation.ElementType;
  4. import java.lang.annotation.Retention;
  5. import java.lang.annotation.RetentionPolicy;
  6. import java.lang.annotation.Target;
  7. /** * 拦截规则的注解 * * @author sywangu * */
  8. @Target(ElementType.METHOD) // 表示注解的作用目标,用例修饰字段、方法和类
  9. @Retention(RetentionPolicy.RUNTIME) // 表示注解的声明周期
  10. @Documented // 该注解表示是否应当被包含在JavaDoc文档中
  11. public @interface Action {
  12. String name();
  13. }
b.编写并使用注解的被拦截类
  1. package com.eleven.aop;
  2. import org.springframework.stereotype.Service;
  3. @Service
  4. public class DemoAnnotationService {
  5. @Action(name = "使用注解式拦截的add")
  6. public void add() { }
  7. }
c.编写切面
  1. package com.eleven.aop;
  2. import java.lang.reflect.Method;
  3. import org.aspectj.lang.JoinPoint;
  4. import org.aspectj.lang.annotation.After;
  5. import org.aspectj.lang.annotation.Aspect;
  6. import org.aspectj.lang.annotation.Pointcut;
  7. import org.aspectj.lang.reflect.MethodSignature;
  8. import org.springframework.stereotype.Component;
  9. @Aspect // 通过该注解声明一个切面
  10. @Component // 该注解表示让这个切面成为Spring管理的一个Bean
  11. public class LogAspect {
  12. // 为了使切点能够多次调用,可以使用PointCue定义一个拦截规则
  13. @Pointcut("@annotation(com.eleven.aop.Action)") // 通过该注解声明切点
  14. public void annotationPointCut() { }
  15. @After("annotationPointCut()") // 使用@PointCut定义的切点
  16. public void after(JoinPoint joinPoint) {
  17. MethodSignature signature = (MethodSignature) joinPoint.getSignature(); // 方法签名
  18. Method method = signature.getMethod(); // 获得签名里面的方法
  19. Action action = method.getAnnotation(Action.class); // // 通过反射可以获得注解上的属性,然后做日志记录操作
  20. System.out.println("注解式拦截:" + action.name());
  21. }
  22. }
d.配置类
  1. package com.eleven.aop;
  2. import org.springframework.context.annotation.ComponentScan;
  3. import org.springframework.context.annotation.Configuration;
  4. import org.springframework.context.annotation.EnableAspectJAutoProxy;
  5. @Configuration // 声明当前类是一个配置类
  6. @ComponentScan("com.eleven.aop") // 自动扫描包下面所有的注解
  7. @EnableAspectJAutoProxy // 该注解表示开启Spring对AspectJ的支持
  8. public class AopConfig {
  9. }
e.运行输出
  1. package com.eleven.aop;
  2. import org.springframework.context.annotation.AnnotationConfigApplicationContext;
  3. public class Main {
  4. public static void main(String[] args) {
  5. AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AopConfig.class);
  6. DemoAnnotationService demoAnnotationService = context.getBean(DemoAnnotationService.class);
  7. demoAnnotationService.add();
  8. context.close();
  9. }
  10. }

在这里插入图片描述

2、基于方法规则拦截

可直接在当前项目中编写,下面和上面的是一起的,继续写就行。

a.编写并使用方法规则的被拦截类
  1. package com.eleven.aop;
  2. import org.springframework.stereotype.Service;
  3. @Service // 声明当前类是Spring管理的一个Bean
  4. public class DemoMethodService {
  5. public void add() { }
  6. }
b.编写切面
  1. // 基于方法规则的被拦截类
  2. @Before("execution(* com.eleven.aop.DemoMethodService.*(..))")
  3. public void before(JoinPoint joinPoint) {
  4. MethodSignature signature = (MethodSignature) joinPoint.getSignature(); // 方法签名
  5. Method method = signature.getMethod();
  6. System.out.println("方法规则拦截:" + method.getName());
  7. }
c.运行输出

在Main里面。

  1. // 基于方法规则的拦截
  2. DemoMethodService demoMethodService = context.getBean(DemoMethodService.class);
  3. demoMethodService.add();

在这里插入图片描述

3.完整代码(以上两个合在一起)

a.Action(拦截规则的注解类)
  1. package com.eleven.aop;
  2. import java.lang.annotation.Documented;
  3. import java.lang.annotation.ElementType;
  4. import java.lang.annotation.Retention;
  5. import java.lang.annotation.RetentionPolicy;
  6. import java.lang.annotation.Target;
  7. /** * 拦截规则的注解 * * @author sywangu * */
  8. @Target(ElementType.METHOD) // 表示注解的作用目标,用例修饰字段、方法和类
  9. @Retention(RetentionPolicy.RUNTIME) // 表示注解的声明周期
  10. @Documented // 该注解表示是否应当被包含在JavaDoc文档中
  11. public @interface Action {
  12. String name();
  13. }
b.AopConfig(配置类)
  1. package com.eleven.aop;
  2. import org.springframework.context.annotation.ComponentScan;
  3. import org.springframework.context.annotation.Configuration;
  4. import org.springframework.context.annotation.EnableAspectJAutoProxy;
  5. @Configuration // 声明当前类是一个配置类
  6. @ComponentScan("com.eleven.aop") // 自动扫描包下面所有的注解
  7. @EnableAspectJAutoProxy // 该注解表示开启Spring对AspectJ的支持
  8. public class AopConfig {
  9. }
c.DemoAnnotationService(注解的被拦截类)
  1. package com.eleven.aop;
  2. import org.springframework.stereotype.Service;
  3. @Service
  4. public class DemoAnnotationService {
  5. @Action(name = "使用注解式拦截的add")
  6. public void add() { }
  7. }
d.DemoMethodService(方法规则的被拦截类)
  1. package com.eleven.aop;
  2. import org.springframework.stereotype.Service;
  3. @Service // 声明当前类是Spring管理的一个Bean
  4. public class DemoMethodService {
  5. public void add() { }
  6. }
e.LogAspect(切面)
  1. package com.eleven.aop;
  2. import java.lang.reflect.Method;
  3. import org.aspectj.lang.JoinPoint;
  4. import org.aspectj.lang.annotation.After;
  5. import org.aspectj.lang.annotation.Aspect;
  6. import org.aspectj.lang.annotation.Before;
  7. import org.aspectj.lang.annotation.Pointcut;
  8. import org.aspectj.lang.reflect.MethodSignature;
  9. import org.springframework.stereotype.Component;
  10. @Aspect // 通过该注解声明一个切面
  11. @Component // 该注解表示让这个切面成为Spring管理的一个Bean
  12. public class LogAspect {
  13. // 为了使切点能够多次调用,可以使用PointCue定义一个拦截规则
  14. @Pointcut("@annotation(com.eleven.aop.Action)") // 通过该注解声明切点
  15. public void annotationPointCut() {
  16. }
  17. // 基于注解的被拦截方式
  18. @After("annotationPointCut()") // 使用@PointCut定义的切点
  19. public void after(JoinPoint joinPoint) {
  20. MethodSignature signature = (MethodSignature) joinPoint.getSignature(); // 方法签名
  21. Method method = signature.getMethod(); // 获得签名里面的方法
  22. Action action = method.getAnnotation(Action.class); // // 通过反射可以获得注解上的属性,然后做日志记录操作
  23. System.out.println("注解式拦截:" + action.name());
  24. }
  25. // 基于方法规则的被拦截类
  26. @Before("execution(* com.eleven.aop.DemoMethodService.*(..))")
  27. public void before(JoinPoint joinPoint) {
  28. MethodSignature signature = (MethodSignature) joinPoint.getSignature(); // 方法签名
  29. Method method = signature.getMethod();
  30. System.out.println("方法规则拦截:" + method.getName());
  31. }
  32. }
f.Main(运行输出)
  1. package com.eleven.aop;
  2. import org.springframework.context.annotation.AnnotationConfigApplicationContext;
  3. public class Main {
  4. public static void main(String[] args) {
  5. AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AopConfig.class);
  6. // 基于注解的方式
  7. DemoAnnotationService demoAnnotationService = context.getBean(DemoAnnotationService.class);
  8. demoAnnotationService.add();
  9. // 基于方法规则的拦截
  10. DemoMethodService demoMethodService = context.getBean(DemoMethodService.class);
  11. demoMethodService.add();
  12. context.close();
  13. }
  14. }

在这里插入图片描述

发表评论

表情:
评论列表 (有 0 条评论,427人围观)

还没有评论,来说两句吧...

相关阅读

    相关 AOP面向切面编程

    [1.引言][1.]         原文地址:[点击打开链接][1.] 软件开发的目标是要对世界的部分元素或者信息流建立模型,实现软件系统的工程需要将系统分解成可以创

    相关 AOP面向切面编程

    AOP 面向切面编程 1.使用场景还原 当我们打开京东 app 进入首页,如果当前是没有网络的状态,里面的按钮点击是没有反应的。只有当我们打开网络的情况下,点击按钮

    相关 AOP面向切面思想

     本文转载于其他大神,旨在帮助还没有理解AOP的童鞋看透弄懂AOP,也欢迎高手批评指正。 先说一个Spring是什么吧,大家都是它是一个框架,但框架这个词对新手有点抽象,以致

    相关 AOP面向切面

    面向切面编程(AOP是Aspect Oriented Program的首字母缩写) ,我们知道,面向对象的特点是继承、多态和封装。而封装就要求将功能分散到不同的对象中去,这在软