先给出代码示例
package com.example.demo.service;
import org.springframework.stereotype.Service;
@Service
public class ProxyService {
public void testA(){
System.out.println("进入A");
this.testB();
}
public void testB() {
System.out.println("进入b");
}
}
package com.example.demo.annotation;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
@Aspect
@Component
public class AspectjTest {
@Around("execution(* com.example.demo.service.ProxyService.testB())")
public void recordProxy(ProceedingJoinPoint joinPoint) throws Throwable {
long start = System.currentTimeMillis();
joinPoint.proceed();
long end = System.currentTimeMillis();
System.out.println("花费时间:"+(end-start));
}
}
package com.example.demo.api;
import com.example.demo.service.ProxyService;
import com.example.demo.service.UserService;
import org.springframework.aop.framework.AopContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
@Controller
public class ProxyApi {
// @Autowired
// ProxyService proxyService1;
@Autowired
private ApplicationContext applicationContext;
@PostMapping("/proxy")
public String test1() {
ProxyService proxyService1 = applicationContext.getBean(ProxyService.class);;
proxyService1.testA();
return "string";
}
}
运行上面的代码会发现 配置aop 拦截方法不会被执行
我们通过debug 查看这个proxyService1 和this的区别,看看他们的值是什么
发现不一样,其实这就是问题的原因。
1、当我们在aop配置拦截的时候会指定类下面的方法路径,在spring启动的时候会先去加载这个ProxyService类,生成一个bean,但是因为你用aop配置了,所以需要代理这个ProxyService类,所以最终存在spring容器中的bean对象就是被代理后的bean对象。所以,我们在用容器获取bean或者用依赖注入获取bean的地址路径显示的是被代理后的bean 。
2、this获取的当前对象方法的一个引用,所以在调用testB方法的时候用的不是被代理的对象,自热不会经过aop拦截,原理和我们使用普通动态代理一样,只能是代理对象才能走自定义的方法。
3、可以通过debug 查看当ProxyService类被代理前和后的zhi值
发现是和之前的debug截图里面的值相符合的哈。
解决方法,就是在调用testB方法的时候用spring容器里的bean对象
@Service
public class ProxyService {
@Autowired
private ProxyService proxyService;
public void testA(){
System.out.println("进入A");
proxyService.testB();
}
public void testB() {
System.out.println("进入b");
}
或者
@Service
public class ProxyService {
public void testA(){
System.out.println("进入A");
ProxyService currentProxy = (ProxyService) AopContext.currentProxy();
currentProxy.testB();
}
public void testB() {
System.out.println("进入b");
}
}
最终结果正确
到此这篇关于Spring this调用当前类方法无法拦截的文章就介绍到这了,更多相关Spring this无法拦截内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!