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
。
在带有 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
。