Spring AOP this 失效解决方案,使用 self() 代替
众所周知,在 Spring 的 bean 中使用 this 引用,会导致 AOP 切面失效,那我们就不用 this,使用 self() 代替
SpringUtils.java
package com.xxx.util; import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.stereotype.Component; @Component public class SpringUtils implements ApplicationContextAware { private static ApplicationContext applicationContext; @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.applicationContext = applicationContext; } public static <T> T getBean(Class<T> clazz) { return applicationContext.getBean(clazz); } }
SelfRefBean.java
package com.xxx.self; import com.xxx.util.SpringUtils; public interface SelfRefBean<T extends SelfRefBean<T>> { default T self() { SelfRefBean<?> bean = SpringUtils.getBean(this.getClass()); return (T) bean; } }
TestService.java,实现 SelfRefBean 接口即可,泛型类传递自身
package com.xxx.service; import com.xxx.self.SelfRefBean; import org.springframework.stereotype.Service; @Service public class TestService implements SelfRefBean<TestService> { public void test1() { System.out.println("test1"); self().test2(); } public void test2() { System.out.println("test2"); } }
TestController.java
package com.xxx.controller; import com.xxx.service.TestService; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import javax.annotation.Resource; @RestController public class TestController { @Resource private TestService testService; @GetMapping("/test") public void test() { testService.test1(); } }
TestAop.java
package com.xxx.aspect; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.aspectj.lang.annotation.Pointcut; import org.springframework.stereotype.Component; @Aspect @Component public class TestAop { /** * 切入点表达式 */ @Pointcut("execution(* com.xxx.service.*Service.*(..))") public void logPointCut() { } /** * 前置通知 */ @Before("logPointCut()") public void before(JoinPoint joinPoint) { System.out.println("前置通知:" + joinPoint.getTarget()); } }
执行 curl
curl http://localhost:8080/test
console 打印:
前置通知:void com.xxx.service.TestService.test1() test1 前置通知:void com.xxx.service.TestService.test2() test2
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
2019-01-16 Spring Boot程序获取tomcat启动端口
2019-01-16 SpringBoot之普通类获取Spring容器中的bean
2019-01-16 Docker批量打标签,批量推送
2019-01-16 OperationCenter Docker容器启动脚本
2018-01-16 使用java代码批量删除新浪微博