Spring- How to use Spring Dependency Injection to write a Standalone Java Application

14,666

Solution 1

suppose you have:

class Bean1 {
  Bean2 bean2;
}

class Bean2 {
  String data;
}

the context.xml file

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

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

then this should be true

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

// bean1.bean2 should not be null here.

Solution 2

you can use autowiring support provided by spring, in order to inject dependencies (and possibly apply post processors) to an object that is not part of the application context.

In your case, this object is your standalone application.

Here is the way to achieve this. In this example, I use @Autowired (for b1), traditional DI (for b2) and initialization hook for b3. The autowiring support with annotations assumes you have defined the appropriate spring post-processor in your application context (e.g. by declaring <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
  }
}

In this example, all b1, b2 and b3 should be non-null (assuming b1 and b2 beans exist in your application context).

I haven't tested it (might not even compile due to some typo), but the idea is in the last 3 lines. See the javadocs for AutowireCapableBeanFactory and mentionned methods to see exactly what happens.

Solution 3

If you prefer (mostly) pure java, you can use java config:

@Configuration
pubic class MyConfig {

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

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

And then to instantiate:

ApplicationContext ctx = 
    new AnnotationConfigApplicationContext(MyConfig.class);

Keep in mind there's some things that pure annotation driven configuration doesn't yet support (such as things like tx:annotation-driven), which you might need some xml glue code for.

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

And then use a standard xml based way of creating the ApplicationContext (like ClasspathXmlApplicationContext, or the spring web context loader, etc...).

Share:
14,666
Buddhi
Author by

Buddhi

Updated on June 04, 2022

Comments

  • Buddhi
    Buddhi about 2 years

    I want to write a standalone application with IOC, how do I use springs dependency injection in there? I'm using JIdea. There is spring 2.5 support but I want to use spring 3.0 here is the way I tried!

    I experience in using Spring MVC we can inject dependencies there in a WebApplicationContext but how do I inject dependencies in a standalone application

    I tried this

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

    but I cannot see that the dependencies are injected by the beans defined there (in the XML file) I put the above code in the main method and two bean definitions for two Objects,in one Java class's constructor I used the other class's object - which was injected to this object - and called a method on that which will print some thing but it didn't worked I thought that the above code creates all the dependencies and injects them but it doesn't seem like that

    How do I properly use Springs IOC, dependency injection in my stand alone app which does not contain a WebApplicationContext?

    Please mention steps.