Spring AOP面向切面

目录

 

一.四个点:

二.切点表达式:

三.项目使用

四.安全日志

五.多个Advice顺序:


 

 

一.四个点:

  1.PointCut 切入点,表示在哪个位置切入

  2.Advice 通知,表示在这个位置要执行的方法

  3.Joinpoint 连接点,表示该方法

 4 .Aspect 切面,(PointCut + Advice) 这俩构成切面

二.切点表达式:

  execution(  返回值类型 包名 方法名(..)异常信息  )

..表示任意参数,*表示任意,例如:

* com.example.service..Order*(..) 

表示返回值类型任意,包com.example.service下以Order开头的任意方法

// 匹配public方法
execution(public * *(..))

// 匹配名称以set开头的方法
execution(* set*(..))

// 匹配AccountService接口或类的方法
execution(* com.xyz.service.AccountService.*(..))

// 匹配service包及其子包的类或接口
execution(* com.xyz.service..*(..))

三.项目使用

 首先,要引入依赖

 <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>6.0.3</version>
        </dependency>
        <!--        aspects依赖-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aspects</artifactId>
            <version>6.0.3</version>
        </dependency>

然后在配置类上写上注解EnableAspecetJAutoProxy开启aop支持

@Configuration
@ComponentScan("com.jjh")
@EnableAspectJAutoProxy(proxyTargetClass = true)
public class SpringConfig {
}

然后写一个Service

@Service
public class OrderService {
    public void updateOrder(){
        System.out.println("订单已修改...");
    }
    public void deleteOrder(){
        System.out.println("订单已删除...");
    }
    public void insertOrder(){
        System.out.println("订单已创建...");
    }
    public void selectOrder(){
        System.out.println("已查询到订单信息...");
        if(true){
            throw new RuntimeException("出现运行时异常!!!");
        }
    }
}

接着写自定义的Advice

@Component
@Aspect
@Order(1)
public class MyAdvice {

    //在方法执行前执行
    @Before("execution(* com.jjh.service..select*(..))")
    public void beforeAdvice() {
        System.out.println("在执行前执行");
    }
    //在方法执行后执行
    @AfterReturning("execution(* com.jjh.service..select*(..))")
    public void afterReturningAdvice() {
        System.out.println("在执行后执行...");
    }
    //在方法执行前后进行环绕
    @Around("execution(* com.jjh.service..select*(..))")
    public void aroundAdvice(ProceedingJoinPoint joinPoint) throws Throwable {

        System.out.println("环绕前执行...");
        joinPoint.proceed();
        System.out.println("环绕后执行...");

    }
    //在方法最后执行
    @After("execution(* com.jjh.service..select*(..))")
    public void afterAdvice() {
        System.out.println("执行后执行...");
    }
    //出现异常时执行
    @AfterThrowing("execution(* com.jjh.service..select*(..))")
    public void afterThrowing() {
        System.out.println("异常出现后执行...");
    }
}

然后写测试程序进行测试

public class ServiceTest {
    
    @Test
    public void  TimeLogTest(){

        ApplicationContext applicationContext=new AnnotationConfigApplicationContext(SpringConfig.class);

        OrderService orderService = applicationContext.getBean("orderService", OrderService.class);

        orderService.insertOrder();
        orderService.deleteOrder();
        orderService.updateOrder();
        orderService.selectOrder();
    }
}

运行结果

订单已创建...
订单已删除...
订单已修改...
环绕前执行...
在执行前执行
已查询到订单信息...
异常出现后执行...
执行后执行...

java.lang.RuntimeException: 出现运行时异常!!!

这里因为出现了异常,所有环绕后就不会执行了!!!

四.安全日志

aop例子:安全日志

给增,删,改加入时间,以及需要知道是谁在操作,可以使用AOP

@Component
@Aspect
@Order(2)
public class SecurityLogAdvice {

    //切入点为修改方法时
    @Pointcut("execution(* com.jjh.service..update*(..))")
    public void updatePointcut(){}

    @Pointcut("execution(* com.jjh.service..delete*(..))")
    public void deletePointcut(){}

    @Pointcut("execution(* com.jjh.service..insert*(..))")
    public void insertPointcut(){}



    @Before("updatePointcut() || deletePointcut() || insertPointcut()")
    public void ShowTimelog(JoinPoint joinPoint){
        SimpleDateFormat dateFormat=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String now = dateFormat.format(new Date());
        /**
         * joinPoint.getSignature()方法获取该连接点对象的签名,可以从签名中获取它
         * 所属的类名,方法名等信息
         */
        System.out.println(now + "   "+joinPoint.getSignature().getDeclaringTypeName() + "."
                +joinPoint.getSignature().getName()+"()");
        
    }
    
}

这里pointcut是公共的切入点,可以简化写法

运行结果:

2023-02-27 22:02:21   com.jjh.service.OrderService.insertOrder()
订单已创建...
2023-02-27 22:02:21   com.jjh.service.OrderService.deleteOrder()
订单已删除...
2023-02-27 22:02:21   com.jjh.service.OrderService.updateOrder()
订单已修改...
已查询到订单信息...

这样就知道哪个方法在哪个时间做了什么事,到时在吧user信息传入即可

五.多个Advice顺序:

 若定义了多个Advice,则可以使用@Order()注解,数值小的优先级大于数值大的

 

 

 

 

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值