重庆网站建设 重庆网站制作,免费企业宣传片制作软件,买商标价格一览表,怎样建个人网站学习视频#xff1a;【编程不良人】2021年SpringBoot最新最全教程 第十一章、AOP
11.1 为什么要使用AOP 问题 现有业务层开发存在问题 额外功能代码存在大量冗余每个方法都需要书写一遍额外功能代码不利于项目维护 Spring中的AOP AOP#xff1a;Aspect 切面 Oriented 面向… 学习视频【编程不良人】2021年SpringBoot最新最全教程 第十一章、AOP
11.1 为什么要使用AOP 问题 现有业务层开发存在问题 额外功能代码存在大量冗余每个方法都需要书写一遍额外功能代码不利于项目维护 Spring中的AOP AOPAspect 切面 Oriented 面向 Programmaing 面向切面编程 Aspect切面 Advice通知 Pointcut切入点 Advice 通知业务逻辑中的一些附加操作称之通知 Pointcut 切入点配置通知应用于项目中那些业务操作 Advice通知就是附加操作的代码Advice通知类型都有不同的执行策略和用途。 Before在目标方法执行之前执行的通知。它不能阻止方法的执行但可以在方法执行前添加额外的功能。AfterReturning在目标方法正常返回后执行的通知。例如如果一个方法正常返回而没有抛出异常就会执行这个通知。AfterThrowing在目标方法抛出异常后执行的通知。如果一个方法抛出异常就会执行这个通知。After在目标方法执行之后执行的通知。无论目标方法如何退出正常返回或抛出异常都会执行的通知。Around包围目标方法的通知可以在目标方法执行前后添加额外的功能并决定是否继续执行目标方法。 Pointcut 是切入点决定了Advice加在哪个具体方法代码上具体使用方式 1.切入点直接写在附加操作里面
Around(valueexecution(* login(..)))
2.通过Pointcut注解 声明切入点实现复用
Pointcut(execution(* login(..))) // 复用切入点解耦合public void myPointcut(){}Around(myPointcut())
After(myPointcut())
Before(myPointcut())11.2 AOP的实现 引入依赖 dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-aop/artifactId
/dependency目前UserServiceImp存在的问题 以log日志这种额外功能为例这样的重复操作存在冗余代码和耦合 Service
public class UserServiceImpl implements UserService {Overridepublic void save(String name) {System.out.println(log);System.out.println(UserServiceImpl.save);}Overridepublic void delete(Integer id) {System.out.println(log);System.out.println(UserServiceImpl.delete);}Overridepublic void update(String name) {System.out.println(log);System.out.println(UserServiceImpl.update);}Overridepublic String find(String name) {System.out.println(log);System.out.println(UserServiceImpl.find);return name;}
}我们通过一个切面配置类来解耦合 /*** 自定义切面配置类*/
Configuration // 指定当前类为配置类
Aspect // 代表这个类是一个切面配置类
public class MyAspectConfig {Before(execution(* com.example.service.*.*(..))) // Before代表在业务逻辑执行前运行 value代表切入点public void before() {System.out.println( 前置附加操作log );}
}通过切入点完成整个业务的额外功能覆盖运行效果
11.3 JoinPoint 参数详解
**JoinPoint参数可以在通知体内声明用于获取有关方法执行的信息。JoinPoint参数提供了许多有用的方法例如getSignature()可以获取方法的签名getArgs()可以获取方法的参数列表getTarget()可以获取目标对象等。通过JoinPoint**参数我们可以在通知中访问和操作方法执行时的上下文信息。
**JoinPoint**参数通常用于以下几种情况
记录日志获取方法的签名和参数列表从而记录方法的执行情况包括方法名、参数值等。异常处理获取方法执行时抛出的异常信息从而进行相应的异常处理。性能监控获取方法的执行时间、参数值等信息用于性能监控和优化。
获取执行方法的信息
Before(execution(* com.example.service.*.*(..))) //
public void before(JoinPoint joinPoint) {String methodName joinPoint.getSignature().getName();String className joinPoint.getTarget().getClass().getName();Object[] args joinPoint.getArgs();System.out.println(Before 执行方法 methodName 在类 className);System.out.println(方法参数 Arrays.toString(args));
}11.4 Around 环绕附加操作
使用Around注解的方法参数必须声明ProceedingJoinPoint这个参数可以控制目标方法的执行
Around(execution(* com.example.service.*.*(..)))
public Object around(ProceedingJoinPoint pjp) throws Throwable {System.out.println(进入环绕的前置操作);System.out.println(当前执行类 pjp.getSignature().getName());System.out.println(方法名 pjp.getTarget().getClass().getSimpleName());//放行目标方法执行Object proceed pjp.proceed(); // 目标方法继续执行System.out.println( 进入环绕的后置操作 );return proceed;
}运行效果
11.5 自定义注解方式的切入点表达式annotation
通过自定义注解annotation实现切面的好处在于可以使切面的定义更加灵活和可重用。使用自定义注解可以将切面的逻辑和配置信息封装在注解中使得切面的使用和配置变得更加简单和直观。 MyAdvice 自定义注解 Retention(RetentionPolicy.RUNTIME) // 指定运行时保留
Target(ElementType.METHOD) //指定修饰 方法
public interface MyAdvice {
}放在通知里的annotation属性使用代表只有被MyAdvice修饰的方法才会被加入额外功能 **Around(annotation(com.example.config.MyAdvice))**
public Object around(ProceedingJoinPoint pjp) throws Throwable {}通过将注解加在业务逻辑上实现给目标方法加上额外功能的目的 UserServiceImpl
Override
MyAdvice
public String find(String name) {
// System.out.println(log);System.out.println(UserServiceImpl.find);return name;
}