Spring框架中很重要的一部分是关于IoC的,Spring提供了ApplicaitonContext这样一个接口 (bean factory),通过它来创建bean。除了这个接口,Spring提供了一些具体的context实现类,包括ClassPathXmlApplicationContext, FileSystemXmlApplicationContext, XmlWebApplicationContext 和 XmlPortletApplicationContext。
通过创建一个简单的例子来看一下Spring IoC是怎么使用的。
首先在Eclipse里面创建一个Java Project, 目录结构如下,这里面主要包括两个Java 文件
1) SequenceGenerator.java
一个简单的bean
2) Main.java
包含main方法,用来创建SequenceGenerator.
3) Spring-Config.xml
Bean 的配置文件, Spring通过这个XML文件来实例化bean.
Class SequenceGeneror
public class SequenceGenerator {
private String prefix;
private String suffix;
private int initial;
private int counter;
public SequenceGenerator(){
//
}
public SequenceGenerator(final String prefix, final String suffix, final int initial) {
this.prefix = prefix;
this.suffix = suffix;
this.initial = initial;
}
public void setPrefix(final String prefix) {
this.prefix = prefix;
}
public void setSuffix(final String suffix) {
this.suffix = suffix;
}
public void setInitial(final int initial) {
this.initial = initial;
}
public synchronized String getSequence() {
StringBuffer sb = new StringBuffer();
sb.append(prefix);
sb.append(initial + counter++);
sb.append(suffix);
return sb.toString();
}
}
Class Main
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Main {
/**
* @param args
*/
public static void main(String[] args) {
ApplicationContext context =
new ClassPathXmlApplicationContext("/META-INF/spring/spring-config.xml");
SequenceGenerator generator = (SequenceGenerator)context.getBean("sequenceGenerator");
System.out.println(generator.getSequence());
}
}
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">
<bean id="sequenceGenerator"
class="com.moodys.demo.model.SequenceGenerator">
<constructor-arg value="40"/>
<constructor-arg value="B"/>
<constructor-arg value="100"/>
<property name="prefix" value="30"/>
<property name="suffix" value="A"/>
<property name="initial" value="100000"/>
</bean>
</beans>
代码都很简单,不过需要注意的是关于这个配置文件。这里面既设置了constructor injection 又设置了 setter injection方式。 那么Spring会如何执行呢?
首先,因为这里面设置了<constuctor-arg>, Spring首先会调用对应的构造方法来初始化对象(如果没有设置constructor-arg, 那么会调用无参的构造方法)。
然后,因为设置了<property>,那么Spring会接着调用Setter方法来对成员变量来赋值 (如果设置了property,但是没有对应的setter方法,会报错的), 因此如果既设置了constructor-arg, 又设置了property的话,通过构造方法设置的成员变量的值会被Setter复写的。
-------------------------------------------------------------------
这个例子很简单,不过在运行的时候还是遇到了些问题,刚开始没有把com.springsource.org.apache.commons.logging.jar放到build path中,结果显示了一些错误信息... Spring在执行的时候需要写日志,如果没有这个jar包的话,会报找不到LogFactory这个类。
Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/commons/logging/LogFactory
at org.springframework.context.support.AbstractApplicationContext.<init>(AbstractApplicationContext.java:160)
at org.springframework.context.support.AbstractRefreshableApplicationContext.<init>(AbstractRefreshableApplicationContext.java:89)
at org.springframework.context.support.AbstractRefreshableConfigApplicationContext.<init>(AbstractRefreshableConfigApplicationContext.java:59)
at org.springframework.context.support.AbstractXmlApplicationContext.<init>(AbstractXmlApplicationContext.java:61)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:136)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:83)
at com.moodys.demo.Main.main(Main.java:28)