Spring 在普通 Java 程序中注入依赖项

Spring Injection of dependencies in a plain Java program

在带有 REST 控制器的 classic 网络应用程序的上下文中,我需要开发一个小的 Java 程序,该程序将使用适当的调度程序作为常规任务调用.

项目的源代码有两个主要的classes:一个是通常的Spring引导Application,带有一些常见的Spring引导注释(@ EnableAutoConfiguration、@componentScan 等)

第二个主要 class 是一个带有 static void main 方法的普通 Java class。由于任务程序将使用标准 Web 应用程序创建的数据,我必须(我必须承认,没有考虑太多),在几个 class 变量上使用 @Autowired 注释以通过 JPA 存储库访问数据.

只是现在,当 运行 任务程序时,我在使用第一个存储库时遇到了 NullPointerException。一秒钟,我感到困惑,然后我意识到错误是可以预料的,因为 Spring 没有发挥它的魔力 .

我现在的问题是如何让 Spring 在这个简单的 Java main class 上进行依赖注入?我的猜测是某个地方可以放置一个或多个注释,但是在大量 Spring 注释中,这就像在一堆针袋中找到一根特定的针。

[编辑] @J-Mengelle 的回答是要走的路:我在启动任务时看到了与启动 Web 应用程序时完全一样的控制台消息。

这是我得到的代码(下面的解释):

AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
ctx.register(Application.class); // This is the Spring boot application class

InputStream is = Application.class.getClassLoader()
        .getResourceAsStream("application.properties"); //$NON-NLS-1$
Properties props = new Properties();
props.load(is);
is.close();

ConfigurableEnvironment environment = new StandardEnvironment();
MutablePropertySources propertySources = environment.getPropertySources();
Map<String, Object> myMap = new HashMap<>();
for (Object key : props.keySet()) {
    myMap.put((String) key, props.get(key));
}
propertySources.addFirst(new MapPropertySource("MY_MAP", myMap)); //$NON-NLS-1$

ctx.setEnvironment(environment);
ctx.refresh();

但是,我遇到了第一个异常消息:

Cannot determine embedded database driver class for database type NONE

这是因为 application.properties 没有被读取并且数据源没有被配置,因此上面的手动读取,我认为通常由 Spring 引导处理。

在那之后,可能会遇到 bean 创建异常。我遇到过 springfox 的一个这样的例外。然后我简单地删除了 Swagger 配置 bean 上的 @EnableSwagger2 注释,它从那时起顺利进行,这意味着我可以编写像 actionRepository = ctx.getBean(ActionRepository.class); 这样的指令并将有效引用正确地注入到变量中。

像这样:

public static void main(String[] args) {
   ApplicationContext ctx = 
   new AnnotationConfigApplicationContext(HelloWorldConfig.class);

   HelloWorld helloWorld = ctx.getBean(HelloWorld.class);

   helloWorld.setMessage("Hello World!");
   helloWorld.getMessage();

}

http://www.tutorialspoint.com/spring/spring_java_based_configuration.htm

无法将 spring 依赖项注入普通 Java class 直到它不是 Spring 上下文的一部分。一种方法是通过将此 class 声明为 bean 并删除 main 方法,将其置于 spring 上下文中。反过来说,如果你需要坚持使用 main 方法,那就是通过应用程序上下文加载 Spring bean。

ApplicationContext applicationContext = new ClassPathXmlApplicationContext("/application-context.xml");
beanA = (BeanA) applicationContext.getBean("beanA");

然后你可以把它赋值给你要设置的class变量BeanA beanA