Saturday, April 30, 2011

Spring IoC with annotations only and without any configuration!

The purpose of this post is to show on a simple example how to create an application using extensively Spring IoC and yet configured only by means of Java5 annotations.

I believe a short and concise example is worth more then theoretical divagation. Therefore I'll strive to be brief!


Prerequisites

* A subset of these Spring libraries: spring-core, spring-aop, spring-beans, spring-tx
Obtainable from the Spring's homepage

* Java 1.5

Main

Let's go directly to the code:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.stereotype.Service;

@Service
public class Main 
{
    
    @Autowired
    private Runnable proxy;
    
    public void run(){
        proxy.run();        
    }
    
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext("the.package.to.be.scanned");
        ((Main) context.getBean(Main.class)).run();
    }
}

Now, the most important line for us is "new AnnotationConfigApplicationContext("the.package.to.be.scanned"). It says:
Check every class in the package "the.package.to.be.scanned" and look for those which are annotated by @Service, @Component, @Controller or @Repository and register them as beans. Once it's done, instantiate all the not-lazy singletons and autowire any dependencies needed.

Of course, registered but not instantiated beans may be instantiated later. Note, that by default beans are not-lazy singletons.

DummyThread

Up there you could see that we autowired an instance of a class implementing the Runnable interface (it's not a good idea in a production code; we do it for the sake of simplicity here!)

import org.springframework.stereotype.Service;

@Service
public class DummyThread implements Runnable{

    public void run() {
        System.out.println("run()");
    }
}

And yes, you should expect "run()" on the conosle as a result of this simple app!

AFactory

Now, you may ask what if I want to register a factory? Is it possible using annotations only? Well... it is!

@Service
public class ConfWithProfiling extends AFactory{
    
    @Bean(name="proxy", autowire=Autowire.BY_NAME) public Runnable proxy(){
        return new DummyThread();
    }
}

The magic is done by @Bean annotation, it says:
This method knows how to create a bean named "proxy".

Note also the @Service annotation. We need that for our scanner in Main class. Without it, Spring context wouldn't register AFactory class and therefore, the "proxy" bean.

Sum up

It is possible to use Spring without any configuration file whatsoever. You must take into account however, that without a @Configuration class or .xml configuration file it might be hard to understand what happends under the hood of Spring. In particular, which classes get instantiated and in what order! More on that later.

No comments:

Post a Comment