Java 覆盖Spring定义:springbean注释@Primary
在我看来,覆盖bean定义比我想象的要难。 首先,我想保持开/关原则 我正在使用Springfox,它将基于Spring映射提供一个招摇过市的json。Springfox由我必须提供的配置类加载:Java 覆盖Spring定义:springbean注释@Primary,java,spring,spring-mvc,Java,Spring,Spring Mvc,在我看来,覆盖bean定义比我想象的要难。 首先,我想保持开/关原则 我正在使用Springfox,它将基于Spring映射提供一个招摇过市的json。Springfox由我必须提供的配置类加载: @EnableWebMvc @Configuration @Import({Swagger2DocumentationConfiguration.class}) @ComponentScan(basePackages = {"special.package.swagger"}) public clas
@EnableWebMvc
@Configuration
@Import({Swagger2DocumentationConfiguration.class})
@ComponentScan(basePackages = {"special.package.swagger"})
public class ApplicationSwaggerConfig {
@Bean
public Docket swaggerApi() {
return new Docket(DocumentationType.SWAGGER_2)
.groupName("rest-api")
.select()
.build()
.pathMapping("/rest-api");
}
...
当然,我不想更改Swagger2DocumentationConfiguration类(遵循打开/关闭原则),而是将ServiceModel的行为更改为Wagger2Mapper
为此,我在“special.package.swagger”文件夹中创建了一个MyServiceModelToSwagger2Mapper类,例如:
@Component
@Primary
public class MyServiceModelToSwagger2Mapper extends ServiceModelToSwagger2MapperImpl {
@Override
public Swagger mapDocumentation(Documentation from) {
System.out.println("\n\n\n\n\n\n\n\n\n\n\n\n\n******************** Override works!!!\n");
return super.mapDocumentation(from);
}
}
弹簧加载组件,解决了模糊问题,但在覆盖处不起作用。有人知道为什么吗
编辑:@smarquis的评论帮助很大。弹簧工作正常
我无意中添加了多个版本的springfox库。应用程序服务器加载了两个库,但都丢失了。一旦类路径问题得到解决,重写就可以完美地工作。这是由于spring与java配置的构建方式——它在内部使用代理和其他东西变得非常复杂 我不记得确切的原因,但如果您这样做,您的覆盖会起作用:
@EnableWebMvc
@Configuration
@Import({Swagger2DocumentationConfiguration.class})
//@ComponentScan(basePackages = {"springfoxswagger.specialpackageswagger"})
public class ApplicationSwaggerConfig {
@Bean
public Docket swaggerApi() {
return new Docket(DocumentationType.SWAGGER_2)
.groupName("rest-api")
.select()
.build()
.pathMapping("/rest-api");
}
@Bean
public springfox.documentation.swagger2.mappers.ServiceModelToSwagger2Mapper mapper() {
return new ServiceModelToSwagger2MapperImpl() {
public Swagger mapDocumentation(Documentation from) {
System.out.println("\n\n\n\n\n\n\n\n\n\n\n\n\n******************** Override works!!!\n");
return super.mapDocumentation(from);
}
};
}
}
可以说,它也更简单
编辑
这似乎对OP不起作用,所以我进一步调查了一下
- 如果只添加ServiceModelToSwigger2Mapperimpl的第二个实现,而不添加@Primary,则会出现异常“…预期为单个匹配bean,但找到2”
- 如果将其与注释一起添加,则会得到OP所说的内容(spring启动,但覆盖不起作用)
- 如果您在我的解决方案中再次添加@Bean,这将使ServiceModelToSwigger2Mapprimpl的实现出现三个,并且没有任何@Primary,spring启动,覆盖工作正常
- 请注意,您不需要在bean上使用@Primary注释,这已经足够精巧了
********************覆盖工程2016-01-26 08:50:26.594 INFO 58548 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : FrameworkServlet 'dispatcherServlet': initialization completed in 22 ms
- 添加@BeanNameAware或@AnnotationConfigDriven这样的“简单”解决方案是行不通的。IMO OP遇到了Spring Java配置错误或限制;我看不出他的解决办法不起作用的任何理由
@AnnotationDrivenConfig
放在类中,然后尝试以下操作:
@EnableWebMvc
@Configuration
@AnnotationDrivenConfig
@Import({Swagger2DocumentationConfiguration.class})
public class ApplicationSwaggerConfig {
@Bean
public Docket swaggerApi() {
return new Docket(DocumentationType.SWAGGER_2)
.groupName("rest-api")
.select()
.build()
.pathMapping("/rest-api");
}
@Bean
@Primary
public MyServiceModelToSwagger2Mapper mapper() {
return new MyServiceModelToSwagger2Mapper();
}
}
MyServiceModelToSwaggger2Mapper类:
public class MyServiceModelToSwagger2Mapper extends ServiceModelToSwagger2MapperImpl {
@Override
public Swagger mapDocumentation(Documentation from) {
System.out.println("\n\n\n\n\n\n\n\n\n\n\n\n\n******************** Override works!!!\n");
return super.mapDocumentation(from);
}
}
您确定
@Primary
正在工作,并且它正在加载自定义定义的bean吗?如果您在MyServiceModelTowagger2Mapper
中实现BeanNameware
,那么继承方法setBeanName(Str)
的参数的第一个参数的值是多少?@user2004685,主批注工作正常。没有这一点,我得到了一个例外。使用它,我可以看到bean正在被初始化。@rdllopes如果实现BeanNameware
?继承方法setBeanName(str)
?@PeterRader的参数的第一个参数的值是多少?结果是。。。org.springframework.context.annotation.ConflictingBeanDefinitionException:为bean类[springfox.documentation.swagger2.mappers.ServiceModelToSwagger2Mapper]指定的注释bean名称“ServiceModelTosWagger2Mapprimpl”与相同名称和类的现有不兼容bean定义冲突[special.package.swagger.MyServiceModelToSwagger2Mapper]这确实是我的第一个解决方案,但它不起作用。Spring根本没有调用mapper()方法。有趣的是,我现在在这里实现它是为了确保它能起作用:2016-01-26 08:12:34.724 INFO 58405---[nio-8080-exec-1]DispatcherServlet:FrameworkServlet“DispatcherServlet”:初始化已开始2016-01-26 08:12:34.745信息58405---[nio-8080-exec-1]o.s.web.servlet.DispatcherServlet:FrameworkServlet'DispatcherServlet':初始化在21毫秒内完成******************重写工作!!!您使用的是哪个版本?我的是Spring 3.2。解决了!问题是springfox库的多个版本。因此,Spring无罪。应用程序服务器加载了两个库s和迷路了。一个类路径被解决了,覆盖工作非常好。我在问题中添加了这个注释。非常好@smarquis。在这个解决方案中,有一个不太好的地方是ServiceModelToSwigger2Mapprimpl有很多依赖项。Springfox解决方案自动连接这些依赖项。因此,初始化MyServiceModelToSwigger2Mapper将需要访问所有依赖项。另一个问题。我没有“AnnotationDrivenConfig”类在我的类路径中。我正在使用Spring 3.2。@AnnotationDrivenConfig
只是为了启用@Autowired
和其他注释,它在Spring 3.2中可用。很抱歉,我没有理解您之前的评论。我刚刚在建议的解决方案中将组件扫描部分替换为@Bean
。关于第一条评论。new MyServiceModelToSwagger2Mapper();关于第二条注释。我在标准Spring框架中找不到AnnotationDrivenConfig:。