Spring-2- AOP 切面编程

当我们需要对一个类中的方法进行功能的增强,又不想改变原方法的代码时

当我们需要保护一个类中的代码时

我们都可以使用代理模式,帮助这个类完成一些功能,这就是 AOP 切面编程

核心:切面 = 通知 + 切点

首先,需要引入 AOP 要用到的依赖



    4.0.0

    com.breeze
    aspect
    1.0-SNAPSHOT
    jar

    
    
        
        
            repository.spring.milestone
            Spring Milestone Repository
            https://repo.spring.io/milestone
        
    

    
    
        
        
            org.springframework
            spring-context
            6.0.0-M2
        
        
        
            org.springframework
            spring-aspects
            6.0.0-M2
        
        
        
            junit
            junit
            4.13.2
            test
        
    

    
        17
        17
    

spring.xml 配置




    

    

编写 需要被增强 的目标类方法

@Component("first")
public class First {

    //原始方法,称作目标方法
    public void origin(){
        System.out.println("我是原始方法");
    }

}

编写代理方法

@Component
@Aspect
public class Plus {

    //增强原始方法,称之为代理方法
    @Before("execution(public * all.First.*(..))")//引号中的就是切点,以切点表达式的方式找到原始方法
    public void add(){
        System.out.println("在原始方法执行前,增强了一些功能");
    }

}

@Before 就是通知,@Before 里面的参数就是切点。合起来就是切面

通知

常用通知:

@Before 目标方向执行前

 

@AfterReturning 目标方法执行后

 

@Around 前后都添加
eg:
@Around("execution(public * dao.Orcle.*(..))")
    public void around(ProceedingJoinPoint joinPoint) throws Throwable {//传参连接点,固定参数
        System.out.println("----------------------------");//前环绕
        joinPoint.proceed();//执行目标,固定方法
        System.out.println("----------------------------");//后环绕
    }

 

@AfterThrowing 发生异常时添加

 

@After  放在 finally 语句块的最终通知

 

叠加通知的作用顺序:
前环绕
前置
原本的方法被执行了
后置
最终通知
后环绕

 

异常通知在最终通知之后,在异常通知之后的后环绕不会执行

切点

常用切点表达式:

一、基于方法执行的切点表达式


匹配特定方法名称
execution(* com.example.service.UserService.findUserById(..)):匹配 com.example.service.UserService 类中名为 findUserById 的方法,无论其参数类型是什么。


匹配特定包下的所有方法
execution(* com.example.service.*.*(..)):匹配 com.example.service 包下任意类的任意方法。


匹配特定返回类型的方法
execution(* com.example.service.UserService.getUser(..)) && return-type=com.example.domain.User:匹配 com.example.service.UserService 类中名为 getUser 且返回类型为 com.example.domain.User 的方法。


二、基于类的切点表达式


匹配特定类中的所有方法
within(com.example.service.UserService):匹配 com.example.service.UserService 类中的所有方法。


匹配特定包下的所有类的所有方法
within(com.example.service.*):匹配 com.example.service 包下所有类的所有方法。


三、基于注解的切点表达式


匹配带有特定注解的方法
@annotation(com.example.annotation.Loggable):匹配带有 @com.example.annotation.Loggable 注解的方法。


四、基于目标对象的切点表达式


匹配特定类型的目标对象的所有方法调用
target(com.example.domain.User):匹配目标对象为 com.example.domain.User 类型的所有方法调用。

切面叠加

当多个切面作用于一个目标方法时
可以通过 @Order(n) 排序
n 越小优先级越高
不论优先级怎样,前置通知一定在目标发放前就被执行,后置通知同理

 

你可能感兴趣的:(java后端转后厨,spring,java,后端)