02-面向切面AOP
程序员文章站
2022-07-12 14:11:17
...
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)
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>4.1.6.RELEASE</version>
</dependency>
<!-- aspectj支持 -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.8.6</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.5</version>
</dependency>
1、基于注解拦截
a.编写可以用于拦截规则的注解
package com.eleven.aop;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 拦截规则的注解
*
* @author sywangu
*
*/
@Target(ElementType.METHOD) // 表示注解的作用目标,用例修饰字段、方法和类
@Retention(RetentionPolicy.RUNTIME) // 表示注解的声明周期
@Documented // 该注解表示是否应当被包含在JavaDoc文档中
public @interface Action {
String name();
}
b.编写并使用注解的被拦截类
package com.eleven.aop;
import org.springframework.stereotype.Service;
@Service
public class DemoAnnotationService {
@Action(name = "使用注解式拦截的add")
public void add() {}
}
c.编写切面
package com.eleven.aop;
import java.lang.reflect.Method;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
@Aspect // 通过该注解声明一个切面
@Component // 该注解表示让这个切面成为Spring管理的一个Bean
public class LogAspect {
// 为了使切点能够多次调用,可以使用PointCue定义一个拦截规则
@Pointcut("@annotation(com.eleven.aop.Action)") // 通过该注解声明切点
public void annotationPointCut() {}
@After("annotationPointCut()") // 使用@PointCut定义的切点
public void after(JoinPoint joinPoint) {
MethodSignature signature = (MethodSignature) joinPoint.getSignature(); // 方法签名
Method method = signature.getMethod(); // 获得签名里面的方法
Action action = method.getAnnotation(Action.class); // // 通过反射可以获得注解上的属性,然后做日志记录操作
System.out.println("注解式拦截:" + action.name());
}
}
d.配置类
package com.eleven.aop;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
@Configuration // 声明当前类是一个配置类
@ComponentScan("com.eleven.aop") // 自动扫描包下面所有的注解
@EnableAspectJAutoProxy // 该注解表示开启Spring对AspectJ的支持
public class AopConfig {
}
e.运行输出
package com.eleven.aop;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class Main {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AopConfig.class);
DemoAnnotationService demoAnnotationService = context.getBean(DemoAnnotationService.class);
demoAnnotationService.add();
context.close();
}
}
2、基于方法规则拦截
可直接在当前项目中编写,下面和上面的是一起的,继续写就行。
a.编写并使用方法规则的被拦截类
package com.eleven.aop;
import org.springframework.stereotype.Service;
@Service // 声明当前类是Spring管理的一个Bean
public class DemoMethodService {
public void add() {}
}
b.编写切面
// 基于方法规则的被拦截类
@Before("execution(* com.eleven.aop.DemoMethodService.*(..))")
public void before(JoinPoint joinPoint) {
MethodSignature signature = (MethodSignature) joinPoint.getSignature(); // 方法签名
Method method = signature.getMethod();
System.out.println("方法规则拦截:" + method.getName());
}
c.运行输出
在Main里面。
// 基于方法规则的拦截
DemoMethodService demoMethodService = context.getBean(DemoMethodService.class);
demoMethodService.add();
3.完整代码(以上两个合在一起)
a.Action(拦截规则的注解类)
package com.eleven.aop;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 拦截规则的注解
*
* @author sywangu
*
*/
@Target(ElementType.METHOD) // 表示注解的作用目标,用例修饰字段、方法和类
@Retention(RetentionPolicy.RUNTIME) // 表示注解的声明周期
@Documented // 该注解表示是否应当被包含在JavaDoc文档中
public @interface Action {
String name();
}
b.AopConfig(配置类)
package com.eleven.aop;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
@Configuration // 声明当前类是一个配置类
@ComponentScan("com.eleven.aop") // 自动扫描包下面所有的注解
@EnableAspectJAutoProxy // 该注解表示开启Spring对AspectJ的支持
public class AopConfig {
}
c.DemoAnnotationService(注解的被拦截类)
package com.eleven.aop;
import org.springframework.stereotype.Service;
@Service
public class DemoAnnotationService {
@Action(name = "使用注解式拦截的add")
public void add() {}
}
d.DemoMethodService(方法规则的被拦截类)
package com.eleven.aop;
import org.springframework.stereotype.Service;
@Service // 声明当前类是Spring管理的一个Bean
public class DemoMethodService {
public void add() {}
}
e.LogAspect(切面)
package com.eleven.aop;
import java.lang.reflect.Method;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
@Aspect // 通过该注解声明一个切面
@Component // 该注解表示让这个切面成为Spring管理的一个Bean
public class LogAspect {
// 为了使切点能够多次调用,可以使用PointCue定义一个拦截规则
@Pointcut("@annotation(com.eleven.aop.Action)") // 通过该注解声明切点
public void annotationPointCut() {
}
// 基于注解的被拦截方式
@After("annotationPointCut()") // 使用@PointCut定义的切点
public void after(JoinPoint joinPoint) {
MethodSignature signature = (MethodSignature) joinPoint.getSignature(); // 方法签名
Method method = signature.getMethod(); // 获得签名里面的方法
Action action = method.getAnnotation(Action.class); // // 通过反射可以获得注解上的属性,然后做日志记录操作
System.out.println("注解式拦截:" + action.name());
}
// 基于方法规则的被拦截类
@Before("execution(* com.eleven.aop.DemoMethodService.*(..))")
public void before(JoinPoint joinPoint) {
MethodSignature signature = (MethodSignature) joinPoint.getSignature(); // 方法签名
Method method = signature.getMethod();
System.out.println("方法规则拦截:" + method.getName());
}
}
f.Main(运行输出)
package com.eleven.aop;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class Main {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AopConfig.class);
// 基于注解的方式
DemoAnnotationService demoAnnotationService = context.getBean(DemoAnnotationService.class);
demoAnnotationService.add();
// 基于方法规则的拦截
DemoMethodService demoMethodService = context.getBean(DemoMethodService.class);
demoMethodService.add();
context.close();
}
}
上一篇: Spring面向切面编程(AOP)
下一篇: uniapp地图-标记点- 连线