AOP注解实现中,为什么@Pointcut要写在一个空方法上,而不能写在某个变量上?【懂点细节】

在AOP的xml配置实现中,我们经常使用以下语句:

<!--原始共功能需要配置成spring控制的资源-->
    <bean id="userService" class="com.ych.service.impl.UserServiceImpl"/>
<!--    抽取的功能也要配置-->
    <bean id="myAdvice" class="com.ych.aop.AOPAdvice"/>
<!--    AOP的配置-->
    <aop:config>
<!--        为切入点配置唯一的id,切入点表示从哪个方法进行抽取-->
        <aop:pointcut id="pt" expression="execution(* *..*(..))"/>
<!--        声明切面,切面表示切入点和通知Advice的关系,ref表示通知的id-->
        <aop:aspect ref="myAdvice">
<!--            before 表示是从切入点的代码之前抽取的代码;method代表方法名;point-ref是之前切入点的id-->
<!--            谁配置在前,谁先加载-->
            <aop:before method="before" pointcut-ref="pt"/>
            <aop:before method="before1" pointcut="execution(* *..*(int)) &amp;&amp; args(j)"/>
        </aop:aspect>
    </aop:config>

而当我们需要使用注解开发的时候,

    <aop:pointcut id="pt" expression="execution(* *..*(..))"/>

注意到这条语句中有对切入点唯一id的声明,以及相应的切入点表达式对被抽取方法的匹配,那么在对应的注解开发中,我们使用@Pointcut进行等效配置。
首先要明确的是,切入点表达式不能变,这是匹配到切入点的关键所在。那么设置切入点的唯一id “pt” 应该怎么做呢。
这时候我们会理所当然的想到,在spring中的@value和@autowired等属性注解。那么我们可不可以进行类似的操作?答案是不可以。
这里对切入点进行唯一的id=pt声明,并没有任何实际意义,仅仅只是一种命名,不应该占用空间,而如果使用某个变量对切入点的id进行声明,无论如何都是要占用内存空间的。而使用void类型的方法,可以在不占用任何内存空间的情况下,完成相同的任务。于是我们得到——

@Pointcut("execution(* *..*(..))")
public void pt() {
}

最后附上aop注解开发的基本框架(对比xml)
在这里插入图片描述

1. 首先需要在pom.xml文件添加以下依赖: ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency> ``` 2. 创建一个切面类,实现对程序运行时长的监控。 ```java @Aspect @Component public class TimeAspect { ThreadLocal<Long> startTime = new ThreadLocal<>(); @Pointcut("execution(* com.example.demo.service.*.*(..))") public void pointcut() {} @Before("pointcut()") public void before(JoinPoint joinPoint) { startTime.set(System.currentTimeMillis()); } @AfterReturning("pointcut()") public void afterReturning(JoinPoint joinPoint) { long time = System.currentTimeMillis() - startTime.get(); System.out.println(joinPoint.getSignature() + " executed in " + time + "ms"); } } ``` 3. 上面的切面类,定义了一个线程局部变量startTime,用于记录程序开始执行的时间。在切点方法执行前,将当前时间保存在startTime;在切点方法执行完毕后,用当前时间减去startTime,得到程序的执行时长。最后输出执行时长。 4. 在启动类上加上@EnableAspectJAutoProxy注解,开启AOP功能。 ```java @SpringBootApplication @EnableAspectJAutoProxy public class DemoApplication { public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } } ``` 5. 在需要进行运行时长监控的方法上添加@LogExecutionTime注解。 ```java @Service public class DemoService { @LogExecutionTime public void execute() throws InterruptedException { Thread.sleep(new Random().nextInt(1000)); } } ``` 6. 最后,执行程序,可以看到输出了程序的运行时长。 ```java @Service public class DemoService { @LogExecutionTime public void execute() throws InterruptedException { Thread.sleep(new Random().nextInt(1000)); } } // 输出:com.example.demo.service.DemoService.execute() executed in 340ms ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值