使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 = "https://www.it610.com/article/pointCut()") public void before(JoinPoint joinPoint){ System.out.println("方法执行前-20220816"); }@AfterReturning(value = "https://www.it610.com/article/pointCut()") public void after(JoinPoint joinPoint){ System.out.println("方法执行后-20220816"); } }

【使springAOP生效不一定要加@EnableAspectJAutoProxy注解】测试的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.082INFO 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
4.0.0org.example springTemplate 1.0-SNAPSHOT8 8 org.springframework.boot spring-boot-starter-web 2.3.3.RELEASE org.example customer-spring-boot-starter 1.0-SNAPSHOT org.aspectj aspectjweaver 1.8.13 org.springframework.boot spring-boot-maven-plugin repackage

在依赖中有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类是否生效;
欢迎关注我的公众号:敲代码的老贾,回复“领取”赠送《Java面试》资料,阿里,腾讯,字节,美团,饿了么等大厂

    推荐阅读