Spring-如何使用Spring Dependency Injection编写独立的Java应用程序

时间:2009-05-14 19:11:12

标签: java dependency-injection inversion-of-control spring

我想用IOC编写一个独立的应用程序,如何在那里使用spring依赖注入?我正在使用JIdea。支持Spring 2.5,但我想使用spring 3.0就是我试过的方式!

  

我使用Spring MVC的经验我们可以在WebApplicationContext中注入依赖项,但是如何在独立应用程序中注入依赖项

我试过这个

  

ApplicationContext context = new ClassPathXmlApplicationContext(new String[] {"com\\ttg\\xmlfile.xml"});

但我看不到依赖项是由那里定义的bean注入的(在XML文件中) 我把上面的代码放在main方法和两个对象的两个bean定义中,在一个Java类的构造函数中我使用了另一个类的对象 - 它被注入到这个对象中 - 并调用了一个方法,它将打印一些东西,但它没有工作我认为上面的代码创建了所有的依赖项并注入它们但它看起来不像那样

  

如何在不包含WebApplicationContext的独立应用程序中正确使用Springs IOC,依赖注入?

请提及步骤。

7 个答案:

答案 0 :(得分:17)

假设你有:

class Bean1 {
  Bean2 bean2;
}

class Bean2 {
  String data;
}

context.xml文件

<bean id="bean1" class="Bean1">
  <property name="bean2" ref="bean2" />
</bean>

<bean id="bean2" class="Bean2" />

然后这应该是真的

ApplicationContext context = new ClassPathXmlApplicationContext(new String[] {"context.xml"});
Bean1 bean1 = (Bean1) context.getBean("bean1");

// bean1.bean2 should not be null here.

答案 1 :(得分:9)

您可以使用spring提供的自动装配支持,以便将依赖关系(并可能应用后处理器)注入不属于应用程序上下文的对象。

在您的情况下,此对象是您的独立应用程序。

这是实现这一目标的方法。在这个例子中,我使用@Autowired(对于b1),传统的DI(对于b2)和b3的初始化钩子。带注释的自动装配支持假定您已在应用程序上下文中定义了适当的spring后处理器(例如,通过声明<context:annotation-config/>)。

public class StandaloneApp implements InitializingBean {
  @Autowired private Bean1 b1;
  private Bean2 b2;
  private Bean3 b3;

  public void afterPropertiesSet() throws Exception {
    this.b3 = new Bean3(b1, b2);
  }

  public void setB2(Bean2 b2) {
    this.b2 = b2;
  }

  public static void main(String... args) {
    String[] locations = // your files relative to the classpath
    ApplicationContext ac = new ClasspathXmlApplicationContext(locations);
    // or use FileSystemXmlApplicationContext if the files are not in the classpath

    StandaloneApp app = new StandaloneApp();
    AutowireCapableBeanFactory acbf = ac.getAutowireCapableBeanFactory();
    acbf.autowireBeanProperties(app, AUTOWIRE_BY_NAME, false);
    acbf.initializeBean(app, "standaloneApp"); // any name will work
  }
}

在此示例中,所有b1,b2和b3都应为非null(假设应用程序上下文中存在b1和b2 bean)。

我还没有测试过它(可能因为一些错字而无法编译),但这个想法是在最后3行。请参阅AutowireCapableBeanFactory的javadoc,并提及确切了解会发生什么的方法。

答案 2 :(得分:2)

如果你更喜欢(大部分)纯java,你可以使用java config:

@Configuration
pubic class MyConfig {

   @Bean
   public Bean1 bean1() { return new Bean1(); }

   @Bean
   public Bean2 bean2() { return new Bean2(bean1()); }
}

然后实例化:

ApplicationContext ctx = 
    new AnnotationConfigApplicationContext(MyConfig.class);

请记住,有一些纯注释驱动配置尚不支持(例如tx:annotation-driven之类的东西),你可能需要一些xml粘合代码。

<beans>
  <tx:annotation-driven />
  <context:annotation-config/>
  <bean class="MyConfig"/>
</beans>

然后使用基于xml的标准方法创建ApplicationContext(如ClasspathXmlApplicationContext或spring web context loader等)。

答案 3 :(得分:0)

您是否正在调用context.getBean("beanName")来获取对bean的引用,或者您正在执行new SomeClass()?如果通过getBean()执行,则应设置注入的属性。

此外,请务必使用相同的bean工厂(ClassPathXmlApplicationContext实例)来检索所有bean。这很可能是静态最终的,并由整个应用程序使用。

答案 4 :(得分:0)

您是如何确认您的咖啡豆未正确接线的?一个常见问题是xml配置文件不在正确的位置。您能否提供一些更多信息,例如项目布局和用于从容器中获取bean的代码?

答案 5 :(得分:0)

如果你将log4j日志记录添加到你的应用程序中,你应该看到一连串的消息会告诉你很多关于Spring是什么和不做什么的消息。如果你没有那种反馈,你就处于黑暗中。你可以通过log4j从Spring获取更多信息来找出答案。

答案 6 :(得分:0)

您可以使用命令@Autowired