Spring Framework源代码解析之IOC容器(一)
2012-05-21 11:56
435 查看
序
最近开始写博客,觉得这样对自己很有好处,可以从头到尾把散乱的知识梳理一遍,通过自己的理解把它写下了,这个过程受益匪浅。今天写Spring的随笔,使用Spring大概有3年时间,可大多时候只是使用它的特性,并没有深入学习它。Spring的源码据网友说写的很漂亮,我也来学习一下。
IOC之HelloWorld
假设我们有这样一个业务,根据产品的ID,从产品库中取得该产品的详细信息。用户接口可能是Web浏览器、桌面软件或者超市的条形码扫描器,总之会用一个类来接受用户请求,我们暂且定名为ProductAction.java.
而具体处理逻辑则是放在产品服务接口中,ProductService.java。该接口有一个实现类ProductServiceImpl.java,具体实现写在ProductServiceImpl.java中。代码如下:
ProductService.java
ProductServiceImpl.java
Product.java
ProductAction. java
Spring配置文件
这样就可以实现往ProductAction类中注入指定的ProductService,而具体业务的交给了ProductServiceImpl处理。
何为IOC?
从上例可以看出,通过Spring的IOC特性,将ProductService具体的实现类注入到ProductAction中,从而ProductAction可以调用ProductService的方法进行逻辑处理。在没有使用Spring的情况下,要完成以上功能,也可以通过new关键字,将ProductSerivce接口的实现类实例化出来。但他们的区别在哪里呢?当使用new关键字实例化对象时,ProductAction类对ProductService实现类的实例化具有控制权;而使用Spring IOC时,ProductAction和ProductService之间的关系则通过Spring来配置(通过注解或者XML配置文件),而对ProductService的控制权由ProductAction转移到了Spring IOC容器上,这就是所谓的控制反转。IOC特性的直接用处就是解耦,在ProductAction中,我们并没有看到对ProductService实现类的依赖,而它们之间的依赖关系则是通过第三方(Spring IOC)来维护。
IOC工作流程
Step1:系统运行时,Spring开始启动,指定将加载的配置文件。
应用程序:
Web应用:
web.xml
Step2:接着AbstractApplicationContext类开始调用prepareRefresh方法,对ApplicationContext进行刷新。
Step3:XmlBeanDefinitionReader类调用loadBeanDefinitions方法进行配置文件加载,配置文件中定义的Java Bean会被加载在IOC容器的一个HashMap当中。HashMap的key就是Bean的id,HasMap的value就是这个Java Bean。(当中详细过程分为定位、载入、注册,我们后面再详细说明)
Step4:依赖注入,当用户向IOC容器索要Bean时,将触发BeanFactory中的getBean方法,当然不同类型的配置会调用不同的BeanFactory,如XmlBeanFactory。从而得到相应的JavaBean。
小结
上面简要介绍了Spring IOC的特性,对IOC的理解,IOC容器的大致工作流程,下文将依据上述流程详细解析IOC容器的实现。
最近开始写博客,觉得这样对自己很有好处,可以从头到尾把散乱的知识梳理一遍,通过自己的理解把它写下了,这个过程受益匪浅。今天写Spring的随笔,使用Spring大概有3年时间,可大多时候只是使用它的特性,并没有深入学习它。Spring的源码据网友说写的很漂亮,我也来学习一下。
IOC之HelloWorld
假设我们有这样一个业务,根据产品的ID,从产品库中取得该产品的详细信息。用户接口可能是Web浏览器、桌面软件或者超市的条形码扫描器,总之会用一个类来接受用户请求,我们暂且定名为ProductAction.java.
而具体处理逻辑则是放在产品服务接口中,ProductService.java。该接口有一个实现类ProductServiceImpl.java,具体实现写在ProductServiceImpl.java中。代码如下:
ProductService.java
public interface ProductService { /** * @Title: getProduct * @Description: 根据ID获取产品信息 * @param id * @return Product * * @throws */ Product getProduct(String id); }
ProductServiceImpl.java
@Service("productService") public class ProductServiceImpl implements ProductService { /* (non-Javadoc) * @see com.cnblogs.leefreeman.domain.service.ProductService#getProduct(java.lang.String) */ @Override public Product getProduct(String id) { // TODO 此处编写取得产品详细信息的逻辑 return null; } }
Product.java
public class Product { /** * id */ private String id; /** * 名称 */ private String name; /** * 生产日期 */ private Date productionDate; /** * 保质期 */ private Date shelfLife; /** * @return the id */ public String getId() { return id; } /** * @param id * the id to set */ public void setId(String id) { this.id = id; } /** * @return the name */ public String getName() { return name; } /** * @param name * the name to set */ public void setName(String name) { this.name = name; } /** * @return the productionDate */ public Date getProductionDate() { return productionDate; } /** * @param productionDate * the productionDate to set */ public void setProductionDate(Date productionDate) { this.productionDate = productionDate; } /** * @return the shelfLife */ public Date getShelfLife() { return shelfLife; } /** * @param shelfLife * the shelfLife to set */ public void setShelfLife(Date shelfLife) { this.shelfLife = shelfLife; } }
ProductAction. java
public class ProductAction { /** * 注入ProductServiceImpl.java */ @Resource(name = "productService") private ProductService productService; public Product getProductById(String id) { Product product = productService.getProduct(id); return product; } }
Spring配置文件
<?xml version="1.0" encoding="UTF-8"?> <?XML:NAMESPACE PREFIX = [default] http://www.springframework.org/schema/beans NS = "http://www.springframework.org/schema/beans" /><?XML:NAMESPACE PREFIX = [default] http://www.springframework.org/schema/beans NS = "http://www.springframework.org/schema/beans" /> <?xml:namespace prefix = context />
这样就可以实现往ProductAction类中注入指定的ProductService,而具体业务的交给了ProductServiceImpl处理。
何为IOC?
从上例可以看出,通过Spring的IOC特性,将ProductService具体的实现类注入到ProductAction中,从而ProductAction可以调用ProductService的方法进行逻辑处理。在没有使用Spring的情况下,要完成以上功能,也可以通过new关键字,将ProductSerivce接口的实现类实例化出来。但他们的区别在哪里呢?当使用new关键字实例化对象时,ProductAction类对ProductService实现类的实例化具有控制权;而使用Spring IOC时,ProductAction和ProductService之间的关系则通过Spring来配置(通过注解或者XML配置文件),而对ProductService的控制权由ProductAction转移到了Spring IOC容器上,这就是所谓的控制反转。IOC特性的直接用处就是解耦,在ProductAction中,我们并没有看到对ProductService实现类的依赖,而它们之间的依赖关系则是通过第三方(Spring IOC)来维护。
IOC工作流程
Step1:系统运行时,Spring开始启动,指定将加载的配置文件。
应用程序:
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("application-context.xml");
Web应用:
web.xml
contextConfigLocation classpath:spring-hibernate-mysql.xml org.springframework.web.context.ContextLoaderListener
Step2:接着AbstractApplicationContext类开始调用prepareRefresh方法,对ApplicationContext进行刷新。
Step3:XmlBeanDefinitionReader类调用loadBeanDefinitions方法进行配置文件加载,配置文件中定义的Java Bean会被加载在IOC容器的一个HashMap当中。HashMap的key就是Bean的id,HasMap的value就是这个Java Bean。(当中详细过程分为定位、载入、注册,我们后面再详细说明)
Step4:依赖注入,当用户向IOC容器索要Bean时,将触发BeanFactory中的getBean方法,当然不同类型的配置会调用不同的BeanFactory,如XmlBeanFactory。从而得到相应的JavaBean。
小结
上面简要介绍了Spring IOC的特性,对IOC的理解,IOC容器的大致工作流程,下文将依据上述流程详细解析IOC容器的实现。
相关文章推荐
- Spring源代码解析第一篇(IOC容器)
- Spring源代码解析(二):IoC容器在Web容器中的启动
- IOC容器注解方式详细解析
- spring ioc容器的学习笔记5---ApplicatonContext ioc容器的应用场景和简单设计原理解析
- Spring源码解读-Spring IoC容器初始化之资源解析
- 《Spring技术内幕》学习笔记4——IoC容器解析Bean定义资源并注册解析后的Bean
- SPRING原理解析-Ioc容器初始化
- Spring核心容器的详细解析以及IOC和DI和过程全解
- Spring IoC容器和AOP解析
- spring中IOC容器注解方式详细解析
- Spring源代码解析(一):IOC容器
- Spring源代码解析(二):IoC容器在Web容器中的启动
- 《深入解析Spring架构与设计原理》阅读笔记(一)----IOC容器的设计与实现
- Spring源码-IOC容器(十)-@Autowired解析
- Spring源码解析三:IOC容器的依赖注入
- Spring源代码解析(一):IOC容器
- Spring源代码解析(一):IOC容器:http://www.javaeye.com/topic/86339
- Spring之IoC容器解析(一)
- Spring IoC容器之BeanFactory底层实现代码解析(一)
- Spring源代码解析(一):IOC容器