Весенний новичок: загрузка бобов и проводка потока - PullRequest
3 голосов
/ 14 января 2012

Я только начал читать «Spring In Action - Третье издание» и застрял, экспериментируя с концепциями проводки.Я не могу понять жизненный цикл компонента после написания этого кода:

    public class TestCase {
    public static void main(String[] args) {

        ApplicationContext context = new ClassPathXmlApplicationContext("test.xml");
        Test1 t1 = (Test1)context.getBean("test1");
        t1.setName1("Win");
        Test1 t2 = (Test1)context.getBean("test1");
        t2.setName1("Lin");
        Test2 t3 = (Test2)context.getBean("test2");
        Test1 t4 = t3.getName();
        System.out.println("End" +t4.getName1());

    }

}

public class Test1 {

    private String name1;

    public String getName1() {
        System.out.println("test1 - getter");
        return name1;
    }

    public void setName1(String name1) {
        System.out.println("test1 - setter");
        this.name1 = name1;
    }

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

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


public class Test2 {

    private int age;
    private Test1 name;
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public Test1 getName() {
        System.out.println("test2 - getter");
        return name;
    }
    public void setName(Test1 name) {
        System.out.println("test2 - setter");
        this.name = name;
    }

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

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

Вот мой test.xml:

<bean id="test1" class="springidol.Test1" init-method="onStart" destroy-method="onStop" >
</bean>

<bean id="test2" class="springidol.Test2" init-method="onStart" destroy-method="onStop">
<property name="name" ref="test1"></property>
</bean>

Вывод:

   start1
test2 - setter
start2
test1 - setter
test1 - setter
test2 - getter
test1 - getter
End - Lin

Если я поменяю область действия Test1 на прототип, я получу:

start1
test2 - setter
start2
start1
test1 - setter
start1
test1 - setter
test2 - getter
test1 - getter
End - null

Я знаю, что прошу слишком много, но может кто-нибудь подсказать мне, какие здесь шаги - я не могу понять, почему вызывается установщик test2после завершения загрузки tst1 (и даже до загрузки test2)!

Во-вторых, почему выходные данные "End" для областей прототипа и по умолчанию отличаются?Спасибо.

1 Ответ

2 голосов
/ 14 января 2012

Потому что Spring сначала устанавливает ссылки на другие bean-компоненты. (Проводка из бобов) После этого будут вызваны методы init.

Поскольку ваш установщик test2 указывает на ссылку test1 в конфигурации контекста вашего приложения, он будет вызван первым.

---------- редактировать ------------

Область действия прототипа немного хитрая, поскольку она ведет себя по-разному в зависимости от того, является ли ваш bean-объект с прототипом прокси-сервером или нет.

Если вы получите прототипный компонент непосредственно из контекста приложения, как вы это сделали, вы будете каждый раз получать новый экземпляр. Установка имени для первого экземпляра не повлияет на имя второго экземпляра, который вы записываете в конце.

Но если в контекст приложения ссылается на bean-объект области действия-прототип из другого singleton bean-компонента, вводится прокси. Этот прокси будет даже переключать фактически вызванный экземпляр для каждого вызова метода . Это будет более раздражающим, так как:

Test1 t4 = t3.getName(); 
t4.setName1("lala");
assertEquals(null,t4.getName1()); //will be true

Но, пожалуйста, проверьте это, так как это то, что я предполагаю, что это делает. Я не проверял это по коду.

...