Spring核心(三)IoC使用

本文介绍Spring框架中IOC容器的概念及其两种实现方法:setter方法注入和构造器注入,并通过示例展示了如何利用Spring实现对象间的解耦。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

       

        上篇文章介绍了Ioc和他的作用,简单的来讲,就是由容器控制程序之间的关系,而不是由我们手动编写控制实现中,由程序代码直接操控。这也就是所谓“控制反转”的概念所在:控制权由应用代码中转到了外部容器,控制权的转移,是所谓反转 

        下面通过添加用户的小例子具体来看,首先配置Spring的环境

        1、加入spring的依赖包

             (1).SPRING_HOME/dist/spring.jar

             (2).SPRING_HOME/lib/log4j/log4j-1.2.14.jar

             (3).SPRING_HOME/lib/jakarta-commons/commons-logging.jar     

        2、提供spring配置文件applicationContext.xml,一个典型的Spring项目需要创建一个或多个Bean配置文件,这些配置文件用于在Spring IOC容器里配置Bean,这个配置文件最好放在classpath目录下。

        3、提供log4j.properties配置文件

 

创建项目,写Dao层接口IUserDao.java

public interface IUserDao {
          public void InsertUser(String username,String password);
}

Dao接口的实现类 UserDaoImpl.java

public class UserDaoImpl implements IUserDao{
         @Override
         public void InsertUser(String username, String password){             
              System.out.println("----UserDaoImpl --addUser----");
         }
 }


业务层接口IUserManager.java

public interface IUserManager {
          public void addUser(String username,String password);
}

业务层接口的实现UserManagerImpl.java

public class UserManagerImpl implements IUserManager {
      private IUserDao  userDao;
      @Override
      public void addUser(String username, String password) {                
            userDao=new IUserDaoImpl();
            userDao.InsertUser(username,password);
      }
 }

其实从这里就可以看出,业务层其实也是依赖了Dao层的具体实现,没有起到解耦的作用。

 

   Client.java

public classClient {
    public static void main(String[] args) { 
        IUserManager usermanager=new UserManagerImpl();
        userManager.addUser("wanghuan","password");
    }
}

       从客户端的代码里,我们也可以看出,跟上篇文章的例子是一样的,客户端也还是依赖于业务层的具体实现。接下来我们使用IOC容器。

       使用IOC容器很简单,就是将我们的对象放到配置文件里,让Spring知道,从而由Spring来帮我们管理。

       Spring 框架的 IOC 容器常用两种方法实现:

         (一)【setter方法注入】:通过 JavaBean的属性分配依赖性。

         (二)【构造器注入】:依赖性以构造函数的形式提供,不以 JavaBean 属性的形式公开。

       首先看setter方法注入,是IOC通过set方法将需要的对象注入。需要提供被注入对象的set方法。

Public  class  UserManagerImpl  implements  UserManager {
    private  IUserDao  userDao;
    //set方法   
    public void  setUserDao(IUserDao  userDao) {
       this.userDao = userDao;
    }
    @Override
    public void addUser(String username, String password) {             
      //不需要实例化,直接可以使用
      userDao.InsertUser(username,password);
  }
}

        重点是配置Spring的核心配置文件applicationContext.xml,在配置文件中配置上userDao的信息,使得IOC容器自己将UserDao对象注入到UserManagerImpl中。

applicationContext.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:aop="http://www.springframework.org/schema/aop"
         xmlns:tx="http://www.springframework.org/schema/tx"
         xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans-2.0.xsd
          http://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop-2.0.xsd
          http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">
<!--id名字自己取,class表示他代表的类,如果在包里的话需要加上包名-->
<bean id="userManager"  class="UserManagerImpl" >
    <!—property代表是通过set方法注入,ref的值表示注入的内容-->
     <property  name="userDao"  ref="userDao"/>     
 </bean>  
<bean id="userDao"  class="UserDaoImpl"/>  
</beans>

        这样我们就可以看出,业务层里只出现了Dao层的接口,是依赖于接口,而没有依赖于真正的实现。客户端对业务层的依赖是同样道理,可以只依赖业务层接口,通过IOC注入解决。

        下面看另一种通过构造器注入。这种方法不需要提供set方法,但需要提供构造方法。看代码:

Public  class  UserManagerImpl  implements  UserManager {
    private  IUserDao  userDao;
    //构造函数
    public  UserManagerImpl(IUserDao  userDao) {
       this.userDao = userDao;
    }  
        @Override
    public void addUser(String username, String password) {             
       userDao.InsertUser(username,password);
    }
}

配置文件也有不同:

applicationContext.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:aop="http://www.springframework.org/schema/aop"
         xmlns:tx="http://www.springframework.org/schema/tx"
         xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans-2.0.xsd
          http://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop-2.0.xsd
          http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">
<bean id="userManager" class="UserManagerImpl" >
    <!—constructor-arg代表是通过构造函数注入,ref的值表示注入的内容-->
    <constructor-arg  ref="userDao "/>     
 </bean>  
<bean id="userDao" class="UserDaoImpl"/>  
</beans>

 

这两种注入方式,在客户端进行调用都是一样的。来看客户端代码:

public  class  Client{
public staticvoidmain(String[] args) { 
      /*这句话就不用出现了
             IUserManager  usermanager=new UserManagerImpl();
      */
       //使用Spring的工厂将ioc容器中的对象取出
       BeanFactory factory=newClassPathXmlApplicationContext("applicationContext.xml");
       //依赖于接口,不会出现具体实现 
       IUserManager userManager=(IUserManager)factory.getBean("userManager");
       userManager.addUser("wanghuan", "password");
    }
}


       上篇文章的解耦过程于上文相同,都是将对象交与IOC容器管理,避免在程序中出现具体实现。通过代码我们可以看出IOC依赖注入的好处:

       1.对象之间的依赖关系,不由对象自身来负责,而是由容器依据配置文件动态建立,这样就很灵活,可配。

       2.采用依赖注入,模块之间一定是松散耦合的

       3.代码易维护易测试

       如果不使用框架,我们传统的写法一般是自己建立工厂或者用单例来处理业务层与Dao层,而使用了Spring,这些工作我们就都不用管了,而且每层的代码都很清楚。这样就使得真正的业务流程更明确了。

评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值