Helloworld之Spring依赖注入/控制反转(DI/IoC)版
作者:雨水, 日期:2014-10-29
摘要:本文主要用于培训初学者理解Spring中的依赖注入的基本概念. 先介绍依赖注入的基本概念,然后以构造器注入为例实现了Helloworld实例。
Spring依赖注入/控制反转
在我们通常的编程中,如果类A要依赖类B,通常是由A来创建一个B的实例。而Spring将创建B的实例的工作交给Spring容器来完成,然后注入A,因此称为依赖注入(DI, Dependency Injection)。这种创建被调用者的工作不再由调用者来完成,因此又称为控制反转(IoC, Inversion of Control)。
依赖注入将Bean以文件的形式组织在一起,降低了程序的耦合性。实例之间的依赖关系由IoC容器负责管理。
依赖注入Helloworld实例
依赖注入的方式有多种,比如构造器注入,设值注入等,这里以构造器注入为例。
第一步:搭建Spring环境
通过直接下载jar包加入工程或者通过Maven/Gradle来引入Spring的依赖jar包. 具体参考: http://spring.io/
第二步:编写具体类
1. 定义接口类MessageService.java
package cn.dennishucd; public interface MessageService { public String getMessage(); }
2. 编写接口的实现类MessageServiceImpl.java
package cn.dennishucd; public class MessageServiceImpl implements MessageService { @Override public String getMessage() { return "Hello World!"; } }
3. 编写服务消费类MessagePrinter.java
package cn.dennishucd; public class MessagePrinter { final private MessageService service; public MessagePrinter(MessageService service) { this.service = service; } public void printMessage() { System.out.println(this.service.getMessage()); } }
4. 编写主程序类HelloworldSpring.java
package cn.dennishucd; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class HelloworldSpring { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("helloworld.xml"); MessagePrinter printer = (MessagePrinter) context.getBean("printer"); printer.printMessage(); ((ClassPathXmlApplicationContext)context).close(); } }
第三步:编写spring配置文件
文件名可以任意,这里命名为helloworld.xml,该文件放在src的根目录下。
<?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="service" class="cn.dennishucd.MessageServiceImpl"/> <bean id="printer" class="cn.dennishucd.MessagePrinter"> <constructor-arg ref="service"/> </bean> </beans>
第四步:运行程序
运行程序,显示:"Hello World!"
程序解释:
(1) MessagePrinter要使用MessageService获取消息的服务,它并不是直接在该类中new一个MessageService的具体实现类,而是提供一个注入接口,即这里的构造注入。
(2) 具体注入哪个MessageService的实现可以在spring的配置文件中进行配置,即通过<constructor-arg ref="service"/>来指定。并且这个具体实现类的实例化也由Spring的容器来实现。
(3) 这里只是一个hello的消息服务例子,想象一下如果是用做系统的数据访问服务。数据访问服务的消费者只需要定义一个接口并提供注入方式,具体使用什么样的数据访问实现就可以在配置文件中进行配置。如果系统需要更换数据访问实现,只需要修改配置文件中要注入的具体数据访问实现即可。这样实现了面向接口编程的松耦合。
(4) 主程序创建了一个Spring应用上下文,直接从应用上下文中获取到MessagePrinter消费者的实例,然后调用相应的方法。
参考资料:
1. http://spring.io/ Spring官网
1. http://www.cnblogs.com/linjiqin/archive/2013/11/04/3407126.html Spring IOC容器基本原理
2. http://blog.csdn.net/a906998248/article/details/7514085 Spring 的核心机制:依赖注入(控制反转)
3. http://outofmemory.cn/code-snippet/3670/spring-inject-by-annotation Spring依赖注入:注解注入总结
4. http://www.yiibai.com/spring/spring_hello_world_example.html Spring Hello World 实例