英文:
How to stop utility "main" from interfering with real "main" SpringBoot application?
问题
我有一个一直运行正常的SpringBoot应用程序:
@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class },
scanBasePackageClasses = { IndexSyncController.class, IndexerService.class })
@ImportResource("classpath:/spring.xml")
public class AppLauncher {
public static void main(String[] args) {
SpringApplication.run(AppLauncher.class, args);
}
}
同时,目前在 src/test/java
目录下,我有一个名为 "utility" 的东西,它有自己的主方法。这也一直运行正常,但只能在我的开发环境中运行:
@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class,
WebMvcAutoConfiguration.class })
public class AuditApp {
public static void main(String[] args) {
SpringApplication.run(AppLauncher.class, args);
}
@Bean
public CommandLineRunner commandLineRunner(ApplicationContext ctx) {
return args -> {
// ...
};
}
}
现在我有一个新的需求:
我需要将
src/test/java
中的AuditApp
工具移植到生产jar包中。
那我只需将它从 src/test/java
移动到 src/main/java
,对吗?并不是!我在这样做时遇到的第一个障碍是,主应用程序会尝试运行 commandLineRunner()
。基于过去类似需求的经验,我相信这只是冰山一角,还会有其他问题。
是否有通用的最佳实践或清单,用于如何实现这一点?
英文:
I have a SpringBoot app that has been working fine:
@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class },
scanBasePackageClasses = { IndexSyncController.class, IndexerService.class })
@ImportResource("classpath:/spring.xml")
public class AppLauncher {
public static void main(String[] args) {
SpringApplication.run(AppLauncher.class, args);
}
And also currently sitting in src/test/java
, I have a "utility" which has its own main method. This too has been working fine, but can only launched in my development environment:
@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class,
WebMvcAutoConfiguration.class })
public class AuditApp {
public static void main(String[] args) {
SpringApplication.run(AppLauncher.class, args);
}
@Bean
public CommandLineRunner commandLineRunner(ApplicationContext ctx) {
return args -> {
...
};
}
Now I have a new requirement
> I need to take the AuditApp
utility from src/test/java
and make it available in the production jar.
So I just move it from src/test/java
to src/main/java
right? Nope! Very first obstacle I ran into when I do that, is that the main application tries to run the commandLineRunner()
. Because of past experience with a similar requirement, I believe this is just the tip of the iceberg and there will be additional issues.
Is there a canonical, general best-practice or checklist for how to accomplish this?
答案1
得分: 1
考虑的第一件事是真正导致你问题的原因。
你错过了所提到的类的包,但从你的症状来看,我怀疑你的AuditApp
与AppLauncher
所在的包相同,或者在AppLauncher
所在的子包中(或者在由导入的spring.xml内部声明的配置扫描的包中)。
@SpringBootApplication
是@SpringBootConfiguration
和@ComponentScan
的缩写(除了其他)。
因此,AppLauncher
会将AuditApp
视为@SpringBootConfiguration
进行包扫描,并实例化在此配置中创建的bean。AuditApp.main
方法从未被调用,但在配置中声明的bean被实例化。
假设你在com.yourapp
有AppLauncher
,而在com.yourapp.audit
有AuditApp
。
如果你将实用程序应用移动到不在AppLauncher
的包扫描范围内的包中,比如com.yourauditapp
。当运行原始应用程序时,CommandLineRunner
bean 将不会被创建。而且AuditApp
不会影响原始应用程序。
它可能干扰的另一种方式是引入可能触发一些Spring Boot自动配置的依赖关系。
英文:
The first thing to consider is the real reason of your problem.
You missed out packages of mentioned classes, but looking at your symptoms, I suspect your AuditApp
is in the same package, or in a subpackage of one the AppLauncher
is in (or is in package scanned by config declared inside imported spring.xml).
The @SpringBootApplication
is an abbreviation for (amongst other) @SpringBootConfiguration
and @ComponentScan
.
Because of this the AppLauncher
treats AuditApp
as a @SpringBootConfiguration
on a package scan and instantiates beans created within this config. The AuditApp.main
method is never called, but the beans declared in the config are instantianted.
Let's say you have AppLauncher
in com.yourapp
and AuditApp
in com.yourapp.audit
.
If you move your utility application to the package which is not under the package scan for AppLauncher
, like com.yourauditapp
. The CommandLineRunner
bean won't be created when running the original application. And the AuditApp
won't affect the original application.
The only other way it can interfere is when it introduces dependencies which may trigger some Spring-Boot autoconfigurations.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论