【问题标题】:Spring Boot with more context具有更多上下文的 Spring Boot
【发布时间】:2017-05-02 17:18:27
【问题描述】:

我有一个带有@SpringBootApplication 主类的弹簧靴(因此它具有隐含标签@EnableAutoConfiguration@ComponentScan@Configuration)。

如果我创建另一个带有注释@Configuration@ComponentScan 的类会发生什么?我要创建另一个豆子容器吗?这样豆子是重复的吗?是创建更多@Configuration 类的好方法吗? @Configuration 创建一个豆子容器?如果是,两个容器共享 bean?

我需要了解这些问题。

【问题讨论】:

  • 请参考官方网站的spring框架和Spring-boot文档。

标签: java spring spring-mvc spring-boot dependency-injection


【解决方案1】:

如果我创建另一个带有注释@Configuration 和@Component Scan 的类会发生什么?

没关系,完全正常..

我创建另一个豆子容器?这样豆子是重复的?

如果你创建了两个相同类型的bean,应用启动时会报错。你需要将其中一个声明为@Primary

【讨论】:

  • 带有springbootapplication的A类和带有Configuration的B类是同一个bean容器还是两个不同的容器?如果我在 C 类中有一个组件。系统创建两个实例是因为有两个配置?
  • 所有 bean 都属于同一个上下文。如果 A 扫描 B 和 C.. 上下文将有同一个 bean 的两个实例(在 B 和 C 中定义),您必须将一个标记为初级
【解决方案2】:

你可以在spring boot中定义多个@configuration Matias Elorriaga 提到。 @Configuration 等于 spring xml 中的<beans> 标记,其中包含许多<bean>(等于@Bean),与注释@Configuration 相同的类说嘿你可以在我里面定义多个bean e.f:

@Configuration
public class AppConfig {
@Bean
    public MessageSource messageSource() {
        ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
        messageSource.setBasename("message");
        messageSource.setDefaultEncoding("UTF-8");
        return messageSource;
    }

    @Bean
    public Validator validator() {
        final LocalValidatorFactoryBean localValidatorFactoryBean = new LocalValidatorFactoryBean();
        localValidatorFactoryBean.setValidationMessageSource(messageSource());
        return localValidatorFactoryBean;
    }

    @Bean
    public LocaleResolver localeResolver() {
        SessionLocaleResolver sessionLocaleResolver = new SessionLocaleResolver();
        sessionLocaleResolver.setDefaultLocale(Locale.ENGLISH);
        return sessionLocaleResolver;
    }

}

另外,如果您有 2 个不同的类具有相同类型的 Bean 例如class: SpringConfigA 有 Composite bean

@Configuration
 public class SpringConfigA {

@Bean
     public Composite composite() {
         Composite c = new Composite();
         return c;             
     }
}

和另一个类 SpringConfigB 有相同的 Composite bean

@Configuration
 public class SpringConfigB {

@Bean
     public Composite composite() {
         Composite c = new Composite();
         return c;             
     }
}

然后它会在 bean 初始化期间抛出异常,因为复合 bean 有歧义,所以 在这里你可以使用限定符来解决这个问题

所以

@Configuration
 public class SpringConfigA {

@Bean
 @Qualifier("compositeA")
     public Composite composite() {
         Composite c = new Composite();
         return c;             
     }
}

另一个类 SpringConfigB 具有相同的 Composite bean,限定符名称为“compositeB”

@Configuration
 public class SpringConfigB {

@Bean
 @Qualifier("compositeB")
     public Composite composite() {
         Composite c = new Composite();
         return c;             
     }
}

【讨论】:

  • 好的,所以两个配置类不是两个不同的容器。你能确认一下吗?我不想复制我的组件 bean,因为这两个配置类具有相同的扫描包
  • 配置类实际上只不过是用于创建和注册 bean 实例的 Spring 托管工厂。具有相同扫描包的两个配置类,这没关系,这不是问题,spring 会处理它,但要确保两个配置类中没有重复的 bean 寄存器。如果您将在 Configuration 类中注册一个 bean,则该类将适用于您的所有应用程序,因此不必担心多个 Configuration。
【解决方案3】:

是的,您可以通过在调度程序 servlet 中注册配置 bean 或通过导入已在 spring 容器中注册的单独配置 bean 来使用 @ComponentScan 注册 bean。 假设您有正在扫描组件的 Config 类-

@ComponentScan(basePackages = {"xyz"})
@Configuration
public class Config {
....
}

要在容器中注册配置,您必须这样做-

new AnnotationConfigWebApplicationContext().register(Config .class);

或者

@Configuration
@Import({MvcConfig.class})
public class AnotherConfig  {
....
}

【讨论】:

  • 如果我有带有 springbootapplication 概念的 A 类和带有 Configuration 注释的 B 类是相同的 bean 容器还是两个不同的容器?如果我在 C 类中有一个组件。系统创建两个实例是因为有两个配置?
  • 这取决于你是想在 springbootapplication 类中还是在单独的配置 beans 中使用它。Spring 无论如何都会将其视为单个容器来完成它的工作
  • 好的,所以两个配置类不是两个不同的容器。你能确认一下吗?我不想复制我的组件 bean,因为这两个配置类具有相同的扫描包
  • ok thnx for the link.. 链接显示使用两个配置创建上下文: AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class, DataSourceConfig.class); ....但在春季启动我不直接创建上下文...谁创建上下文?方法 SpringApplication.run ?它会自动使用带有注释 @Configuration 的所有类?
猜你喜欢
  • 2015-11-12
  • 2019-02-11
  • 2018-08-17
  • 2023-03-04
  • 2018-05-17
  • 2017-05-23
  • 2017-12-15
  • 2015-05-02
  • 2019-08-22
相关资源
最近更新 更多