一、成果演示
以上面的例子演示,
业务类,
UserService.java
package com.my.template.service;import com.my.template.entity.User;import org.springframework.stereotype.Service;/** * @date 2022/8/9 15:28 */@Servicepublic 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@Aspectpublic 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 */@RestControllerpublic 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的依赖,该依赖有上面的依赖,
会引入spring-boot-autoconfigure的依赖,这是主动拆卸的依赖,也就是会读取其下的spring.factories文件,在该文件中有上面的配置,
没错就是因为AopAutoConfiguration类的问题。上面看具体起因。
三、起因剖析
要看具体起因,咱们就要关上AopAutoConfiguration这个类看下,
先看正文吧,正文中说 AopAutoConfiguration等同于@EnableAspectJAutoProxy注解, 也就是该类起的作用和@EnableAspectJAutoProxy是一样的,再看该类上的注解,重点看@ConditionalOProperty注解中的内容,意思是如果 在配置文件中有”spring.aop.auto“的配置,如果不配置为true,否则能够配置为false, 当初我的配置文件中是没有该配置项的,
server.port=9099spring.datasource.type=com.mysql.cj.jdbc.MysqlDataSourcespring.datasource.driver-class-name=com.mysql.cj.jdbc.Driverspring.datasource..driver-class-name=com.mysql.cj.jdbc.Driverspring.datasource.username=yh_devspring.datasource..password=DvpJe2xspring.datasource.url=jdbc:mysql://10.0.0.37:3306/channel_center#?????my.customer.name=hellomy.customer.code=autoconfiguration
那么我当初减少该配置,并设置为false,
server.port=9099spring.datasource.type=com.mysql.cj.jdbc.MysqlDataSourcespring.datasource.driver-class-name=com.mysql.cj.jdbc.Driverspring.datasource..driver-class-name=com.mysql.cj.jdbc.Driverspring.datasource.username=yh_devspring.datasource..password=DvpJe2xspring.datasource.url=jdbc:mysql://10.0.0.37:3306/channel_center#?????my.customer.name=hellomy.customer.code=autoconfigurationspring.aop.auto=false
重启服务之后,看测试后果,
从测试后果能够看到springAOP没有起作用,当初在启动类上加上@EnableAspectJAutoProxy注解,看下测试后果,
从下面的测试后果能够看到,增加了@EnableAspectJAutoProxy注解springAOP失效了。
综上,在springboot环境下,因为存在spring-boot-autoconfigure依赖,默认会注入AopAutoConfiguration配置类,该类的作用等同于@EnableAspectJAutoProxy注解,所以在这种状况下能够不加@EnableAspectJAutoProxy注解,AopAutoConfiguration能够通过spring.aop.auto属性管制;
四、总结
本文次要剖析了在springboot环境下,不加@EnableAspectJAutoProxy注解springAOP依然失效的问题。 为了保险期间请一律加上@EnableAspetJAutoProxy注解。
- AopAutoConfiguration类等同于@EnableAspectJAutoProxy注解;
- spring.aop.auto=ture/false属性能够管制AopAutoConfiguration类是否失效;
欢送关注我的公众号:敲代码的老贾,回复“支付”赠送《Java面试》材料,阿里,腾讯,字节,美团,饿了么等大厂