【问题标题】:Why @Autowired annotation associate every bean of the same class into context.xml?为什么@Autowired 注解将同一个类的每个bean 关联到context.xml 中?
【发布时间】:2015-08-11 22:06:01
【问题描述】:

Context.xml

<?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="foo" class="annotation.Foo">
    <property name="name" value="firstFoo"></property>
</bean>
<bean id="secondaryFoo" class="annotation.Foo">
    <property name="name" value="secondaryFoo"></property>
    <qualifier value="secondaryFoo"></qualifier>
</bean>
<bean id="bar" class="annotation.Bar" />

栏:

public class Bar {

@Autowired
@Qualifier(value="secondaryFoo")
private Foo foo;

public void setFoo(Foo foo) {
    this.foo = foo;
}
public void  printFooName(){
    System.out.println("\nBar class: foo.getName(): "+foo.getName()+"\n");      
}

}

富:

public class Foo {
private String name;

public Foo(){
    System.out.println("\nFoo class: Constructor invoked, name: "+ name + "\n");
}

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

public String getName() {
    return name;
}

@PostConstruct
public void init() {
    System.out.println("\nFoo class: @PostConstruct Bean Foo successfully initialized, name: " + name +"\n");
}
@PreDestroy
public void cleanUp() {
    System.out.println("*\nFoo class: @PreDestroy clean up called\n");
}
}

主要:

public class TestFooBar {

public static void main(String[] args) throws InterruptedException {

    System.out.println("\nMain invoked\n");

    AbstractApplicationContext applicationContext = 
            new ClassPathXmlApplicationContext("annotation/annotation.xml");

    Bar bar = applicationContext.getBean("bar", Bar.class);

    bar.printFooName();

}

}

当我运行应用程序时,系统会按以下顺序打印出来:

- Main invoked 
- Foo class: Constructor invoked, name: null 
- Foo class: @PostConstruct Bean Foo successfully initialized, name: firstFoo 
- Foo class: Constructor invoked, name: null 
- Foo class: @PostConstruct Bean Foo successfully initialized, name: secondaryFoo 
- Bar class: foo.getName(): secondaryFoo

如果我在 Bar 类 (@Autowired @Qualifier(value="secondary Foo")) 中指定了具有辅助 Foo id 的 bean,为什么在 te 上下文中,bean 都被实例化了?

如果我去掉这两个注解,System out 的结果是一样的!怎么可能?

【问题讨论】:

    标签: java xml spring annotations autowired


    【解决方案1】:

    您在 annotation.xml 上下文中指定了两个 Foo bean,因此 Spring 实例化它们(以及您的 bar bean)。

    然后,此外,它会将 secondaryFoo 作为依赖项注入到您的 bar bean 中。

    如果您不希望自动创建 bean,您可以在 annotation.xml 中将它们声明为 lazy-init="true"

    【讨论】:

    • 喜欢这个? &lt;bean id="secondaryFoo" class="annotation.Foo" lazy-init="true"&gt; ... lazy="true" Spring 给了我这个错误:org.springframework.beans.factory.xml.XmlBeanDefinitionStoreException
    • 但是我看到,使用惰性属性,bean 的实例化都相同。区别只是实例化的顺序。对?我只需要实例化 firstFoo 。有可能吗?
    • 如果您只希望 firstFoo 实例化您希望注入到 bar 中的内容? Lazy-init 会将初始化推迟到需要时,即注入另一个 bean 或从上下文中查找。如果您将第一个和第二个 foo 都声明为惰性,则因为您不在应该实例化的任何地方使用 firstFoo。希望对您有所帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-05
    • 2020-09-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-25
    相关资源
    最近更新 更多