依赖注入(DI)是spring的核心。下面让我们看看spring的HelloWorld程序应该怎么来编写。
首先需要创建一个服务类来打印问候信息。创建GreetingService接口来定义该行为:
package com.springtest.helloworld;
public interface GreetingService {
void sayGreeting();
}
然后创建具体的类来实现该接口
package com.springtest.helloworld;
public class GreetingSerivceImpl implements GreetingService {
private String greeting;
public GreetingSerivceImpl() {}
public GreetingSerivceImpl(String greeting) {
this.greeting = greeting;
}
public void setGreeting(String greeting) {
this.greeting = greeting;
}
/* (non-Javadoc)
* @see com.springtest.helloworld.GreetingService#sayGreeting()
*/
@Override
public void sayGreeting() {
// TODO Auto-generated method stub
System.out.println(greeting);
}
}
GreetingServiceImpl类有一个属性:greeting。greeting这个属性有两种赋值方式:构造函数和setter方法。现在的问题是:谁来调用构造函数或setter方法对greeting进行赋值?如前所述,是有spring容器来对greeting进行赋值。Spring配置文件(.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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
<bean id="greetingService"
class="com.springtest.helloworld.GreetingServiceImpl">
<property name="greeting" value="hello, spring"/>
</bean>
</beans>
上述xml文件在spring容器中声明了一个GreetingServiceImpl的实例,并且将属性greeting的值设置为”hello, spring”。xml文件中的beans标签是spring配置文件的根节点,而bean元素通常表示一个类并且负责对类进行配置。在bean元素下,元素property表示一个属性,它告诉spring容器去调用相应的setter方法,并传递给其value值。下面的代码简要地说明了spring使用xml配置文件来实例化greeting 服务时所对应的java代码:
GreetingServiceImpl greetingService = new GreetingServiceImpl();
greetingService.setGreeting("hello, spring");
同样地,spring可以通过GreetingServiceImpl的构造函数来设置greeting属性。比如,
<bean id="greetingService"
class="com.springtest.helloworld.GreetingServiceImpl">
<constructor-arg value="hello, spring"/>
</bean>
下面的代码说明了spring使用构造函数来实例化greeting 服务时所对应的java代码:
GreetingServiceImpl greetingService =
new GreetingServiceImpl("hello, spring");
最后列出用于加载spring容器并获得greeting服务的类代码:
package com.springtest.helloworld;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.FileSystemResource;
public class HelloApp {
public static void main(String[] args) {
BeanFactory factory = new
XmlBeanFactory(new FileSystemResource("hello.xml"));
GreetingService greetingService =
(GreetingService)factory.getBean("greetingService");
greetingService.sayGreeting();
}
}
代码中的BeanFactory就是spring容器。需要注意的,若要保证上述代码可以正确运行,需要把hello.xml放到工程目录下面。另外,需下载commons-logging-1.1.1.jar并将其加入到工程build path下面。
综合来看,spring的HelloWorld例子有个很明显的特点:在main方法中我们没有显式地实例化服务类,而是通过BeanFactory实例化配置文件(.xml)通过spring容器来进行实例化,而在main方法中只是针对接口编程,这就是DI的工作原理。