在数字化转型中,选择合适的跨平台开发框架不仅能提高效率,还有助于确保数据安全与合规性。
823
2022-10-19
Spring this调用当前类方法无法拦截的示例代码
先给出代码示例
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");
}
}
最终结果正确
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~