我认识到 ApplicationContext 和 XmlBeanFactory 在对象的运行时初始化方面存在巨大差异。
applicationcontext 立即调用对象构造函数,从而立即创建对象。
仅当调用 beanFactory.getBean(String name) 时,XmlBeanFactory 才会创建对象。
如果这对问题域很重要,请尝试以下代码,作为避免 XmlBeanFactory 的原始源的等效代码。
final Resource resource = new ClassPathResource("SpringHelloWorld.xml");
final DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
final XmlBeanDefinitionReader xmlBeanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
xmlBeanDefinitionReader.loadBeanDefinitions(resource);
Spring3HelloWorld myBean = beanFactory.getBean("Spring3HelloWorldBean", Spring3HelloWorld.class);
myBean.sayHello();
为了使明显的船长满意,下面是一个比较完整的例子。
首先是模型 Person.java。
package com.stackoverflow.questions_5231371;
// ./spring-tutorial/src/main/java/com/stackoverflow/questions_5231371/Person.java
public class Person {
int id;
String name;
public Person() {
System.out.println("calling Employee constructor");
}
public int getId() {
return id;
}
public void setId(final int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(final String name) {
this.name = name;
}
@Override
public String toString() {
return "Person [id=" + id + ", name=" + name + "]";
}
}
然后是personbeans.xml中的对象数据。
<?xml version="1.0" encoding="UTF-8"?>
<!-- ./spring-tutorial/src/main/java/personbeans.xmlxml -->
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="p1" class="com.stackoverflow.questions_5231371.Person">
<property name="id" value="1" />
<property name="name" value="Sheldon" />
</bean>
<bean id="p2" class="com.stackoverflow.questions_5231371.Person">
<property name="id" value="2" />
<property name="name" value="Penny" />
</bean>
<bean id="p3" class="com.stackoverflow.questions_5231371.Person">
<property name="id" value="3" />
<property name="name" value="Leonard" />
</bean>
</beans>
以及调用对象的主要方法。
package com.stackoverflow.questions_5231371;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
// ./spring-tutorial/src/main/java/com/stackoverflow/questions_5231371/Main.java
public class Main {
public static void main(final String[] args) {
// Spring #1 IoC application context
System.out.println("--- ApplicationContext");
final ApplicationContext context = new ClassPathXmlApplicationContext("personbeans.xml");
System.out.println("context created ---");
System.out.println(context.getBean("p1"));
System.out.println(context.getBean("p2"));
System.out.println(context.getBean("p3"));
// Spring #2 IoC bean factory
System.out.println("--- DefaultListableBeanFactory");
final Resource resource = new ClassPathResource("personbeans.xml");
final DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
final XmlBeanDefinitionReader xmlBeanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
xmlBeanDefinitionReader.loadBeanDefinitions(resource);
System.out.println("bean definition loaded ---");
System.out.println(beanFactory.getBean("p1"));
System.out.println(beanFactory.getBean("p2"));
System.out.println(beanFactory.getBean("p3"));
}
}
有趣的部分是在控制台输出中加载构造函数时的输出“调用员工构造函数”时的比较。
--- ApplicationContext
calling Employee constructor
calling Employee constructor
calling Employee constructor
context created ---
Person [id=1, name=Sheldon]
Person [id=2, name=Penny]
Person [id=3, name=Leonard]
--- DefaultListableBeanFactory
bean definition loaded ---
calling Employee constructor
Person [id=1, name=Sheldon]
calling Employee constructor
Person [id=2, name=Penny]
calling Employee constructor
Person [id=3, name=Leonard]