Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 覆盖Spring定义:springbean注释@Primary_Java_Spring_Spring Mvc - Fatal编程技术网

Java 覆盖Spring定义:springbean注释@Primary

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

在我看来,覆盖bean定义比我想象的要难。 首先,我想保持开/关原则

我正在使用Springfox,它将基于Spring映射提供一个招摇过市的json。Springfox由我必须提供的配置类加载:

@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:。