【SSH快速进阶】——Spring IOC容器注入的几种方式

简介:   **IOC(Inversion of Control)**:控制反转,怎么理解这句话呢?看一个例子就明白了。  一个操作用户的Dao层接口UserDao :

  **IOC(Inversion of Control)**:控制反转,怎么理解这句话呢?看一个例子就明白了。

  一个操作用户的Dao层接口UserDao :


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


  UserDao 的两个实现类(Oracle版本和MySql版本):

public class UserDao4OracleImpl implements UserDao{
  @Override
  public void addUser(String username, String password) {
    System.out.println("UserDao4Oracle实现添加用户");
  }
}


public class UserDao4MySqlImpl implements UserDao {
  @Override
  public void addUser(String username, String password) {
    System.out.println("UserDao4MySqlImpl实现添加用户");
  }
}


  在Service的实现类中调用UserDao接口时,需要手动new实现该接口的实现类:


public class UserManagerImpl implements UserManager{
  @Override
  public void addUser(String username, String password) {
    //由应用程序自己来负责服务(对象)定位
    UserDao userDao =new UserDao4MySqlImpl();
    userDao.addUser("DannyHoo", "123456");
  }
}


 在上面的代码看出来,在使用userDao接口时,需要在这里主动找mysql的实现类UserDao4MySqlImpl,而IOC的工作就是自动为我们实例化。


 控制反转的意思在这里就体现出来了,把原本由程序管理Bean的工作(实例化、各种依赖引用等)反交给IOC容器来做。


 利用IOC容器来为我们管理Bean的方式有多种:



1、构造方法注入


 在需要注入的Service实现类中添加userDao的引用,一个构造方法,参数为需要注入的userDao:


public class UserManagerImpl implements UserManager{
  //用构造方法构造UserDao,不依赖具体实现
  private UserDao userDao;
  //如果有多个依赖,构造方法可以配置多个参数
  public UserManagerImpl(UserDao userDao){
    this.userDao=userDao;
  }
  @Override
  public void addUser(String username, String password){
    userDao.addUser(username,password);
  }
}


  上面用构造方法构造UserDao,不依赖具体实现。

  在Spring配置文件中的配置如下


<bean id="userDao4MySql" class="com.danny.spring.dao.UserDao4MySqlImpl"></bean>
<bean id="userDao4Oracle" class="com.danny.spring.dao.UserDao4OracleImpl"></bean>
<bean id="userManager" class="com.danny.spring.manager.UserManagerImpl">
  <!-- 依赖查找,可以构造多个参数依赖,顺序随意 -->
  <constructor-arg ref="userDao4MySql"/>
</bean>  


2、Setter注入


  Setter注入就是用Setter方法代替了上面的构造方法,IOC容器利用Setter方法来给需要注入的引用赋值。这是最常用的方式。


  添加Setter 方法:


public class UserManagerImpl implements UserManager{
  private UserDao userDao;
  //setter注入
  public void setUserDao(UserDao userDao) {
    this.userDao = userDao;
  }
  @Override
  public void addUser(String username, String password) {
    userDao.addUser(username,password);
  }
}

  在Spring配置文件中的配置如下


<bean id="userDao4MySql" class="com.danny.spring.dao.UserDao4MySqlImpl"></bean>
<bean id="userDao4Oracle" class="com.danny.spring.dao.UserDao4OracleImpl"></bean>
<bean id="userManager" class="com.danny.spring.manager.UserManagerImpl">
  <property name="userDao" ref="userDao4MySql"/>
</bean> 


3、静态工厂注入


  当我们通过静态工厂来获取Dao的实例时,比如再添加一个UserDaoFactory


public class UserDaoFactory {
  //生产UserDao4MySqlImpl实例
  public static final UserDao4MySqlImpl getUserDao4MySqlImpl(){
    return new UserDao4MySqlImpl();
  }
  //生产UserDao4OracleImpl实例
  public static final UserDao4OracleImpl getUserDao4OracleImpl(){
    return new UserDao4OracleImpl();
  }
}


  UserManagerImpl中的代码还跟Setter注入的代码一样:


public class UserManagerImpl implements UserManager{
  private UserDao userDao;
  //setter注入
  public void setUserDao(UserDao userDao) {
    this.userDao = userDao;
  }
  @Override
  public void addUser(String username, String password) {
    userDao.addUser(username,password);
  }
}


  但是配置文件不一样:


<bean id="userDao4MySql" class="com.danny.spring.dao.UserDaoFactory" factory-method="getUserDao4MySqlImpl"/>
<bean id="userDao4Oracle" class="com.danny.spring.dao.UserDaoFactory" factory-method="getUserDao4OracleImpl"/>
<bean id="userManager" class="com.danny.spring.manager.UserManagerImpl">
    <property name="userDao" ref="userDao4MySql"/>
</bean> 

 上面配置文件中,userManager的注入的参数仍然是userDao,ref是userDao4MySql或userDao4Oracle,userDao4MySql和userDao4Oracle,他们的的class不再指向自己,而是指向生产他们的静态工厂,factory-method则是生产他们的方法。


相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。 &nbsp; 相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情:&nbsp;https://www.aliyun.com/product/rds/mysql&nbsp;
相关文章
|
XML Java 测试技术
《深入理解Spring》:IoC容器核心原理与实战
Spring IoC通过控制反转与依赖注入实现对象间的解耦,由容器统一管理Bean的生命周期与依赖关系。支持XML、注解和Java配置三种方式,结合作用域、条件化配置与循环依赖处理等机制,提升应用的可维护性与可测试性,是现代Java开发的核心基石。
|
Java Spring
在使用Spring的`@Value`注解注入属性值时,有一些特殊字符需要注意
【10月更文挑战第9天】在使用Spring的`@Value`注解注入属性值时,需注意一些特殊字符的正确处理方法,包括空格、引号、反斜杠、新行、制表符、逗号、大括号、$、百分号及其他特殊字符。通过适当包裹或转义,确保这些字符能被正确解析和注入。
1196 3
|
Java 测试技术 程序员
为什么Spring不推荐@Autowired用于字段注入?
作为Java程序员,Spring框架在日常开发中使用频繁,其依赖注入机制带来了极大的便利。然而,尽管@Autowired注解简化了依赖注入,Spring官方却不推荐在字段上使用它。本文将探讨字段注入的现状及其存在的问题,如难以进行单元测试、违反单一职责原则及易引发NPE等,并介绍为何Spring推荐构造器注入,包括增强代码可读性和维护性、方便单元测试以及避免NPE等问题。通过示例代码展示如何将字段注入重构为构造器注入,提高代码质量。
827 1
|
XML Java 数据格式
Spring IoC容器的设计与实现
Spring 是一个功能强大且模块化的 Java 开发框架,其核心架构围绕 IoC 容器、AOP、数据访问与集成、Web 层支持等展开。其中,`BeanFactory` 和 `ApplicationContext` 是 Spring 容器的核心组件,分别定位为基础容器和高级容器,前者提供轻量级的 Bean 管理,后者扩展了事件发布、国际化等功能。
526 18
|
XML Java 数据格式
京东一面:spring ioc容器本质是什么? ioc容器启动的步骤有哪些?
京东一面:spring ioc容器本质是什么? ioc容器启动的步骤有哪些?
|
Java Spring
一键注入 Spring 成员变量,顺序编程
介绍了一款针对Spring框架开发的插件,旨在解决开发中频繁滚动查找成员变量注入位置的问题。通过一键操作(如Ctrl+1),该插件可自动在类顶部添加`@Autowired`注解及其成员变量声明,同时保持光标位置不变,有效提升开发效率和代码编写流畅度。适用于IntelliJ IDEA 2023及以上版本。
394 2
一键注入 Spring 成员变量,顺序编程
|
前端开发 Java Docker
使用Docker容器化部署Spring Boot应用程序
使用Docker容器化部署Spring Boot应用程序
|
Java Docker 微服务
利用Docker容器化部署Spring Boot应用
利用Docker容器化部署Spring Boot应用
506 0
|
XML Java 数据格式
Spring IOC容器的深度解析及实战应用
【10月更文挑战第14天】在软件工程中,随着系统规模的扩大,对象间的依赖关系变得越来越复杂,这导致了系统的高耦合度,增加了开发和维护的难度。为解决这一问题,Michael Mattson在1996年提出了IOC(Inversion of Control,控制反转)理论,旨在降低对象间的耦合度,提高系统的灵活性和可维护性。Spring框架正是基于这一理论,通过IOC容器实现了对象间的依赖注入和生命周期管理。
431 0
|
Linux 网络安全 Docker
盘古栈云,创建带ssh服务的linux容器
创建带ssh服务的linux容器
607 146