上下文:我有一个带有一些实用程序的项目来执行数据修复等操作。每个实用程序都是Java应用程序,即具有main()
方法的类。我想将它们定义为Spring Boot应用程序,因此我可以使用ApplicationRunner
和ApplicationArguments
工具。 Spring配置是通过共享配置类中的注释定义的。我在下面给出了这个设置的最小例子。
期望:如果我致电SpringApplication.run(SomeClass.class, args)
,其中SomeClass
是ApplicationRunner
,则会在该类上运行run()
,而不会在应用中的任何其他类上运行上下文。
实际发生的事情:它调用上下文中的所有ApplicationRunners
。
为什么呢?我理解SpringApplication.run(Class, String[])
表示“运行此类”,而它似乎意味着“从此类加载应用程序上下文并运行您可以在其中找到的任何内容”。我应该如何解决它只运行一个类?我不介意我的其他应用程序类是否不在应用程序上下文中,因为我需要的所有配置都在共享配置类中。但我不想根据我需要运行的类来编辑代码(例如添加或删除注释)。
最小例子:
Spring配置类(共享):
package com.stackoverflow.example;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class ExampleSpringConfig {
/** Some bean - just here to check that beans from this config are injected */
@Bean public FooService fooService () {
return new FooService();
}
}
两个应用程序类
package com.stackoverflow.example;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import javax.annotation.Resource;
@SpringBootApplication
public class SomethingJob implements ApplicationRunner {
@Resource private FooService fooService;
public void run(ApplicationArguments args) throws Exception {
System.out.println("Doing something"); // do things with FooService here
}
public static void main(String[] args) {
SpringApplication.run(SomethingJob.class, args);
}
}
和另一个相同的,除了它打印“做其他事情”。
输出:
[Spring Boot startup logs...]
Doing something else
Doing something
[Spring Boot shutdown logs...]
答案 0 :(得分:2)
首先,只应使用@SpringBootApplication注释一个类。正如您在答案中注意到的那样,这定义了外部" main"入口点。为了清晰度和概念分离,我建议这是与ApplicationRunner
类不同的类。
为了只运行一些但不是所有的跑步者,我通过解析参数完成了这一操作,并迅速退出了不应该被调用的跑步者。 e.g。
package com.stackoverflow.example;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import javax.annotation.Resource;
@Component
public class SomethingJob implements ApplicationRunner {
@Resource private FooService fooService;
public void run(ApplicationArguments args) throws Exception {
if (!args.containsOption("something")) return
System.out.println("Doing something"); // do things with FooService here
}
}
通过这种方式,您可以执行java -jar myjar.jar --something
或java -jar myjar.jar --something-else
,具体取决于您要运行哪一个。
答案 1 :(得分:0)
我在尝试使用我的最小示例时找到了解决方法。
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.demo.mongo.example</groupId>
<artifactId>demomongo</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>demomongo Maven Webapp</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>4.2.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.2.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb</artifactId>
<version>1.2.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>4.2.4.RELEASE</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.7.1</version>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.9.2</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.7.1-1</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>3.0-alpha-1</version>
</dependency>
</dependencies>
<build>
<finalName>demomongo</finalName>
</build>
</project>
只是div
,/
和(declare-const a01 Int)
(declare-const a02 Int)
(assert(or (= (div a01 a02) 2) (= (div a02 a01) 2)))
(assert( > a01 0))
(assert( > a02 0))
(check-sat)
的别名。通过单独应用它们,我发现导致此行为的List<String> results= em.createQuery(
"SELECT myclass FROM myClass ")
.setMaxResults(10)
.getResultList();
注释。如果我只申请其他2,我就不会解决问题。
我想这是因为image: java:openjdk-8-jdk
before_script:
- export GRADLE_USER_HOME=`pwd`/.gradle
cache:
paths:
- .gradle/wrapper
- .gradle/caches
build:
stage: build
script:
- ./gradlew assemble
test:
stage: test
script:
- ./gradlew check
意味着&#34;我是一个配置类,我定义的任何bean应该在组件扫描期间被拉入上下文&#34;虽然这个类没有定义一个 preg_match('/\d{4}/', $value, $match);
,但是一个,它具有相同的效果。因此,如果类路径中有2个这样的bean,它们都会进入应用程序上下文。
如果没有@SpringBootApplication
,您要运行的bean仍然会被注册,因为它被@ComponentScan
调用引用,但类路径上的其他@EnableAutoConfiguration
不会被注册;吨
通过确保我的应用上下文中只有一个@Configuration
,这可以解决我的问题。但它并没有回答更广泛的问题,&#34;如果我做有几个@Configuration
,我怎么告诉Spring Boot运行哪一个?&#34;所以我仍然感谢任何更完整的答案或建议采用不同的方法。