こんにちは、単純なアプリケーションを手に入れたので、いくつかの統合テストを作成しようとしています。そのため、JUnit テストで springboot を使用しており、テスト開発と本番用にわずかに異なる構成が必要なため、プロファイルを使用しています。私の問題は、アプリケーションをスタンドアロンの tomcat サーバーにデプロイすると、プロファイルが完全に機能することです。ただし、springboot で JUnit テストを開始すると、アプリケーションはすべてのプロファイル構成を読み込もうとするため、競合が発生します。
「タイプ 'org.springframework.context.MessageSource' の適格な Bean がありません: 単一の一致する Bean が期待されていましたが、2 つ見つかりました」
すでに述べたように、これはスタンドアロンの tomcat で動作します。
ここに私のコードのスニペットがあります:
これは私のテストクラスです
@ActiveProfiles(ProfileConstants.TEST)
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = {SpringBootInitializer.class})
public class MyTest
次に、SpringBootInitializer
@Configuration
@EnableAutoConfiguration
@Import(WebAppConfig.class)
public class SpringBootInitializer extends SpringBootServletInitializer implements ServletContextAware
{
/**
* this method will force the embedded tomcat to load the jsf-configuration
*
* @param servletContext the servletcontext of embedded tomcat
*/
@Override
public void setServletContext(ServletContext servletContext)
{
// sets the spring default initialization profile to test
servletContext.setInitParameter("spring.profiles.active", ProfileConstants.TEST);
// will ensure, that the context-initialization is executed. If not set to true the jsf-config will not be
// loaded
servletContext.setInitParameter("com.sun.faces.forceLoadConfiguration", "true");
// will initialize jsf-context
servletContext.addListener(com.sun.faces.config.ConfigureListener.class);
}
/**
* registration of the {@link FacesServlet} with url mappings to .xhtml, .jsf and .faces
*
* @return the ServletRegistrationBean with registered {@link FacesServlet}
*/
@Bean
public ServletRegistrationBean facesServletRegistration()
{
ServletRegistrationBean registration = new ServletRegistrationBean(new FacesServlet(), "*.xhtml", "*.jsf",
"*.faces");
registration.setLoadOnStartup(1);
return registration;
}
}
そして最後に私の WebAppConfig.class
@Configuration
@ComponentScan({"my.component.package"})
@EnableWebMvc
public class WebAppConfig extends WebMvcConfigurerAdapter
{
...
/**
* spring locale. the resource-bundles will be set here . <br>
* also the {@link MessageReaderHolder} will be initialized here that holds a static default implementation
* to read the messages from the resource bundles.
*
* @return the resource bundles
*/
@Profile({ ProfileConstants.PRODUCTION, ProfileConstants.TEST})
@Bean(name = "messageSource")
public MessageSource messageSourceProduction()
{
ReloadableResourceBundleMessageSource bundleMessageSource = new ReloadableResourceBundleMessageSource();
bundleMessageSource.setBasenames("classpath:locale");
MessageReaderHolder.initialize(bundleMessageSource);
return bundleMessageSource;
}
/**
* spring locale. the resource-bundles will be set here . <br>
* also the {@link MessageReaderHolder} will be initialized here that holds a static default implementation
* to read the messages from the resource bundles.
*
* @return the resource bundles
*/
@Profile({ ProfileConstants.DEVELOPMENT})
@Bean(name = "messageSource")
public MessageSource messageSourceDevelopment()
{
ReloadableResourceBundleMessageSource bundleMessageSource = new ReloadableResourceBundleMessageSource();
bundleMessageSource.setBasenames("classpath:locale");
bundleMessageSource.setCacheSeconds(30);
MessageReaderHolder.initialize(bundleMessageSource);
return bundleMessageSource;
}
}
使用するプロファイルに基づいて、1 つの messageSource のみが構成に読み込まれることを期待します。私は常に 1 つのプロファイルのみを使用しているため、アプリケーションは重複する Bean をロードするべきではありませんが、ロードします。
なぜこれが起こるのですか?この問題の手がかりが見つかりません...