使springAOP生效不一定要加@EnableAspectJAutoProxy注解

在上篇文章《springAOP和AspectJ有关系吗?如何使用springAOP面向切面编程》中遗留了一个问题,那就是在springboot中使用springAOP需要加@EnableAspectJAutoProxy注解吗,网上很多都说需要加这个注解,但是有些情况却是不需要加,就比如我下面的例子,这是为什么,难道网上都说错了吗?

一、效果演示

以下面的例子演示,

业务类,

UserService.java

package com.my.template.service;  import com.my.template.entity.User; import org.springframework.stereotype.Service;  /**  * @date 2022/8/9 15:28  */ @Service public class UserService implements Us{     @Override     public void saveUser(User user){         System.out.println("保存user对象到数据库:"+user);     } }

切面类,

LogAspect.java

package com.my.template.aop;  import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.AfterReturning; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.aspectj.lang.annotation.Pointcut; import org.springframework.stereotype.Component;  /**  * @date 2022/8/11 14:12  */ @Component @Aspect public class LogAspect {     @Pointcut("execution(* com.my.template.service.UserService.*(..))")     public void pointCut(){      }     @Before(value = "pointCut()")     public void before(JoinPoint joinPoint){         System.out.println("方法执行前-20220816");     }      @AfterReturning(value = "pointCut()")     public void after(JoinPoint joinPoint){         System.out.println("方法执行后-20220816");     } }

测试的controller

UserController.java

package com.my.template.controller;  import com.my.template.entity.User; import com.my.template.service.Us; import com.my.template.service.UserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController;  /**  * @date 2022/8/9 15:35  */ @RestController public class UserController {     @Autowired     private Us us;     @RequestMapping("/saveUser")     public String saveUser(){          User user=new User();         user.setId("1");         user.setName("张三");         us.saveUser(user);         return "success";     } }

sprinboot的启动类,

BootServer.java

package com.my.template;  import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.EnableAspectJAutoProxy; import org.springframework.context.annotation.ImportResource;  /**  * 启动类  * @date 2022/6/3 21:32  */ @SpringBootApplication() public class BootServer {     public static void main(String[] args) {         try {             SpringApplication.run(BootServer.class);         }catch (Exception e){             e.printStackTrace();         }     } }

测试结果如下,

2022-08-16 22:30:44.082  INFO 25716 --- [nio-9099-exec-1] o.s.web.servlet.DispatcherServlet        : Completed initialization in 6 ms 方法执行前-20220816 保存user对象到数据库:User{name='张三', id='1'} 方法执行后-20220816

从上面的测试结果来看,没有加@EnableAspectJAutoProxy注解,但是AOP生效了,这是为什么?

二、为什么不加@EnableAspectJAutoProxy切面生效

关于这个问题我排查了很久,最后在依赖中找到了原因,看下pom文件

pom.xml

<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0"          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">     <modelVersion>4.0.0</modelVersion>      <groupId>org.example</groupId>     <artifactId>springTemplate</artifactId>     <version>1.0-SNAPSHOT</version>      <properties>         <maven.compiler.source>8</maven.compiler.source>         <maven.compiler.target>8</maven.compiler.target>     </properties>     <dependencies>         <!--spring-boot的web依赖-->         <dependency>             <groupId>org.springframework.boot</groupId>             <artifactId>spring-boot-starter-web</artifactId>             <version>2.3.3.RELEASE</version>         </dependency>         <!--自定义的starter-->         <dependency>             <groupId>org.example</groupId>             <artifactId>customer-spring-boot-starter</artifactId>             <version>1.0-SNAPSHOT</version>         </dependency>         <!--使用springAOP需要引入该依赖-->         <dependency>             <groupId>org.aspectj</groupId>             <artifactId>aspectjweaver</artifactId>             <version>1.8.13</version>         </dependency>     </dependencies>          <build>         <plugins>             <plugin>                 <groupId>org.springframework.boot</groupId>                 <artifactId>spring-boot-maven-plugin</artifactId>                 <executions>                     <execution>                         <goals>                             <goal>repackage</goal>                         </goals>                     </execution>                 </executions>             </plugin>         </plugins>     </build> </project>

在依赖中有spring-boot-starter-web的依赖,该依赖有下面的依赖,

使springAOP生效不一定要加@EnableAspectJAutoProxy注解

会引入spring-boot-autoconfigure的依赖,这是自动装配的依赖,也就是会读取其下的spring.factories文件,在该文件中有下面的配置,

使springAOP生效不一定要加@EnableAspectJAutoProxy注解

没错就是因为AopAutoConfiguration类的问题。下面看具体原因。

三、原因分析

要看具体原因,我们就要打开AopAutoConfiguration这个类看下,

使springAOP生效不一定要加@EnableAspectJAutoProxy注解

先看注释吧,注释中说AopAutoConfiguration等同于@EnableAspectJAutoProxy注解,也就是该类起的作用和@EnableAspectJAutoProxy是一样的,再看该类上的注解,重点看@ConditionalOProperty注解中的内容,意思是如果在配置文件中有”spring.aop.auto“的配置,如果不配置为true,否则可以配置为false,现在我的配置文件中是没有该配置项的,

server.port=9099 spring.datasource.type=com.mysql.cj.jdbc.MysqlDataSource spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver spring.datasource..driver-class-name=com.mysql.cj.jdbc.Driver spring.datasource.username=yh_dev spring.datasource..password=DvpJe2x spring.datasource.url=jdbc:mysql://10.0.0.37:3306/channel_center #????? my.customer.name=hello my.customer.code=autoconfiguration

那么我现在增加该配置,并设置为false,

server.port=9099 spring.datasource.type=com.mysql.cj.jdbc.MysqlDataSource spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver spring.datasource..driver-class-name=com.mysql.cj.jdbc.Driver spring.datasource.username=yh_dev spring.datasource..password=DvpJe2x spring.datasource.url=jdbc:mysql://10.0.0.37:3306/channel_center #????? my.customer.name=hello my.customer.code=autoconfiguration spring.aop.auto=false

重启服务之后,看测试结果,

使springAOP生效不一定要加@EnableAspectJAutoProxy注解

从测试结果可以看到springAOP没有起作用,现在在启动类上加上@EnableAspectJAutoProxy注解,看下测试结果,

使springAOP生效不一定要加@EnableAspectJAutoProxy注解

从上面的测试结果可以看到,添加了@EnableAspectJAutoProxy注解springAOP生效了。

综上,在springboot环境下,由于存在spring-boot-autoconfigure依赖,默认会注入AopAutoConfiguration配置类,该类的作用等同于@EnableAspectJAutoProxy注解,所以在这种情况下可以不加@EnableAspectJAutoProxy注解,AopAutoConfiguration可以通过spring.aop.auto属性控制;

四、总结

本文主要分析了在springboot环境下,不加@EnableAspectJAutoProxy注解springAOP仍然生效的问题。为了保险期间请一律加上@EnableAspetJAutoProxy注解。

  1. AopAutoConfiguration类等同于@EnableAspectJAutoProxy注解;
  2. spring.aop.auto=ture/false属性可以控制AopAutoConfiguration类是否生效;

使springAOP生效不一定要加@EnableAspectJAutoProxy注解

 

发表评论

评论已关闭。

相关文章

当前内容话题