Spring源码解析-spring ioc容器

很多人一提ioc,便张口就来:控制反转。究竟哪些方面被反转了呢?答案是依赖对象的获得被反转了。很多时候,我们通过多个对象之间的协作来完成一个功能,如果获取所依赖对象靠自身来实现,这将导致代码的耦合度高和难以测试。当然,控制反转还有一个好听的名字:依赖注入。

IOC(Inverse of Control):

在每个框架的中都有一个容器的概念,所谓的容器就是将常用的服务,封装起来,然后,用户只需要遵循一定的规则,就可以达到统一、灵活、安全、方便、快速的目的。

IOC是一个依赖注入DI(Dependence Injection)的方式达到控制反转目的的框架。

控制反转:的优势在于将服务交给容器。

我们对比一下由我们的应用程序负责服务(对象)定位:

public class UserManagerImpl implements UserManager {  
   public void addUser(String username, String password) {  
   //由我们的应用程序负责服务(对象)定位  
   //UserDao userDao = new UserDao4MySqlImpl();  
   UserDao userDao = new UserDao4OracleImpl();  
   userDao.addUser(username, password);   
   }  
}  
public class UserManagerImpl implements UserManager {     
    private UserDao userDao;      
    public void addUser(String username, String password) {  
        userDao.addUser(username, password);  
    }  
    public void setUserDao(UserDao userDao) {  
        this.userDao = userDao;  
    }  
}  

 在spring ioc中有三种依赖注入,分别是:

  • a、接口注入;
  • b、setter方法注入;
  • c、构造方法注入;

 setter方法注入

setter注入模式在实际开发中有非常广泛的应用,setter方法更加直观,我们来看一下spring的配置文件

扫描二维码关注公众号,回复: 280684 查看本文章
<?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:aop="http://www.springframework.org/schema/aop"    
         xmlns:tx="http://www.springframework.org/schema/tx"    
         xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd    
           http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.1.xsd    
           http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.1.xsd">    
    
    <!-- 使用spring管理对象的创建,还有对象的依赖关系 -->    
    <bean id="userDao4Mysql" class="com.tgb.spring.dao.UserDao4MysqlImpl"/>    
    
    <bean id="userDao4Oracle" class="com.tgb.spring.dao.UserDao4OracleImpl"/>    
        
    <bean id="userManager" class="com.tgb.spring.manager.UserManagerImpl">    
        <!-- (1)userManager使用了userDao,Ioc是自动创建相应的UserDao实现,都是由容器管理-->    
        <!-- (2)在UserManager中提供构造函数,让spring将UserDao实现注入(DI)过来 -->    
        <!-- (3)让spring管理我们对象的创建和依赖关系,必须将依赖关系配置到spring的核心配置文件中 -->    
    
        <property name="userDao" ref="userDao4Oracle"></property>    
    </bean>    
        
</beans>  

接着我们来看一下,setter表示依赖关系的写法

public class UserManagerImpl implements UserManager{      
    private UserDao userDao;    
    //使用设值方式赋值    
    public void setUserDao(UserDao userDao) {    
        this.userDao = userDao;    
    }         
    @Override    
    public void addUser(String userName, String password) {    
        userDao.addUser(userName, password);    
    }    
}    

 构造器注入

 

构造器注入,即通过构造函数完成依赖关系的设定。我们看一下spring的配置文件:

<?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:aop="http://www.springframework.org/schema/aop"    
             xmlns:tx="http://www.springframework.org/schema/tx"    
             xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd    
               http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.1.xsd    
               http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.1.xsd">    
        
        <!-- 使用spring管理对象的创建,还有对象的依赖关系 -->    
        <bean id="userDao4Mysql" class="com.tgb.spring.dao.UserDao4MysqlImpl"/>    
        
        <bean id="userDao4Oracle" class="com.tgb.spring.dao.UserDao4OracleImpl"/>    
            
        <bean id="userManager" class="com.tgb.spring.manager.UserManagerImpl">    
            <!-- (1)userManager使用了userDao,Ioc是自动创建相应的UserDao实现,都是由容器管理-->    
            <!-- (2)在UserManager中提供构造函数,让spring将UserDao实现注入(DI)过来 -->    
            <!-- (3)让spring管理我们对象的创建和依赖关系,必须将依赖关系配置到spring的核心配置文件中 -->    
        
            <constructor-arg ref="userDao4Oracle"/>    
        </bean>    
            
    </beans>    

 我们再来看一下,构造器表示依赖关系的写法,代码如下所示:

 public class UserManagerImpl implements UserManager{    
        
        private UserDao userDao;    
        
        //使用构造方式赋值    
        public UserManagerImpl(UserDao userDao) {    
            this.userDao = userDao;    
        }    
        
        @Override    
        public void addUser(String userName, String password) {    
        
            userDao.addUser(userName, password);    
        }    
    }    

  spring ioc通过引入xml配置,由ioc容器来管理对象的生命周期,依赖关系等。

             
 

它的加载过程是什么样的呢?

         
 

         BeanDefinition是一个接口,用于属性承载,比如<bean>元素标签拥有class、scope、lazy-init等配置。bean的定义方式有千千万万种,无论是何种标签,无论是何种资源定义,无论是何种容器,只要按照spring的规范编写xml配置文件,最终的bean定义内部表示都将转换为内部的唯一结构:BeanDefinition。当BeanDefinition注册完毕以后,spring的BeanFactory就可以随时根据需要进行实例化了。

猜你喜欢

转载自sunwonder.iteye.com/blog/2398240