[spring-projects/spring-boot]hideProxy = true 不生效

2024-04-11 260 views
2

描述: 我使用了@EnableAspectJAutoProxy(exposeProxy = true),但是我无法通过 获取当前的AOP代理AopContex.currentProxy()

环境: Spring Boot(2.1.4.RELEASE)。

该项目只有两个类:

@SpringBootApplication
@EnableAsync
@EnableAspectJAutoProxy(exposeProxy = true)
public class DemoTest2Application {

    public static void main(String[] args) {
        SpringApplication.run(DemoTest2Application.class, args);
    }
}
@Controller
public class EmailController {

    @RequestMapping(value = "/test", method = RequestMethod.GET)
    @ResponseBody
    public Object asyncCall() throws InterruptedException {
        System.out.println("before....");
        ((EmailController) AopContext.currentProxy()).testAsyncTask();
        System.out.println("after....");
        return "OK";
    }

    @Async
    public void testAsyncTask() throws InterruptedException {
        Thread.sleep(10000);
        System.out.println("异步任务执行完成!");
    }
    }

当我请求“localhost:8080/test”时。我得到异常:

java.lang.IllegalStateException: Cannot find current proxy: Set 'exposeProxy' property on Advised to 'true' to make it available.
    at org.springframework.aop.framework.AopContext.currentProxy(AopContext.java:69) ~[spring-aop-5.1.6.RELEASE.jar:5.1.6.RELEASE]

翻遍各种文件,我也不知道自己哪里错了。

回答

9

@dongguabai 有趣,这可能是因为 Spring Boot 已经自动配置了这一点。您能否添加spring.aop.auto=false到您的应用程序并检查是否可以解决问题?

5

@snicoll 谢谢你的回复。我补充一下spring.aop.auto=false,但是问题还是没有解决。

9

((EmailController) AopContext.currentProxy()).testAsyncTask();这个方法必须要获取当前代理类啊,但是你的testAsyncTask()并没有使用到切面之类的东西,所以就获取不到当前方法的代理类了。。你需要在方法上加上@Transactional之类会切面的东西。让他代理到AOP

2

但是testAsyncTask()使用了@Async注解啊

4

没用过@async注解,你看看这个注解的实现是用的aop吗?好像不是吧,没有使用到AOP在AOP的上下文就获取不到的吧。

3

本质用的就是AOP

4

我也面临着同样的问题。

8

据我所知,没有任何东西可以将设置exposeProxy@EnableAspectJAutoProxy由于@EnableAsync.后者有自己的代理相关属性,但没有代理暴露的属性。这会导致AnnotationAwareAspectJAutoProxyCreatorexposeProxy属性设置为trueAsyncAnnotationBeanPostProcessor(为具有@Async方法的类创建代理)其exposeProxy属性的默认值为 false

3

我们应该如何更改 AsyncAnnotationBeanPostProcessor 的 ExposeProxy 属性

2

@dngzsexposeProxy添加@EnableAsync到应用程序时设置属性。

7

抱歉,您能说得更具体一些吗? ProxyAsyncConfiguration 未设置,如何覆盖它?

@Bean(name = TaskManagementConfigUtils.ASYNC_ANNOTATION_PROCESSOR_BEAN_NAME)
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public AsyncAnnotationBeanPostProcessor asyncAdvisor() {
    Assert.notNull(this.enableAsync, "@EnableAsync annotation metadata was not injected");
    AsyncAnnotationBeanPostProcessor bpp = new AsyncAnnotationBeanPostProcessor();
    Class<? extends Annotation> customAsyncAnnotation = enableAsync.getClass("annotation");
    if (customAsyncAnnotation != AnnotationUtils.getDefaultValue(EnableAsync.class, "annotation")) {
        bpp.setAsyncAnnotationType(customAsyncAnnotation);
    }
    if (this.executor != null) {
        bpp.setExecutor(this.executor);
    }
    if (this.exceptionHandler != null) {
        bpp.setExceptionHandler(this.exceptionHandler);
    }
    bpp.setProxyTargetClass(this.enableAsync.getBoolean("proxyTargetClass"));
    bpp.setOrder(this.enableAsync.<Integer>getNumber("order"));
    return bpp;
}

我对你的工作时间感到抱歉。

3

抱歉,我回答得太仓促了。正如我上面已经指出的那样@EnableAsync, .

您上面引用的代码是 Spring Framework 的一部分,而不是 Spring Boot 的一部分。如果您希望能够配置所AsyncAnnotationBeanPostProcessor创建的代理以公开其创建的代理,请打开Spring 框架增强请求。

9

非常感谢您的回答,耽误您宝贵的时间了。

8
    @Resource
    private AsyncAnnotationBeanPostProcessor asyncAdvisor;

    @PostConstruct
    private void init(){
        asyncAdvisor.setExposeProxy(true);
    }
0

这篇写得不是特别好。每个被委托的类都需要编写。如果要全局,可以实现 BeanPostProcessor 和 PriorityOrdered 将 AsyncAnnotationBeanPostProcessor 设置在 AsyncAnnotationBeanPostProcessor 之前。这是全球通用的,当然这只是一种方式

这样写不是特别好,每个被代理的类都需要这么写,如果你想全局生效,你可以实现BeanPostProcessor和PriorityOrdered去在AsyncAnnotationBeanPostProcessor之前设置处理AsyncAnnotationBeanPostProcessor,这样就全局通用了,当然这只是一种方式

9

它似乎增加了@EnableAspectJAutoProxy(exposeProxy = true)实际的 bean 工作

2

如上所述这个问题需要通过增强 Spring 框架来解决。

1

这对我有用,手动设置属性

@Component
public class AsyncBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        BeanDefinition beanDefinition = beanFactory.getBeanDefinition(org.springframework.scheduling.config.TaskManagementConfigUtils.ASYNC_ANNOTATION_PROCESSOR_BEAN_NAME);
        beanDefinition.getPropertyValues().add("exposeProxy", true);
    }
}