[Spring Framework]DI依赖注入②(自动装配、集合注入)

简介: DI依赖注入②(自动装配、集合注入)

@[TOC]

依赖自动装配

在前文我们所提到的setter注入、构造器注入都需要配置,在我看来是有点麻烦的,为了简化我们的代码、提高我们的效率,我们可以使用依赖自动装配,那么什么是依赖自动装配呢?

==IoC容器根据bean所依赖的资源在容器中自动查找并注入到bean中的过程称为自动装配==

自动装配存在以下几种方式:

  • ==按类型(常用)==
  • 按名称
  • 按构造方法(很少用我们不去了解)
  • 不启用自动装配

接下来我们还是借用前文的工程结构来做两个实验:

在前文中:

我们的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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="bookDao" class="impl.BookDaoImpl"/>
    <bean id="bookService" class="impl.BookServiceImpl">
        <property name="bookDao" ref="bookDao"/>
    </bean>
</beans>

BookServiceImpl类:

public class BookServiceImpl implements BookService {
    private BookDao bookDao;

    public void setBookDao(BookDao bookDao) {
        this.bookDao = bookDao;
    }

    public void save() {
        System.out.println("book service save ...");
        bookDao.save();
    }
}

App:

public class App2 {
    public static void main(String[] args) {
        //获取容器
        ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
        BookService bookService = (BookService) ctx.getBean("bookService");

        bookService.save();
    }
}

接下来我们使用自动装配:

首先我们将<property>标签删除,然后在<bean>标签中添加autowire属性:

<bean id="bookDao" name="bookBookDao" class="impl.BookDaoImpl"/>
<!--autowire属性:开启自动装配,通常使用按类型装配-->
<bean id="bookService" class="impl.BookServiceImpl" scope="prototype" autowire="byType"/>

接下来我们在运行App2,结果正常:
在这里插入图片描述

注意:
①需要注入属性的类中对应属性的setter方法不能省略
②被注入的对象必须要被Spring的IOC容器管理
③按照类型在Spring的IOC容器中如果找到多个对象,会报 NoUniqueBeanDefinitionException

也就是说如果使用byType,那么容器中有且仅有一个bean的类型与之对应,否则就会报错!

那么假如真有两个bean的类型都满足怎么办呢?(当然这种情况很少发生,byType可以放心使用)

我们可以使用:byName

<bean id="bookDao" name="bookBookDao" class="impl.BookDaoImpl"/>
<bean id="bookService" class="impl.BookServiceImpl" scope="prototype" autowire="byName"/>

==注意事项:==

  • 按照名称注入中的名称指的是什么?

    在这里插入图片描述

    • bookDao是private修饰的,外部类无法直接方法
    • 外部类只能通过属性的set方法进行访问
    • 对外部类来说,setBookDao方法名,去掉set后首字母小写是其属性名

      • 为什么是去掉set首字母小写?
      • 这个规则是set方法生成的默认规则,set方法的生成是把属性名首字母大写前面加set形成的方法名
    • ==所以按照名称注入,其实是和对应的set方法有关,但是如果按照标准起名称,属性名和set对应的名是一致的==
  • 如果按照名称去找对应的bean对象,找不到则注入Null
  • 当某一个类型在IOC容器中有多个对象,按照名称注入只找其指定名称对应的bean对象,不会报错

==最后对于依赖注入,需要注意一些其他的配置特征==:

  1. 自动装配用于引用类型依赖注入,不能对简单类型进行操作
  2. 使用按类型装配时(byType)必须保障容器中相同类型的bean唯一,推荐使用
  3. 使用按名称装配时(byName)必须保障容器中具有指定名称的bean,因变量名与配置耦合,不推荐使用
  4. 自动装配优先级低于setter注入与构造器注入,同时出现时自动装配配置失效

集合注入

前面我们已经能完成引入数据类型和简单数据类型的注入,但是还有一种数据类型==集合==,集合中既可以装简单数据类型也可以装引用数据类型,对于集合,在Spring中该如何注入呢?

我们从以下几个方面入手:

  • 数组
  • List
  • Set
  • Map
  • Properties

项目准备:

实现了BookDao接口的BookDaoImpl:

public class BookDaoImpl implements BookDao {
    private int[] array;

    private List<String> list;

    private Set<String> set;

    private Map<String,String> map;

    private Properties properties;

    public void save() {
        System.out.println("book dao save ...");

        System.out.println("遍历数组:" + Arrays.toString(array));

        System.out.println("遍历List" + list);

        System.out.println("遍历Set" + set);

        System.out.println("遍历Map" + map);

        System.out.println("遍历Properties" + properties);
    }

    public void setArray(int[] array) {
        this.array = array;
    }

    public void setList(List<String> list) {
        this.list = list;
    }

    public void setSet(Set<String> set) {
        this.set = set;
    }

    public void setMap(Map<String, String> map) {
        this.map = map;
    }

    public void setProperties(Properties properties) {
        this.properties = properties;
    }
}

App3:

public class AppForDICollection {
    public static void main( String[] args ) {
        ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
        BookDao bookDao = (BookDao) ctx.getBean("bookDao");
        bookDao.save();
    }
}

注入数组类型数据

<property name="array">
    <array>
        <value>100</value>
        <value>200</value>
        <value>300</value>
    </array>
</property>

注入List类型数据

<property name="list">
    <list>
        <value>book</value>
        <value>apple</value>
        <value>fenda</value>
        <value>banana</value>
    </list>
</property>

注入Set类型数据

<property name="set">
    <set>
        <value>cat</value>
        <value>car</value>
        <value>cupple</value>
        <value>cola</value>
    </set>
</property>

注入Map类型数据

<property name="map">
    <map>
        <entry key="country" value="china"/>
        <entry key="province" value="henan"/>
        <entry key="city" value="kaifeng"/>
    </map>
</property>

注入Properties类型数据

<property name="properties">
    <props>
        <prop key="country">china</prop>
        <prop key="province">henan</prop>
        <prop key="city">kaifeng</prop>
    </props>
</property>

然后我们运行App3:
在这里插入图片描述

注意:
①property标签表示setter方式注入,构造方式注入constructor-arg标签内部也可以写 <array><list><set><map><props>标签
List的底层也是通过数组实现的,所以 <list><array>标签是可以混用
集合中要添加引用类型,只需要把 <value>标签改成 <ref>标签,这种方式用的比较少
相关文章
|
2月前
|
Java Spring
在使用Spring的`@Value`注解注入属性值时,有一些特殊字符需要注意
【10月更文挑战第9天】在使用Spring的`@Value`注解注入属性值时,需注意一些特殊字符的正确处理方法,包括空格、引号、反斜杠、新行、制表符、逗号、大括号、$、百分号及其他特殊字符。通过适当包裹或转义,确保这些字符能被正确解析和注入。
170 3
|
2月前
|
Java 测试技术 程序员
为什么Spring不推荐@Autowired用于字段注入?
作为Java程序员,Spring框架在日常开发中使用频繁,其依赖注入机制带来了极大的便利。然而,尽管@Autowired注解简化了依赖注入,Spring官方却不推荐在字段上使用它。本文将探讨字段注入的现状及其存在的问题,如难以进行单元测试、违反单一职责原则及易引发NPE等,并介绍为何Spring推荐构造器注入,包括增强代码可读性和维护性、方便单元测试以及避免NPE等问题。通过示例代码展示如何将字段注入重构为构造器注入,提高代码质量。
113 1
|
7天前
|
设计模式 XML Java
【23种设计模式·全精解析 | 自定义Spring框架篇】Spring核心源码分析+自定义Spring的IOC功能,依赖注入功能
本文详细介绍了Spring框架的核心功能,并通过手写自定义Spring框架的方式,深入理解了Spring的IOC(控制反转)和DI(依赖注入)功能,并且学会实际运用设计模式到真实开发中。
【23种设计模式·全精解析 | 自定义Spring框架篇】Spring核心源码分析+自定义Spring的IOC功能,依赖注入功能
|
5天前
|
存储 Java 应用服务中间件
【Spring】IoC和DI,控制反转,Bean对象的获取方式
IoC,DI,控制反转容器,Bean的基本常识,类注解@Controller,获取Bean对象的常用三种方式
|
21天前
|
Java Spring
一键注入 Spring 成员变量,顺序编程
介绍了一款针对Spring框架开发的插件,旨在解决开发中频繁滚动查找成员变量注入位置的问题。通过一键操作(如Ctrl+1),该插件可自动在类顶部添加`@Autowired`注解及其成员变量声明,同时保持光标位置不变,有效提升开发效率和代码编写流畅度。适用于IntelliJ IDEA 2023及以上版本。
一键注入 Spring 成员变量,顺序编程
|
23天前
|
Java 数据库 数据安全/隐私保护
轻松掌握Spring依赖注入:打造你的登录验证系统
本文以轻松活泼的风格,带领读者走进Spring框架中的依赖注入和登录验证的世界。通过详细的步骤和代码示例,我们从DAO层的创建到Service层的实现,再到Spring配置文件的编写,最后通过测试类验证功能,一步步构建了一个简单的登录验证系统。文章不仅提供了实用的技术指导,还以口语化和生动的语言,让学习变得不再枯燥。
37 2
|
缓存 Java 测试技术
Spring Framework发布5.3.11和5.2.18
Spring Framework发布5.3.11和5.2.18
398 0
|
Java 容器 Spring
Spring Framework 5.1 正式发布
Spring Framework 5.1 正式,支持JDK 11这个LTS版本。
1405 0
|
Java Spring 应用服务中间件
Spring Framework 2.5发布
Spring Framework 2.5发布   Spring Framework是Java平台上非常流行的开源框架之一。 其最新的特征有:完全支持Java 6,JDBC 4,JAX-WS 2.0,基于annotation的依赖注入,在类路径中自动检测组件,自动配置组件作为Spring的被管对象的能力,新的AOP特征,多个Web层增强等等。
664 0