• ​​一、注入是什么​​
  • ​​1.1为什么需要注入​​
  • ​​1.2如何进行注入​​
  • ​​1.3注入的好处​​
  • ​​1.4原理分析​​
  • ​​二、Set注入详解​​
  • ​​1.JDK内置类型​​
  • ​​1.1String+8种基本数据类型​​
  • ​​1.2数组类型​​
  • ​​1.3Set类型​​
  • ​​1.3List类型​​
  • ​​1.4Map类型​​
  • ​​1.Properties类型​​
  • ​​2.用户自定义类型​​
  • ​​2.1方式一​​
  • ​​2.2方式二​​
  • ​​3.Set注入的简化写法​​
  • ​​3.1基于属性简化​​
  • ​​3.2基于p命名空间简化​​

一、注入是什么

通过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>

Spring的Set注入_赋值

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>

Spring的Set注入_成员变量_02

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

2.2方式二

  • 为成员变量提供set,get方法
  • 配置文件中进行配置
    Spring的Set注入_成员变量_03
<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>

Spring的Set注入_框架_04

下面的写法也是一样的

<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>

Spring的Set注入_Spring_05