在独立的 Java 应用程序中使用 Spring 3 自动装配
Posted
技术标签:
【中文标题】在独立的 Java 应用程序中使用 Spring 3 自动装配【英文标题】:Using Spring 3 autowire in a standalone Java application 【发布时间】:2011-04-09 06:03:00 【问题描述】:这是我的代码:
public class Main
public static void main(String[] args)
Main p = new Main();
p.start(args);
@Autowired
private MyBean myBean;
private void start(String[] args)
ApplicationContext context =
new ClassPathXmlApplicationContext("META-INF/config.xml");
System.out.println("my beans method: " + myBean.getStr());
@Service
public class MyBean
public String getStr()
return "string";
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<context:annotation-config />
<context:component-scan base-package="mypackage"/>
</beans>
为什么这不起作用?我得到NullPointerException
。是否可以在独立应用程序中使用自动装配?
【问题讨论】:
努力使您的问题易于阅读。并向我们展示异常堆栈跟踪。 我在这里维护一个操作示例:tshikatshikaaa.blogspot.com/2012/08/… 【参考方案1】:如果你正在运行 SpringBoot:
我也遇到了同样的问题,我无法从静态 main 方法自动装配我的一项服务。
如果您依赖 SpringApplication.run,请参阅下面的方法:
@SpringBootApplication
public class PricingOnlineApplication
@Autowired
OrchestratorService orchestratorService;
public static void main(String[] args)
ConfigurableApplicationContext context = SpringApplication.run(PricingOnlineApplication.class, args);
PricingOnlineApplication application = context.getBean(PricingOnlineApplication.class);
application.start();
private void start()
orchestratorService.performPricingRequest(null);
我注意到 SpringApplication.run 返回一个上下文,可以使用类似于上述方法。从那里开始,它与上面完全相同;-)
【讨论】:
【参考方案2】:一个不错的解决方案是进行以下操作,
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
@Component
public class SpringContext implements ApplicationContextAware
private static ApplicationContext context;
/**
* Returns the Spring managed bean instance of the given class type if it exists.
* Returns null otherwise.
* @param beanClass
* @return
*/
public static <T extends Object> T getBean(Class<T> beanClass)
return context.getBean(beanClass);
@Override
public void setApplicationContext(ApplicationContext context) throws BeansException
// store ApplicationContext reference to access required beans later on
SpringContext.context = context;
然后你可以像这样使用它:
YourClass yourClass = SpringContext.getBean(YourClass.class);
我在以下网站找到了这个非常好的解决方案:https://confluence.jaytaala.com/pages/viewpage.action?pageId=18579463
【讨论】:
【参考方案3】:对于 Spring 4,使用 Spring Boot 我们可以有以下示例,而无需使用直接从 ApplicationContext 获取 Bean 的反模式:
package com.yourproject;
@SpringBootApplication
public class TestBed implements CommandLineRunner
private MyService myService;
@Autowired
public TestBed(MyService myService)
this.myService = myService;
public static void main(String... args)
SpringApplication.run(TestBed.class, args);
@Override
public void run(String... strings) throws Exception
System.out.println("myService: " + MyService );
@Service
public class MyService
public String getSomething()
return "something";
确保所有注入的服务都在com.yourproject
或其子包下。
【讨论】:
【参考方案4】:Spring 正在远离 XML 文件并大量使用注释。以下示例是一个简单的独立 Spring 应用程序,它使用注释而不是 XML 文件。
package com.zetcode.bean;
import org.springframework.stereotype.Component;
@Component
public class Message
private String message = "Hello there!";
public void setMessage(String message)
this.message = message;
public String getMessage()
return message;
这是一个简单的 bean。它用@Component
注解装饰,以便Spring容器自动检测。
package com.zetcode.main;
import com.zetcode.bean.Message;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.ComponentScan;
@ComponentScan(basePackages = "com.zetcode")
public class Application
public static void main(String[] args)
ApplicationContext context
= new AnnotationConfigApplicationContext(Application.class);
Application p = context.getBean(Application.class);
p.start();
@Autowired
private Message message;
private void start()
System.out.println("Message: " + message.getMessage());
这是主要的Application
类。 @ComponentScan
注释搜索组件。 @Autowired
注释将 bean 注入到 message
变量中。 AnnotationConfigApplicationContext
用于创建 Spring 应用程序上下文。
我的Standalone Spring tutorial 展示了如何使用 XML 和注释创建独立的 Spring 应用程序。
【讨论】:
此解决方案比 xml 解决方案要容易得多。非常适合我。 我很好奇为什么需要自动装配然后从上下文中获取 bean。我认为我的回答解决了这个反模式 @MichailMichailidis 你有一个 Spring Boot 应用程序。这里我们处理一个经典的 Spring 应用程序。我们需要引导应用程序。 谢谢@JanBodnar。我认为现在默认情况下所有应用程序都是 SpringBootApplications 或者扩展 CommandLineRunner 类似于您所描述的内容,或者以其他方式启动 Web 服务器【参考方案5】:Spring 在独立应用程序中工作。您使用错误的方法来创建弹簧豆。这样做的正确方法是:
@Component
public class Main
public static void main(String[] args)
ApplicationContext context =
new ClassPathXmlApplicationContext("META-INF/config.xml");
Main p = context.getBean(Main.class);
p.start(args);
@Autowired
private MyBean myBean;
private void start(String[] args)
System.out.println("my beans method: " + myBean.getStr());
@Service
public class MyBean
public String getStr()
return "string";
在第一种情况下(问题中的那个),您是自己创建对象,而不是从 Spring 上下文中获取它。所以 Spring 没有机会获得 Autowire
依赖项(这会导致 NullPointerException
)。
在第二种情况下(此答案中的那个),您从 Spring 上下文中获取 bean,因此它由 Spring 管理,Spring 负责 autowiring
。
【讨论】:
@Autowired 不是全押策略吗? spring 管理 all 对象创建无,但您不能将 @Autowired 添加到调用堆栈中的某些字段并使用 new ..() 实例化它们。 @Cojones,您可以自动装配一些 bean 并使用 new 创建其他 bean,否则您将如何调用new ArrayList()
?如果你有一个带有自动装配参数的类并且你用new
实例化它,那么自动装配将不会发生。
您的 config.xml 中可能还需要这个:<context:annotation-config /> <context:component-scan base-package="com.yourcompany.mycomponents" />
不要忘记 Main 上面的 @Component 注解,否则你会得到一个 No qualifying bean of type [..] is defined 异常。我花了一些时间才弄清楚。
@TinusSky 即使我得到了 No qualifying bean of type..error以上是关于在独立的 Java 应用程序中使用 Spring 3 自动装配的主要内容,如果未能解决你的问题,请参考以下文章
如何在独立的 Java 程序中获取我的 Web 应用程序中的 Spring Application 上下文
对于独立应用程序(对于 Spring JMS),Java main 方法应该是啥?