如何处理spring>=6.2.0的第三方库中错误的(@Autowired+@Bean)方法注解

问题描述 投票:0回答:1

我有一个第三方库,我无法控制它,并且其中有一些 java 代码:

@Configuration
public class DemoConfig {
    @Autowired
    @Bean
    public DemoService demoService() {
        return new DemoService(demoService2());
    }
    @Bean
    public DemoService2 demoService2() {
        return new DemoService2();
    }
}

上面的代码一直运行良好,直到 Spring 6.2.0,此时 Spring 开始拒绝 @Autowired 为无效(这很公平)并导致应用程序崩溃(详细信息请参阅 BeanMethod 类)。

我的主要问题是:我的选择是什么?

  1. 我宁愿避免手动破解库字节码(使用像 recaf 这样的字节码编辑器),因为这个第 3 方库仍在不断发展,我不想在每个新版本出现时都手动重新破解它变得可用。
  2. 我不能等到库维护者最终自己解决问题,因为这可能需要很长时间。
  3. 我尝试编写一个 java-agent 来即时修复问题(通过使用 javassist 修改内存中的字节码),但我发现 Spring 的 BeanMethod 类依赖于 asm 来验证 bean 元数据/注释,也就是说,它将直接从底层类文件读取注释元数据(即使我的类已经由于代理而加载到内存中)。因此,在尝试使用我设计的字节码(从额外的 Autowired 注释中剥离)之前,Spring 就崩溃了。

作为我的构建工具(在本例中为 gradle)的一部分,以编程方式修改第 3 方库字节码是我的最佳选择吗?

非常感谢您的专业知识和时间。

spring
1个回答
0
投票

我会尝试从组件扫描中排除此配置,并在需要时在其他配置类中手动添加其 bean。 在 Spring Boot 上,它可能如下所示:

@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(
        excludeFilters = {
                @ComponentScan.Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
                @ComponentScan.Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class),
                @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = DemoConfig.class) // exclude configuration from the scan
        })
public class MyApplication {
}

新配置:

@Configuration
public class NewDemoConfig {
    
    @Bean
    public DemoService demoService() {
        return new DemoService(demoService2());
    }
    @Bean
    public DemoService2 demoService2() {
        return new DemoService2();
    }
}

P.s.:为了在 Spring Boot 应用程序中从组件扫描中排除配置,我接受了 this 答案,可能有更优雅的方法。

© www.soinside.com 2019 - 2024. All rights reserved.