Spring的Set注入

简介: Spring的Set注入

一、注入是什么

通过Spring工厂以及配置文件,为所创建对象的成员变量赋值

1.1为什么需要注入

通过编码的方式为成员变量进行赋值,存在耦合?为什么
我们以前都是通过set方法来为成员变量赋值,这样通过代码为成员变量赋值存在耦合
注入可以解决这种问题

1.2如何进行注入

  • 类的成员变量提供set方法
  • 配置Spring的配置文件
    <bean id="person"  class="com.zyh.basic.Person">
<!--        peroperty的name值要设置成为成员变量的属性名
            value就相当于是我们给属性赋的值-->
        <property name="id">
            <value >10</value>
        </property>
        <property name="name" >
            <value>tom</value>
        </property>
    </bean>

在这里插入图片描述

1.3注入的好处

解耦合

1.4原理分析

Spring读取配置文件,遇到bean标签

  <bean id="person"  class="com.zyh.basic.Person">

这个时候它就会通过反射来创建对象
Person person=new Person();
调用的是无参构造方法,就算构造器私有也可以调用

然后读取到property标签以前对应的属性值

        <property name="id">
            <value>10</value>
        </property>
        <property name="name">
            <value>tom</value>
        </property>
   

比如说,读取到标签的name属性值为id,value标签为10
这个时候,就会调用对应的set方法为这个属性赋值
如果我们写的实体类中没有提供对应的set方法,那么就会报错
报错信息说id不可写

Invalid property 'id' of bean class [com.zyh.basic.Person]: Bean property 'id' is not writable or has an invalid setter method

我们可以看出在这个时候,Spring底层是通过调用set方法来进行成员变量的赋值,这种方式称为set注入

二、Set注入详解

我们知道一个类里面的参数可以是不同的类型,我们可以大体分成两类

  • Java原生类型(JDK内置类型) 比如基本数据类型,引用数据类型
  • 我们自定义的那些类型

针对不同的类型的成员变量,我们在property标签中,需要嵌套其他的标签

1.JDK内置类型

1.1String+8种基本数据类型

在property标签中使用value标签来进行赋值

<property name="name">
            <value>tom</value>
        </property>

1.2数组类型

private String[] emails;
 <property name="emails">

            <list>
                <value>zhangsan@qq.com</value>
                <value>lisi@qq.com</value>
                <value>wangwu@qq.com</value>
            </list>
        </property>

1.3Set类型

private Set<String> details;
<property name="details">
            <set>
                <value>101</value>
                <value>102</value>
                <value>103</value>
                <value>102</value>
            </set>

        </property>

注意:如果我们在配置文件的value标签中配置多个相同的值,我们在输出的时候其实那些相同的数据只会保留一个,其他的会被过滤掉

1.3List类型

 private List<String> address;
<property name="address">
            <list>
                <value>上海</value>
                <value>北京</value>
                <value>杭州</value>
            </list>
        </property>

1.4Map类型

注意:Map集合中的数据是以键值对的形式存储的,把key和value看成一个Entry(javase的内容)
在这里如果我们想要用标签来进行对应的赋值的话,在map里面用entry标签
entry里面用key标签代表键
值根据对应类型选择对应类型的标签

private Map<String,String> map;
<property name="map">
            <map>
<!--                map中的数据以键值对的形式存储-->
                <entry>
                    <key><value>10</value></key>
                    <value>tom</value>
                </entry>
            </map>
        </property>

1.Properties类型

Perperties是特殊的map,它的键值对都是存储String类型

<property name="p">
            <props>
                <prop key="key1">value1</prop>
                <prop key="key2">value2</prop>
            </props>
        </property>

2.用户自定义类型

2.1方式一

  • 为成员变量提供set,get方法

    • 配置文件中进行注入(赋值)
<!--    bean标签就是为了创建对象的-->
    <bean id="userservice" class="com.zyh.basic.UserServiceImpl">
        <property name="userDao" >
            <bean  class="com.zyh.basic.UserDAOImpl"/>
        </property>
    </bean>

在这里插入图片描述
不过这种方法存在着一种问题,比如说现在有三个类,A,B,C,A类的成员变量中有C类型,B类的成员变量也有C类型,那么使用第一种方式的话,我们如果想要为这个属性赋值的话,我们就得在配置文件中进行两次注入,这样就会导致代码冗余,因为我们要进行的操作功能其实是一样的,其实我们是可以想办法让A和B共用C,但是在Spring中,只要写bean标签,它就会帮我们创建对象,这样就导致C类型的对象多次创建,导致资源浪费

2.2方式二

  • 为成员变量提供set,get方法
  • 配置文件中进行配置

在这里插入图片描述

  <bean id="userdao" class="com.zyh.basic.UserDAOImpl"></bean>
    <bean id="userservice" class="com.zyh.basic.UserServiceImpl">
        <property name="userDao" >
            <ref bean="userdao"></ref>
        </property>
    </bean>
  

3.Set注入的简化写法

3.1基于属性简化

先来回顾一下,之前我们写set注入

JDK类型注入
 <property name="name">
            <value>tom</value>
        </property>

我们现在有一种简化的写法
用value属性代替value标签

 <property name="name" value="tom"/>
             

注意:value属性只能简化8大基本数据类型+String类型注入标签

我们再来看一下,如果是用户自定义类型要怎么简化
老规矩,先来回顾之前的注入怎么写

 <bean id="userdao" class="com.zyh.basic.UserDAOImpl"></bean>
    <bean id="userservice" class="com.zyh.basic.UserServiceImpl">
        <property name="userDao" >
            <ref bean="userdao"></ref>
        </property>
    </bean>

我们可以用ref属性来替代\<ref bean>

<property name="userDAO" ref="userdao"/>

3.2基于p命名空间简化

下面两种方式是一样的

 <bean id="person" class="com.zyh.basic.Person" p:id="10" p:name="jack"/>
 
     
 <bean id="person" class="com.zyh.basic.Person">
      <property name="id" value="1"></property> 
        <property name="name" value="tom"></property> 
    </bean>

在这里插入图片描述
下面的写法也是一样的

  <bean id="userdao" class="com.zyh.basic.UserDAOImpl"></bean>
    <bean id="userservice" class="com.zyh.basic.UserServiceImpl">
        <property name="userDao" >
            <ref bean="userdao"></ref>
        </property>
    </bean>
<bean id="userdao" class="com.zyh.basic.UserDAOImpl"></bean>
 <bean id="userService" class="com.zyh.basic.UserServiceImpl" p:userDao-ref="userdao"></bean>

在这里插入图片描述

相关文章
|
29天前
|
Java Spring
在使用Spring的`@Value`注解注入属性值时,有一些特殊字符需要注意
【10月更文挑战第9天】在使用Spring的`@Value`注解注入属性值时,需注意一些特殊字符的正确处理方法,包括空格、引号、反斜杠、新行、制表符、逗号、大括号、$、百分号及其他特殊字符。通过适当包裹或转义,确保这些字符能被正确解析和注入。
|
1月前
|
Java 测试技术 程序员
为什么Spring不推荐@Autowired用于字段注入?
作为Java程序员,Spring框架在日常开发中使用频繁,其依赖注入机制带来了极大的便利。然而,尽管@Autowired注解简化了依赖注入,Spring官方却不推荐在字段上使用它。本文将探讨字段注入的现状及其存在的问题,如难以进行单元测试、违反单一职责原则及易引发NPE等,并介绍为何Spring推荐构造器注入,包括增强代码可读性和维护性、方便单元测试以及避免NPE等问题。通过示例代码展示如何将字段注入重构为构造器注入,提高代码质量。
|
1月前
|
缓存 Java Spring
源码解读:Spring如何解决构造器注入的循环依赖?
本文详细探讨了Spring框架中的循环依赖问题,包括构造器注入和字段注入两种情况,并重点分析了构造器注入循环依赖的解决方案。文章通过具体示例展示了循环依赖的错误信息及常见场景,提出了三种解决方法:重构代码、使用字段依赖注入以及使用`@Lazy`注解。其中,`@Lazy`注解通过延迟初始化和动态代理机制有效解决了循环依赖问题。作者建议优先使用`@Lazy`注解,并提供了详细的源码解析和调试截图,帮助读者深入理解其实现机制。
33 1
|
3月前
|
XML Java 数据格式
Spring5入门到实战------4、IOC容器-Bean管理XML方式、集合的注入(二)
这篇文章是Spring5框架的实战教程,主题是IOC容器中Bean的集合属性注入,通过XML配置方式。文章详细讲解了如何在Spring中注入数组、List、Map和Set类型的集合属性,并提供了相应的XML配置示例和Java类定义。此外,还介绍了如何在集合中注入对象类型值,以及如何使用Spring的util命名空间来实现集合的复用。最后,通过测试代码和结果展示了注入效果。
Spring5入门到实战------4、IOC容器-Bean管理XML方式、集合的注入(二)
|
3月前
|
缓存 Java 数据库连接
Spring Boot 资源文件属性配置,紧跟技术热点,为你的应用注入灵动活力!
【8月更文挑战第29天】在Spring Boot开发中,资源文件属性配置至关重要,它让开发者能灵活定制应用行为而不改动代码,极大提升了可维护性和扩展性。Spring Boot支持多种配置文件类型,如`application.properties`和`application.yml`,分别位于项目的resources目录下。`.properties`文件采用键值对形式,而`yml`文件则具有更清晰的层次结构,适合复杂配置。此外,Spring Boot还支持占位符引用和其他外部来源的属性值,便于不同环境下覆盖默认配置。通过合理配置,应用能快速适应各种环境与需求变化。
44 0
|
3月前
|
安全 Java 开发者
开发者必看!@Resource与private final的较量,Spring Boot注入技巧大揭秘,你不可不知的细节!
【8月更文挑战第29天】Spring Boot作为热门Java框架,其依赖注入机制备受关注。本文通过对比@Resource(JSR-250规范)和@Autowired(Spring特有),并结合private final声明的字段注入,详细探讨了两者的区别与应用场景。通过示例代码展示了@Resource按名称注入及@Autowired按类型注入的特点,并分析了它们在注入时机、依赖性、线程安全性和单一职责原则方面的差异,帮助开发者根据具体需求选择最合适的注入策略。
141 0
|
4月前
|
Java Spring
spring注入的几种方式
spring注入的几种方式
26 0
|
5月前
|
Java Spring 容器
spring如何进行依赖注入,通过set方法把Dao注入到serves
spring如何进行依赖注入,通过set方法把Dao注入到serves
|
5月前
|
Java Linux 程序员
技术笔记:Spring生态研习【五】:Springboot中bean的条件注入
技术笔记:Spring生态研习【五】:Springboot中bean的条件注入
|
5月前
|
SQL 安全 Java
Spring Boot中的跨站点脚本攻击(XSS)与SQL注入防护
【6月更文挑战第15天】在现代Web应用程序开发中,安全性是一个至关重要的课题。跨站点脚本攻击(XSS)和SQL注入是最常见的两种攻击类型,它们可以严重威胁到应用程序的安全。
577 0