springboot 面向切面AOP
阿里云国内75折 回扣 微信号:monov8 |
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6 |
AOP
AOP:面向切面编程,相对于OOP面向对象编程。Spring的AOP的存在目的是为了解耦。AOP可以让一组类共享相同的行为。在OOP中只能通过继承类和实现接口,来使代码的耦合度增强,且类继承只能为单继承,阻碍更多行为添加到一组类上,AOP弥补了OOP的不足。
Spring支持AspectJ的注解式切面编程。
(1)使用@Aspect声明是一个切面。
(2)使用@After、@Before、@Around定义建言(advice),可直接将拦截规则(切点)作为参数。
(3)其中@After、@Before、@Around参数的拦截规则为切点(PointCut),为了使切点复用,可使用@PointCut专门定义拦截规则,然后在@After、@Before、@Around的参数中调用。
(4)其中符合条件的每一个被拦截处为连接点(JoinPoint)。
本例将演示基于注解拦截和基于方法规则拦截两种方式,演示一种模拟记录操作的日志系统的实现。其中注解式拦截能够很好地控制要拦截的粒度和获得更丰富的信息,Spring本身在事务处理(@Transcational)和数据缓存(@Cacheable等)上面都使用此种形式的拦截。
添加spring aop支持及AspectJ依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.8.5</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.5</version>
</dependency>
编写拦截规则的注解
Action.java
package com.shrimpking;
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;
/**
* Created by IntelliJ IDEA.
*
* @Author : Shrimpking
* @create 2023/6/7 18:20
* @Target可以使用在方法上
* @Retention 策略是运行时
* @Documented 可以生成文档标注
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Action
{
String name();
}
代码解释
这里讲下注解,注解本身是没有功能的,就和xml一样。注解和xml都是一种元数据,元数据即解释数据的数据,这就是所谓配置。
注解的功能来自用这个注解的地方。
编写使用注解的类
DemoAnnotationService.java
package com.shrimpking;
import org.springframework.stereotype.Service;
/**
* Created by IntelliJ IDEA.
*
* @Author : Shrimpking
* @create 2023/6/7 18:22
*/
@Service
public class DemoAnnotationService
{
@Action(name = "注解式拦截的add方法")
public void add()
{
//...
}
}
编写使用方法规则被拦截类
DemoMethodService.java
package com.shrimpking;
import org.springframework.stereotype.Service;
/**
* Created by IntelliJ IDEA.
*
* @Author : Shrimpking
* @create 2023/6/7 18:31
*/
@Service
public class DemoMethodService
{
public void addOther()
{
//...
}
public void update()
{
//...
}
}
编写切面
LogAspect.java
package com.shrimpking;
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;
import java.lang.reflect.Method;
/**
* Created by IntelliJ IDEA.
*
* @Author : Shrimpking
* @create 2023/6/7 18:31
* @Aspect注解声明一个切面
* @Component让此切面成为Spring容器管理的Bean
*/
@Aspect
@Component
public class LogAspect
{
/**
* @PointCut注解声明切点,规则是使用了Action注解的均切入
*/
@Pointcut("@annotation(com.shrimpking.Action)")
public void pointCut()
{
}
/**
* 使用pointCut切入点
* @param joinPoint
*/
@After("pointCut()")
public void after(JoinPoint joinPoint)
{
//获取连接点的签名,强转为方法签名
MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
//获取方法名
Method method = methodSignature.getMethod();
//获取方法上的注解
Action annotation = method.getAnnotation(Action.class);
//输出注解名称
System.out.println("注解式拦截 " + annotation.name());
}
/**
* 自定义切入规则,是DemoMethodService类下的所有方法
* @param joinPoint
*/
@Before("execution(* com.shrimpking.DemoMethodService.*(..))")
public void before(JoinPoint joinPoint)
{
//获取连接点的签名,强转为方法签名
MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
//获取方法名
Method method = methodSignature.getMethod();
//输出方法名称
System.out.println("方法式拦截 " +method.getName());
}
}
代码解释
①通过@Aspect注解声明一个切面。
②通过@Component让此切面成为Spring容器管理的Bean。
③通过@PointCut注解声明切点。
④通过@After注解声明一个建言,并使用@PointCut定义的切点。
⑤通过反射可获得注解上的属性,然后做日志记录相关的操作,下面的相同。
⑥通过@Before注解声明一个建言,此建言直接使用拦截规则作为参数。
配置类
AopConfig.java
package com.shrimpking;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
/**
* Created by IntelliJ IDEA.
*
* @Author : Shrimpking
* @create 2023/6/7 18:46
* @EnableAspectJAutoProxy注解开启Spring对AspectJ代理的支持
*/
@Configuration
@ComponentScan("com.shrimpking")
@EnableAspectJAutoProxy
public class AopConfig
{
}
代码解释
①使用@EnableAspectJAutoProxy注解开启Spring对AspectJ代理的支持。
运行
package com.shrimpking;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
@SpringBootApplication
public class Springboot41AopApplication
{
public static void main(String[] args)
{
//SpringApplication.run(Springboot41AopApplication.class, args);
AnnotationConfigApplicationContext context
= new AnnotationConfigApplicationContext(AopConfig.class);
DemoAnnotationService demoAnnotationService
= context.getBean(DemoAnnotationService.class);
demoAnnotationService.add();
DemoMethodService demoMethodService
= context.getBean(DemoMethodService.class);
demoMethodService.addOther();
demoMethodService.update();
context.close();
}
}
结果如图
阿里云国内75折 回扣 微信号:monov8 |
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6 |