下面是详解SpringBoot之集成SpringAOP的完整攻略:
什么是Spring AOP
Spring AOP(Aspect Oriented Programming,面向切面编程)是Spring框架中的一个重要模块。它实现了基于代理的AOP,并且与IOC容器无缝集成,提供了便捷的配置方式。
面向切面编程就是将通用的横切关注点(如日志、安全、事务等)从业务逻辑中分离出来,形成一个独立的逻辑单元,这样可以在不干扰业务逻辑的情况下,清晰、模块化地实现这些横切关注点。
Spring AOP的核心概念
Spring AOP的核心概念包括:
-
切面(Aspect):它是横切关注点的模块化。切面定义了在哪个连接点(JoinPoint)上执行哪个通知(Advice)。
-
连接点(Join Point):程序的执行时机,如方法执行或异常抛出等。
-
切入点(Pointcut):匹配连接点的规则,用于限定通知执行的范围。
-
通知(Advice):执行在连接点上的操作。通知包括忽略返回值、在连接点前后执行的增强处理、环绕通知等。
-
引入(Introduction):在通知之外为类型添加新的方法或属性,一般不太用到。
-
织入(Weaving):把切面应用到目标对象并创建新的代理对象的过程。
Spring AOP的通知类型包括:
-
前置通知(Before Advice):在连接点之前运行的通知方法。
-
后置通知(After Advice):在连接点之后运行的通知方法。
-
返回通知(After Returning Advice):在连接点正常完成后运行的通知方法。
-
异常抛出通知(After Throwing Advice):在连接点抛出异常后运行的通知方法。
-
环绕通知(Around Advice):在连接点前后都运行的通知方法。
Spring AOP的使用
现在我们来看看在Spring Boot中如何集成Spring AOP。下面是步骤:
步骤一:引入AOP依赖
在maven配置文件中,添加以下依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
步骤二:创建切面类
在创建切面时,需要使用@Aspect注解标注,同时定义切点和通知类型。以下是一个简单的切面类的示例代码:
@Aspect
@Component
public class LogAspect {
@Pointcut("execution(public * com.example.demo.service..*.*(..))")
public void logPointcut(){}
@Before("logPointcut()")
public void beforeMethod(JoinPoint jp){
String className = jp.getSignature().getDeclaringTypeName();
String methodName = jp.getSignature().getName();
System.out.println("==> " + className + "." + methodName + "() 调用开始。");
}
@AfterReturning(returning = "result", pointcut = "logPointcut()")
public void afterReturningMethod(JoinPoint jp, Object result) {
String className = jp.getSignature().getDeclaringTypeName();
String methodName = jp.getSignature().getName();
System.out.println("==> " + className + "." + methodName + "() 调用结束。返回值:" + result);
}
@AfterThrowing(throwing = "ex", pointcut = "logPointcut()")
public void afterThrowingMethod(JoinPoint jp, Exception ex) {
String className = jp.getSignature().getDeclaringTypeName();
String methodName = jp.getSignature().getName();
System.out.println("==> " + className + "." + methodName + "() 抛出异常:" + ex.getMessage());
}
}
以上代码定义了一个切面类:LogAspect,其中定义了三个通知。
-
前置通知:在连接点之前输出方法调用开始的提示语句。
-
返回通知:在连接点正常完成后输出方法调用结束和返回值的提示语句。
-
异常抛出通知:在连接点抛出异常后输出异常提示语句。
步骤三:在应用程序中使用切面
在需要应用切面的类或方法上使用@Aspect注解即可,下面是一个简单的示例:
@Service
public class DemoService {
public String sayHello(String name) {
System.out.println("Hello, " + name);
return "result";
}
@Log
public void doSomething(String input){
System.out.println("doing something...");
}
}
在上述示例中,我们在方法doSomething上使用了@Log注解,该注解作为一个切点进行切入。
示例
下面是一个完整的示例代码:
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@Bean
public CommandLineRunner commandLineRunner(ApplicationContext ctx) {
return args -> {
DemoService demoService = ctx.getBean(DemoService.class);
String greeting = demoService.sayHello("World");
System.out.println(greeting);
demoService.doSomething("test");
};
}
}
@Service
public class DemoService {
public String sayHello(String name) {
System.out.println("Hello, " + name);
return "result";
}
@Log
public void doSomething(String input){
System.out.println("doing something...");
}
}
@Aspect
@Component
public class LogAspect {
@Pointcut("@annotation(com.example.demo.annotation.Log)")
public void logPointcut(){}
@Before("logPointcut()")
public void beforeMethod(JoinPoint jp){
String className = jp.getSignature().getDeclaringTypeName();
String methodName = jp.getSignature().getName();
System.out.println("==> " + className + "." + methodName + "() 调用开始。");
}
@AfterReturning(returning = "result", pointcut = "logPointcut()")
public void afterReturningMethod(JoinPoint jp, Object result) {
String className = jp.getSignature().getDeclaringTypeName();
String methodName = jp.getSignature().getName();
System.out.println("==> " + className + "." + methodName + "() 调用结束。返回值:" + result);
}
@AfterThrowing(throwing = "ex", pointcut = "logPointcut()")
public void afterThrowingMethod(JoinPoint jp, Exception ex) {
String className = jp.getSignature().getDeclaringTypeName();
String methodName = jp.getSignature().getName();
System.out.println("==> " + className + "." + methodName + "() 抛出异常:" + ex.getMessage());
}
}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Log {}
在上述示例代码中:
-
DemoService类中定义了一个sayHello方法和一个doSomething方法,并在doSomething方法上使用了@Log注解。
-
LogAspect切面类中定义了一个切点和三个通知。
-
@Log注解是我们自定义的注解,在需要记录日志的方法上进行标注。
当我们运行上述代码时,可以看到控制台输出了以下内容:
Hello, World
==> com.example.demo.service.DemoService.doSomething() 调用开始。
doing something...
==> com.example.demo.service.DemoService.doSomething() 调用结束。返回值:null
以上就是集成Spring AOP的完整攻略。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:详解SpringBoot之集成Spring AOP - Python技术站