在上篇文章《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的依赖,该依赖有下面的依赖,

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

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

三、原因分析

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

先看注释吧,注释中说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注解,看下测试结果,

从上面的测试结果可以看到,添加了@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注解的更多相关文章

  1. JQuery - 动态添加Html后,如何使CSS生效,JS代码可用?

    今天在开发JQuery Mobile程序时候,需要从服务器取得数据,随后显示在页面上的Listview控件中,数据完整获取到了,也动态添加到Listview控件中,但是数据对应的CSS没有任何效果了, ...

  2. 更新gitignore后如何使其生效

    Files already tracked by Git are not affected; Git - gitignore Documentation https://git-scm.com/doc ...

  3. 【Spring注解驱动开发】二狗子让我给他讲讲@EnableAspectJAutoProxy注解

    写在前面 最近,二狗子入职了新公司,新入职的那几天确实有点飘.不过慢慢的,他发现他身边的人各个身怀绝技啊,有Spring源码的贡献者,有Dubbo源码的贡献者,有MyBatis源码的贡献者,还有研究A ...

  4. Linux安装redis,启动配置不生效(指定启动加载配置文件)

    一.今天有个同学问我,为什么明明安装了redis,修改了配置,启动的时候,配置还是不生效.如下图是安装后的redis文件图. 二.想加载上图中的redis.conf,进入到src中寻找到启动文件red ...

  5. 使ViewStub 来提高UI的加载的性能

    首先看下API中的ViewStub 根据的文档的说明,ViewStub是一种默认不可见的试图,它没有大小,所以不能被改变,也不能通过某些把viewstub添加到布局当中来, 不过我们可以使用infla ...

  6. SpringBoot 中使用shiro注解使之生效

    在shiroConfig配置类中增加如下代码: /** * 开启Shiro的注解(如@RequiresRoles,@RequiresPermissions),需借助SpringAOP扫描使用Shiro ...

  7. Android WebView导入HTML使Js生效的方法

    WebSettings ws = webview.getSettings(); ws.setJavaScriptEnabled(true);//加上这句 webview.loadDataWithBas ...

  8. 不停止nginx服务,使配置文件生效

    ps -ef | grep "nginx: master process" | grep -v "grep" | awk -F ' ' '{print $2}' ...

  9. 使gitignore生效

    git rm -r --cached . // 删除本地缓存 git add . // 添加要提交的文件 初次提交直接声明gitignore并提交就可以: 非初次提交,改动的gitignore要进行上 ...

随机推荐

  1. mybatis中二级缓存整合ehcache实现分布式缓存

    mybatis自带二级缓存,但是这个缓存是单服务器工作,无法实现分布式缓存.那么什么是分布式缓存呢?假设现在有两个服务器1和2,用户访问的时候访问了1服务器,查询后的缓存就会放在1服务器上,假设现在有 ...

  2. 使用 vim 快速对当前文件夹下的文件批量重命名

    前言 我们在使用 Linux 的时候,有很多种方法可以对文件进行重命名,例如 命令行 下的 mv 命令,或者是使用像 dolphin 这样的图形文件管理器.但是有时候需要对一个文件夹下的所有文件批量重 ...

  3. Windows系统重置用户登录密码

    更新记录 2022年4月16日:本文迁移自Panda666原博客,原发布时间:2021年8月23日. 方法一.使用带有密码恢复功能的PE盘 买一张 PE光盘 或 自制PE启动盘,这里推荐微PE. 准备 ...

  4. Ubuntu远程桌面助手(URDC)

    目前自动驾驶域控制器项目中使用了英伟达的Orin芯片+Ubuntu20.04系统.域控属于典型的Headless设备,开发调试时需要连接显示器(HDMI/DP).鼠标和键盘,或者使用NoMachine ...

  5. JavaScript写倒计时

    在网页中,特别是电商网站中,倒计时的出现频率很高,接下来给大家介绍一下怎么用JavaScript写一个倒计时.代码如下: 首先我们通过Date构造函数的方法创建一个倒计时的结束的时间.并将其转换为毫秒 ...

  6. python+anaconda+pycharm的使用

    研一开学的时候开始接触了这些,但是对于其各种功能感到十分混乱,现在通过这篇博文将其功能详细的写出来. 1.python解释器 首先要了解python解释器,我们俗称的下载python也就是下载pyth ...

  7. 微服务探索之路04篇k8s增加子节点,metrics资源监控,ingress-nginx域名配置及https配置

    1 k8s增加子节点 1.1 子节点服务器安装docker,使用脚本自动安装 curl -fsSL https://get.docker.com | bash -s docker --mirror A ...

  8. MAC帧的格式&&wireshark分析MAC帧

    MAC帧的格式 MAC帧较为简单,由五个字段组成 目的地址:6字节 源地址:6字节 类型字段:2字节,用来标志上一层使用的是什么协议,以便把收到的MAC地址帧的数据交给上一层的这个协议. 数据字段:其 ...

  9. Kafka KRaft模式探索

    1.概述 Kafka是一种高吞吐量的分布式发布订阅消息系统,它可以处理消费者在网站中的所有动作流数据.其核心组件包含Producer.Broker.Consumer,以及依赖的Zookeeper集群. ...

  10. 2019 CSP-S 初赛解析

    因为我不会设置用博客园显示Markdown语法,所以在洛谷也写了一份:传送门 一起讨论的这套卷.题干 然后还有一些可以借鉴一下的解析 选择: T1. 注意运算顺序: a%3=1 --> (int ...