Spring Boot应用中AOP Advice未执行问题排查求助
解决Spring Boot AOP Advice未执行问题
问题背景
在Spring Boot应用中实现日志切面,已引入spring-aspects和spring-aop依赖,切面类已成功实例化,但调用Student类的get/set方法时,所有@Before Advice均未触发,控制台无对应日志输出。
核心原因
Spring AOP的切面拦截仅对Spring容器管理的Bean实例生效。当前代码中通过new Student()手动创建对象,该对象不属于Spring容器管理,因此切面无法拦截其方法调用。
解决方案
- 将Student类纳入Spring容器管理:给
Student类添加@Component注解 - 从Spring容器获取Student实例:在主类中通过依赖注入或ApplicationContext获取Bean,而非手动new对象
修改后的代码示例
1. 实体类Student(添加@Component)
package com.ayushsingh.aopproject.entity; import org.springframework.stereotype.Component; @Component // 新增注解,让Spring管理该类实例 public class Student { private Long id; private String name; private String address; private Integer age; private Long phone; // 省略getter/setter方法 }
2. 主类AopProjectApplication(获取Spring容器中的Student Bean)
package com.ayushsingh.aopproject; import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.EnableAspectJAutoProxy; import org.springframework.beans.factory.annotation.Autowired; import com.ayushsingh.aopproject.entity.Student; @SpringBootApplication @EnableAspectJAutoProxy public class AopProjectApplication implements CommandLineRunner { @Autowired private Student student; // 通过依赖注入获取Spring管理的Student实例 public static void main(String[] args) { SpringApplication.run(AopProjectApplication.class, args); } @Override public void run(String... args) throws Exception { student.setId(1L); student.setAddress("Address 1"); student.setAge(25); student.setName("Ayush"); student.setPhone(8145000047L); String name = student.getName(); System.out.println("Name: " + student.getName()); } }
3. 切面类LoggingAspect(无需修改)
package com.ayushsingh.aopproject.aop; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.springframework.stereotype.Component; @Aspect @Component public class LoggingAspect { LoggingAspect() { System.out.println("Logging Aspect instansiated"); } @Before("execution(public String com.ayushsingh.aopproject.entity.Student.getName())") public void LoggingAdvice1() { System.out.println("Advice 1"); } @Before("execution(public String com.ayushsingh.aopproject.entity.Student.getName())") public void LoggingAdvice2() { System.out.println("Adivce 2"); } @Before("execution(public String com.ayushsingh.aopproject.*.get*())") public void LoggingAdvice3() { System.out.println("Advice 3"); } @Before("execution(public void com.ayushsingh.aopproject.*.set*(*))") public void LoggingAdvice4() { System.out.println("Advice 4"); } @Before("execution(public * com.ayushsingh.aopproject.entity.*.get*())") public void LoggingAdvice5() { System.out.println("Advice 5"); } }
预期控制台输出
修改后运行应用,控制台会输出各个Advice的日志,示例如下:
2024-02-07T15:20:41.325+05:30 INFO 21704 --- [ restartedMain] c.a.aopproject.AopProjectApplication : No active profile set, falling back to 1 default profile: "default" 2024-02-07T15:20:41.408+05:30 INFO 21704 --- [ restartedMain] .e.DevToolsPropertyDefaultsPostProcessor : Devtools property defaults active! Set 'spring.devtools.add-properties' to 'false' to disable Logging Aspect instansiated 2024-02-07T15:20:42.527+05:30 INFO 21704 --- [ restartedMain] o.s.b.d.a.OptionalLiveReloadServer : LiveReload server is running on port 35729 2024-02-07T15:20:42.607+05:30 INFO 21704 --- [ restartedMain] c.a.aopproject.AopProjectApplication : Started AopProjectApplication in 1.732 seconds (process running for 2.185) Advice 4 Advice 4 Advice 4 Advice 4 Advice 4 Advice 1 Advice 2 Advice 3 Advice 5 Name: Ayush Advice 1 Advice 2 Advice 3 Advice 5
内容的提问来源于stack exchange,提问作者ayush
相关产品推荐
相关产品推荐

