【问题标题】:Spring- How to use Spring Dependency Injection to write a Standalone Java ApplicationSpring - 如何使用 Spring 依赖注入来编写独立的 Java 应用程序
【发布时间】:2010-10-26 07:04:28
【问题描述】:

我想用 IOC 编写一个独立的应用程序,我如何在其中使用 springs 依赖注入?我正在使用 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、依赖注入?

请提及步骤。

【问题讨论】:

  • 后来我发现我没有添加库这就是原因---antlr-3.0.1.jar ---

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


【解决方案1】:

假设你有:

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.

【讨论】:

    【解决方案2】:

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

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

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

    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 的 javadocs 和提及的方法以了解究竟发生了什么。

    【讨论】:

      【解决方案3】:

      如果你喜欢(大部分)纯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 上下文加载器等...)。

      【讨论】:

        【解决方案4】:

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

        【讨论】:

          【解决方案5】:

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

          【讨论】:

            【解决方案6】:

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

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

            【讨论】:

              【解决方案7】:

              你可以使用命令@Autowired

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 2023-03-30
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2011-09-30
                • 2014-12-03
                • 1970-01-01
                相关资源
                最近更新 更多