一抑堡、效果演示
以下面的例子演示催跪,
業(yè)務(wù)類,
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對(duì)象到數(shù)據(jù)庫(kù):"+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("方法執(zhí)行前-20220816");
}
@AfterReturning(value = "pointCut()")
public void after(JoinPoint joinPoint){
System.out.println("方法執(zhí)行后-20220816");
}
}
測(cè)試的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的啟動(dòng)類懊蒸,
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;
/**
* 啟動(dòng)類
* @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();
}
}
}
測(cè)試結(jié)果如下,
2022-08-16 22:30:44.082 INFO 25716 --- [nio-9099-exec-1] o.s.web.servlet.DispatcherServlet : Completed initialization in 6 ms
方法執(zhí)行前-20220816
保存user對(duì)象到數(shù)據(jù)庫(kù):User{name='張三', id='1'}
方法執(zhí)行后-20220816
從上面的測(cè)試結(jié)果來(lái)看悯搔,沒(méi)有加@EnableAspectJAutoProxy注解骑丸,但是AOP生效了,這是為什么妒貌?
二通危、為什么不加@EnableAspectJAutoProxy切面生效
關(guān)于這個(gè)問(wèn)題我排查了很久,最后在依賴中找到了原因灌曙,看下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的依賴菊碟,該依賴有下面的依賴,
會(huì)引入spring-boot-autoconfigure的依賴在刺,這是自動(dòng)裝配的依賴逆害,也就是會(huì)讀取其下的spring.factories文件,在該文件中有下面的配置蚣驼,
沒(méi)錯(cuò)就是因?yàn)锳opAutoConfiguration類的問(wèn)題魄幕。下面看具體原因。
三颖杏、原因分析
要看具體原因纯陨,我們就要打開AopAutoConfiguration這個(gè)類看下,
先看注釋吧,注釋中說(shuō)AopAutoConfiguration等同于@EnableAspectJAutoProxy注解翼抠,也就是該類起的作用和@EnableAspectJAutoProxy是一樣的咙轩,再看該類上的注解,重點(diǎn)看@ConditionalOProperty注解中的內(nèi)容阴颖,意思是如果在配置文件中有”spring.aop.auto“的配置臭墨,如果不配置為true,否則可以配置為false膘盖,現(xiàn)在我的配置文件中是沒(méi)有該配置項(xiàng)的,
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
那么我現(xiàn)在增加該配置尤误,并設(shè)置為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
重啟服務(wù)之后,看測(cè)試結(jié)果损晤,
從測(cè)試結(jié)果可以看到springAOP沒(méi)有起作用软棺,現(xiàn)在在啟動(dòng)類上加上@EnableAspectJAutoProxy注解,看下測(cè)試結(jié)果尤勋,
從上面的測(cè)試結(jié)果可以看到喘落,添加了@EnableAspectJAutoProxy注解springAOP生效了。
綜上最冰,在springboot環(huán)境下瘦棋,由于存在spring-boot-autoconfigure依賴,默認(rèn)會(huì)注入AopAutoConfiguration配置類暖哨,該類的作用等同于@EnableAspectJAutoProxy注解赌朋,所以在這種情況下可以不加@EnableAspectJAutoProxy注解,AopAutoConfiguration可以通過(guò)spring.aop.auto屬性控制篇裁;
四沛慢、總結(jié)
本文主要分析了在springboot環(huán)境下,不加@EnableAspectJAutoProxy注解springAOP仍然生效的問(wèn)題达布。為了保險(xiǎn)期間請(qǐng)一律加上@EnableAspetJAutoProxy注解团甲。
- AopAutoConfiguration類等同于@EnableAspectJAutoProxy注解;
- spring.aop.auto=ture/false屬性可以控制AopAutoConfiguration類是否生效黍聂;
靜態(tài)方法不能使用AOP躺苦;