Dave
Dave

Reputation: 1502

I don't understand Autowired in Spring

ApplicationContext

<?xml version="1.0" encoding="UTF-8"?>
<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 />

    <bean id="beanFactory" class="testSpring.BeanFactory" />

    <bean id="a1" class="testSpring.A">
        <property name="name" value="I am A one!"></property>
    </bean>

    <bean id="a2" class="testSpring.A">
        <property name="name" value="I am A two!"></property>
    </bean>

    <bean id="b" class="testSpring.B">
        <property name="name" value="I am B!"></property>
    </bean>

</beans>

Main

public class Main 
{
    public static void main( String[] args )
    {
        System.out.println("Avvio applicazione: Main invocato");
        AbstractApplicationContext applicationContext = new ClassPathXmlApplicationContext(
                "ApplicationContext.xml");

        BeanFactory ai = applicationContext.getBean("beanFactory", BeanFactory.class);


    }
}

A (The same for B bean)

public class A {

    private String name;

    public A(){

    }

    @SuppressWarnings("restriction")
    @PostConstruct
    public void init(){
        System.out.println("Bean A created, name: " + name);
    }

    public String getName(){
        return this.name;
    }

    public void setName(String name){
        this.name = name;
    }   

}

BeanFactory

public class BeanFactory {

    @Autowired
    @Qualifier(value="a1")
    private A a;

    public void setA(A a){
        this.a = a;
    }

    public void printAName(){
        System.out.println("Classe AInstantiator: AInstantiator.printAName -> a.getName() = " + a.getName());
    }

}

This is the result of running:

Avvio applicazione: Main invocato
Bean A created, name: I am A one!
Bean A created, nome: I am A two!
Bean B created, name: I am B!

How it's possible?!

1) Why A two is created? I specified in the @Qualifier a1 bean, not both! Qualifier annotation isn't used to binding a specific bean of the same class? Right?

2) Why Bean B is created? I don't binding it with @Autowired.

If I remove

 @Autowired 
 @Qualifier(value="a1")

from BeanFactory, the result is the same! It's not possible.. I don't understand. Maybe the compiler is crashed? Help, please!

Upvotes: 0

Views: 551

Answers (2)

Milos Gregor
Milos Gregor

Reputation: 950

The beans are eagerly initialized by default which means the container "eagerly create and configure all singleton beans as part of the initialization process". Simply, the @PostConstruct methods are called on start up regardless of any autowiring or other dependency injection.

If you want otherwise, you need to set :

lazy-init="true"

Upvotes: 2

Beau Grantham
Beau Grantham

Reputation: 3456

Beans are eagerly created by default. If you'd like to delay this you can use lazy-initialization.

Upvotes: 0

Related Questions