依赖注入的实现方式:设值注入和构造方法注入

Posted 爱上漫天繁星

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了依赖注入的实现方式:设值注入和构造方法注入相关的知识,希望对你有一定的参考价值。

      SSH开发时,一般将项目分成3层:web层、service层和dao层。开发的基本流程是先定义dao接口,然后实现该接口,在定义同类型的service接口,再实现service接口(此时使用dao接口注入),接着再从web层去调用service层。

      dao层完成的是底层的数据库操作,service层则完成纯粹的业务逻辑,该层中的数据操作部分是通过注入的dao层来实现的。service层的作用是将从dao层取得的数据做更贴近业务的实现,dao层则只实现对数据的增、删、改、查操作。使用这种分层方式更有利于项目的扩展和维护。

一、设值注入

      设值注入是指IoC容器使用setter方法注入被依赖的实例。通过调用无参构造器或无参static工厂方法实例化bean之后,调用该bean的setter方法,即可实现基于setter的DI。

  1.  新建项目,配置运行环境(Build Path中加入spring和其它依赖的jar包)
  2. User类,作为被保存的模型对象
    package com.deciphering.model;
    
    public class User {
        private String username;
        private String password;
        
        public String getUsername() {
            return username;
        }
        public void setUsername(String username) {
            this.username = username;
        }
        public String getPassword() {
            return password;
        }
        public void setPassword(String password) {
            this.password = password;
        }
    }
    User.java
  3. User类的接口UserDAO(针对接口编程的好处是UserDAO可以有多个不同的实现类,分别用来操作不同的数据库)
    package com.deciphering.dao;
    import com.deciphering.model.User;
    
    
    public interface UserDAO {
        public void save(User user);
    }
    UserDAO
  4. UserDAO的实现类UserDAOImpl(简化处理)
    package com.deciphering.dao.impl;
    
    import com.deciphering.dao.UserDAO;
    import com.deciphering.model.User;
    
    
    public class UserDAOImpl implements UserDAO {
    
        public void save(User user) {
            
            System.out.println(user.getUsername() + " saved in Oracle!");        
            //System.out.println(user.getUsername() + " saved in DB2!");        
            //System.out.println(user.getUsername() + " saved in mysql!");
            
        }
    
    }
    UserDAOImpl
  5. 业务逻辑接口UserService
    package com.deciphering.service;
    import com.deciphering.dao.UserDAO;
    import com.deciphering.model.User;
    
    public class UserServiceImpl {
        
        private UserDAO userDAO;  
        
        public void add(User user) {
            userDAO.save(user);
        }
        public UserDAO getUserDAO() {
            return userDAO;
        }
        public void setUserDAO(UserDAO userDAO) {
            this.userDAO = userDAO;
        }
    /*    public UserServiceImpl(UserDAO userDAO) {
            super();
            this.userDAO = userDAO;
        }
        */
    }
    UserService 
  6. 业务逻辑接口的实现类UserServiceImpl
    package com.deciphering.service;
    import com.deciphering.dao.UserDAO;
    import com.deciphering.model.User;
    
    public class UserServiceImpl implements UserService{
        
        private UserDAO userDAO;  
        
        public void add(User user){
            userDAO.save(user);
        }
        public UserDAO getUserDAO() {
            return userDAO;
        }
        public void setUserDAO(UserDAO userDAO) {
            this.userDAO = userDAO;
        }
        
    }
  7. Spring的配置文件beans.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.5.xsd">
               
      <bean id="u" class="com.deciphering.dao.impl.UserDAOImpl">
      </bean>
        
      <bean id="userService" class="com.deciphering.service.UserServiceImpl">     
           <property name="userDAO">
               <ref bean="u"/>
           </property> 
              
      </bean>
    </beans>
  8. 测试类
    Test
    package com.deciphering.service;
    import org.junit.Test;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    import com.deciphering.model.User;
    import com.deciphering.service.UserServiceImpl;
    
    public class UserServiceTest {
    
        @Test
        public void testAdd() throws Exception {
            
            ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
            UserServiceImpl service = (UserServiceImpl)ctx.getBean("userService");
        
            User u = new User();
            
            u.setUsername("测试用户");
            u.setPassword("123456");
            
            service.add(u);
        }
        
    }

     

二、构造方法注入

      构造方法注入是指IoC容器使用构造方法来注入被依赖的实例。基于构造器的DI通过调用带参数的构造方法来实现,每个参数代表着一个依赖。

      在上面的项目文件里,做少量的修改,即可变为构造方法注入。

  1. 修改UserServiceImpl类,在使用构造方法注入时,必须显式的给出待参数的构造方法。
    package com.deciphering.service;
    import com.deciphering.dao.UserDAO;
    import com.deciphering.model.User;
    
    public class UserServiceImpl {
        
        private UserDAO userDAO;  
        
        public void add(User user) {
            userDAO.save(user);
        }
        public UserDAO getUserDAO() {
            return userDAO;
        }
        public void setUserDAO(UserDAO userDAO) {
            this.userDAO = userDAO;
        }
    //定义构造方法
        public UserServiceImpl(UserDAO userDAO) {
            super();
            this.userDAO = userDAO;
        }
        
    }
  2. 修改beans.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.5.xsd">
               
      <bean id="u" class="com.deciphering.dao.impl.UserDAOImpl">
      </bean>
        
      <bean id="userService" class="com.deciphering.service.UserServiceImpl">
            <!--
           <property name="userDAO">
               <ref bean="u"/>
           </property> 
           -->
     //使用构造方法注入,为UserService实例注入u实例     
           <constructor-arg>
               <ref bean="u"/>
           </constructor-arg>
           
           
      </bean>
     
    </beans>

    文件结构:

       

以上是关于依赖注入的实现方式:设值注入和构造方法注入的主要内容,如果未能解决你的问题,请参考以下文章

Ioc和AOP使用扩展

Java Spring学习笔记----Bean的依赖注入

应届生应聘阿里,字节跳动必须知道Spring 依赖注入!你还没掌握吗?

构造方法注入和设值注入有什么区别

依赖注入DI

Spring4--课程笔记4