我有一个非常基本的Spring Boot Application。
项目中有2个@SpringBootApplication
:
ApplicationA:
package com.example;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.ImportResource;
/**
* Created on 2/16/16.
*/
@SpringBootApplication
@ImportResource("classpath:run-app-a-context.xml")
public class ApplicationA {
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(ApplicationA.class, args);
System.out.println(context.getBean("helloA"));
System.out.println(context.getBean("helloB"));
}
}
ApplicationB:
package com.example;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.ImportResource;
/**
* Created on 2/16/16.
*/
@SpringBootApplication
@ImportResource("classpath:run-app-b-context.xml")
public class ApplicationB {
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(ApplicationB.class, args);
System.out.println(context.getBean("helloA"));
System.out.println(context.getBean("helloB"));
}
}
如您所见,ApplicationA仅应导入run-app-a-context.xml
,而ApplicationB仅应导入run-app-b-context.xml
。但是,这不是发生的事情。
如果我跑./gradlew bootRun
;我得到以下输出(强调添加):
./gradlew bootRun :compileJava UP-TO-DATE :processResources UP-TO-DATE :classes UP-TO-DATE :findMainClass :bootRun . ____ _ __ _ _ /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \ ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \ \\/ ___)| |_)| | | | | || (_| | ) ) ) ) ' |____| .__|_| |_|_| |_\__, | / / / / =========|_|==============|___/=/_/_/_/ :: Spring Boot :: (v1.3.1.RELEASE) 2016-02-16 11:42:21.889 INFO 47524 --- [ main] com.example.ApplicationA : Starting ApplicationA on LMC with PID 47524 (/Users/IdeaProjects/whyisitloadingeverything/build/classes/main started in /Users/IdeaProjects/whyisitloadingeverything) 2016-02-16 11:42:21.896 INFO 47524 --- [ main] com.example.ApplicationA : No active profile set, falling back to default profiles: default 2016-02-16 11:42:21.975 INFO 47524 --- [ main] s.c.a.AnnotationConfigApplicationContext : Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@24a35978: startup date [Tue Feb 16 11:42:21 PST 2016]; root of context hierarchy 2016-02-16 11:42:22.883 INFO 47524 --- [ main] o.s.b.f.xml.XmlBeanDefinitionReader : Loading XML bean definitions from class path resource [run-app-b-context.xml] 2016-02-16 11:42:23.081 INFO 47524 --- [ main] o.s.b.f.xml.XmlBeanDefinitionReader : Loading XML bean definitions from class path resource [run-app-a-context.xml] 2016-02-16 11:42:23.255 INFO 47524 --- [ main] o.s.b.f.config.PropertiesFactoryBean : Loading properties file from URL [jar:file:/Users/.gradle/caches/modules-2/files-2.1/org.springframework.integration/spring-integration-core/4.2.4.RELEASE/4780d5c2b680796844916402816135f0e79f166f/spring-integration-core-4.2.4.RELEASE.jar!/META-INF/spring.integration.default.properties] 2016-02-16 11:42:23.258 INFO 47524 --- [ main] o.s.i.config.IntegrationRegistrar : No bean named 'integrationHeaderChannelRegistry' has been explicitly defined. Therefore, a default DefaultHeaderChannelRegistry will be created. 2016-02-16 11:42:23.451 INFO 47524 --- [ main] faultConfiguringBeanFactoryPostProcessor : No bean named 'errorChannel' has been explicitly defined. Therefore, a default PublishSubscribeChannel will be created. 2016-02-16 11:42:23.470 INFO 47524 --- [ main] faultConfiguringBeanFactoryPostProcessor : No bean named 'taskScheduler' has been explicitly defined. Therefore, a default ThreadPoolTaskScheduler will be created. 2016-02-16 11:42:24.036 INFO 47524 --- [ main] o.s.b.f.config.PropertiesFactoryBean : Loading properties file from URL [jar:file:/Users/.gradle/caches/modules-2/files-2.1/org.springframework.integration/spring-integration-core/4.2.4.RELEASE/4780d5c2b680796844916402816135f0e79f166f/spring-integration-core-4.2.4.RELEASE.jar!/META-INF/spring.integration.default.properties] 2016-02-16 11:42:24.100 INFO 47524 --- [ main] o.s.s.c.ThreadPoolTaskScheduler : Initializing ExecutorService 'taskScheduler' 2016-02-16 11:42:24.226 INFO 47524 --- [ main] o.s.j.e.a.AnnotationMBeanExporter : Registering beans for JMX exposure on startup 2016-02-16 11:42:24.243 INFO 47524 --- [ main] o.s.c.support.DefaultLifecycleProcessor : Starting beans in phase 0 2016-02-16 11:42:24.243 INFO 47524 --- [ main] o.s.i.endpoint.EventDrivenConsumer : Adding {logging-channel-adapter:_org.springframework.integration.errorLogger} as a subscriber to the 'errorChannel' channel 2016-02-16 11:42:24.244 INFO 47524 --- [ main] o.s.i.channel.PublishSubscribeChannel : Channel 'application.errorChannel' has 1 subscriber(s). 2016-02-16 11:42:24.244 INFO 47524 --- [ main] o.s.i.endpoint.EventDrivenConsumer : started _org.springframework.integration.errorLogger 2016-02-16 11:42:24.256 INFO 47524 --- [ main] com.example.ApplicationA : Started ApplicationA in 2.9 seconds (JVM running for 3.466) application A application B 2016-02-16 11:42:24.257 INFO 47524 --- [ Thread-1] s.c.a.AnnotationConfigApplicationContext : Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@24a35978: startup date [Tue Feb 16 11:42:21 PST 2016]; root of context hierarchy 2016-02-16 11:42:24.258 INFO 47524 --- [ Thread-1] o.s.c.support.DefaultLifecycleProcessor : Stopping beans in phase 0 2016-02-16 11:42:24.259 INFO 47524 --- [ Thread-1] o.s.i.endpoint.EventDrivenConsumer : Removing {logging-channel-adapter:_org.springframework.integration.errorLogger} as a subscriber to the 'errorChannel' channel 2016-02-16 11:42:24.259 INFO 47524 --- [ Thread-1] o.s.i.channel.PublishSubscribeChannel : Channel 'application.errorChannel' has 0 subscriber(s). 2016-02-16 11:42:24.259 INFO 47524 --- [ Thread-1] o.s.i.endpoint.EventDrivenConsumer : stopped _org.springframework.integration.errorLogger 2016-02-16 11:42:24.260 INFO 47524 --- [ Thread-1] o.s.s.c.ThreadPoolTaskScheduler : Shutting down ExecutorService 'taskScheduler' 2016-02-16 11:42:24.261 INFO 47524 --- [ Thread-1] o.s.j.e.a.AnnotationMBeanExporter : Unregistering JMX-exposed beans on shutdown BUILD SUCCESSFUL Total time: 13.537 secs
我看到正在加载两个xml上下文文件,因此两个文件中的bean都被添加到应用程序上下文中。
为什么Spring / Spring Boot会自动加载所有xml配置文件?如何阻止此行为?
答案 0 :(得分:5)
这是因为@SpringBootApplication
default includes @ComponentScan
注释以及@Configuration
注释。
如果未定义basePackageClasses()
或basePackages()
(或其别名value()
),ComponentScan annotation将默认递归扫描当前包。它查找标有@Configuration的类,如果找到,则将在其中定义的bean添加到应用程序上下文中。
由于ApplicationA
和ApplicationB
都在同一个包中;在启动ApplicationA
时,ApplicationB
会自动进行组件扫描(反之亦然,在启动ApplicationB
时)。
The fix是将ApplicationA
和ApplicationB
放在不同的包中。