Spring AOP

Spring AOP是什么?

AOP(面向切面编程):将那些与业务无关,却为业务模块所共同调用的逻辑(例如事务处理、日志管理、权限控制等)封装抽取成一个可重用的模块,这个模块被命名为“切面”(Aspect),便于减少系统的重复代码,降低模块间的耦合度,并有利于未来的可拓展性和可维护性;

在Spring AOP中,切面由切点(Pointcut)和通知(Advice)组成。切点是一个表达式,用于匹配哪些方法需要被横切,通知是在切点位置执行的代码,表示横切逻辑。

切点表达式配置语法:
execution(修饰符 返回值 包名称.类名称.方法名称(参数列表))
execution(public void com.apesource.service.ServiceImp.findAll())

  1. 修饰符可以省略代表任意        execution(返回值 包名称.类名称.方法名称(参数列表))
  2. 返回值可以使用“*”代表任意        execution(* 包名称.类名称.方法名称(参数列表))
  3. 包名可以使用“*”代表任意名称        execution(* *.*.*.类名称.方法名称(参数列表))
  4. 包名可以使用“..”代表任意个数         execution(* *...类名称.方法名称(参数列表))
  5. 类名与方法名可以使用“*”代表任意        execution(* *...*.*(参数列表))
  6. 参数列表可以使用".."代表任意个数任意类型        execution(* *...*.*(..))

    如果有参数        int======>int        String===>java.lang.String

Spring AOP提供了几种常见的通知类型,包括:

  • 前置通知(Before):在方法执行前执行的逻辑
  • 后置通知(After):在方法执行后执行的逻辑
  • 返回通知(After-returning):在方法成功返回后执行的逻辑
  • 异常通知(After-throwing):在方法抛出异常后执行的逻辑
  • 环绕通知(Around):在方法执行前后都可以执行的逻辑,可以控制目标方法的执行流程

Spring AOP 基于动态代理实现:

  • 如果被代理的对象,已经实现某个接口,则 Spring AOP 会使用 JDK Proxy(反射),基于接口的方式,创建代理对象;
  • 如果被代理的对象,没有实现某个接口, Spring AOP 会使用 Cglib,基于继承的方式,生成一个被代理对象的子类来作为代理;

Spring AOP可以通过注解或XML配置的方式来定义切点和通知,并且可以与Spring的IOC容器无缝集成,使得切面和目标对象的创建和管理变得更加简单。 

1⃣️XML

1.添加依赖:

        
            org.springframework
            spring-context
            5.3.28
        

        
            org.aspectj
            aspectjweaver
            1.9.7
        

2.创建切面类:

public class LoggerUtil {
    //前置通知
    public void beforeMethod(){
        System.out.println("前置通知=====>"+new Date());
    }
    //返回通知
    public void afterRrturnMethod(){
        System.out.println("返回通知=====>"+new Date());
    }
    //异常通知
    public void throwMethod(){
        System.out.println("异常通知=====>"+new Date());
    }
    //后置通知
    public void afterMethod(){
        System.out.println("后置通知=====>"+new Date());
    }

    //环绕通知
    public Object arroundMethod(ProceedingJoinPoint pjp){
        Object obj = null;
        try {
            //环绕通知---前置通知
            System.out.println("环绕通知---前置通知");
            Object[] objs = pjp.getArgs();
            obj = pjp.proceed(objs);
            //环绕通知---返回通知
            System.out.println("环绕通知---返回通知");
        } catch (Throwable throwable) {
            //环绕通知---异常通知
            System.out.println("环绕通知---异常通知");
            throwable.printStackTrace();
        } finally {
            //环绕通知---后置通知
            System.out.println("环绕通知---后置通知");
        }
        return obj;
    }
}

3.配置XML:

    
    
        
        
                        
            
            
            
            
            
            
            
        
    

2⃣️注解

1.添加依赖:

        
            org.springframework
            spring-context
            5.3.28
        

        
            org.aspectj
            aspectjweaver
            1.9.7
        

2.创建切面类:

@Component
@Aspect//切面
//@EnableAspectJAutoProxy 
public class LoggerUtil {
    //切点
    @Pointcut(value="execution(* com.apesource.service.*.*(..))")
    public void dian(){}
    
    //前置通知
//    @Before("dian()")
    public void beforeMethod(){
        System.out.println("前置通知=====>"+new Date());
    }
    //返回通知
//    @AfterReturning("dian()")
    public void afterRrturnMethod(){
        System.out.println("返回通知=====>"+new Date());
    }
    //异常通知
//    @AfterThrowing("dian()")
    public void throwMethod(){
        System.out.println("异常通知=====>"+new Date());
    }
    //后置通知
//    @After("dian()")
    public void afterMethod(){
        System.out.println("后置通知=====>"+new Date());
    }

    //环绕通知
    @Around("dian()")
    public Object arroundMethod(ProceedingJoinPoint point){
        Object returnObj = null;//执行切点方法
        try {
            System.out.println("环绕通知====>前置通知");
            //切点
            Object[] obj = point.getArgs();//切点方法的参数
            returnObj = point.proceed(obj);
            System.out.println("环绕通知====>返回通知");
        } catch (Throwable throwable) {
            throwable.printStackTrace();
            System.out.println("环绕通知====>异常通知");
        } finally {
            System.out.println("环绕通知====>后置通知");
        }
        return returnObj;//切点方法的返回值
    }
}

3.配置XML:(也大可不配直接注解)

  
    

你可能感兴趣的:(Spring框架,spring,java,后端)