1.什么是注入—就是赋值
通过Spring工厂及配置文件,为所创建的对象的成员变量赋值
1.1为什么需要注入
-
优点:解耦合
-
通过编码的方式,为成员变量赋值会存在耦合
-
传统赋值方法 👇 set方法赋值
public void test4() {
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("/applicationContext.xml");
Person person = (Person) ctx.getBean("person");
// 通过代码为变量赋值, 存在耦合, 如果我们以后想修改变量的值, 需要修改代码, 重新编译
person.setId(1);
person.setName("zhenyu");
System.out.println(person);
}
1.2注入的步骤
-
实体类 提供set get方法
-
通过配置文件赋值
<bean id="person" class="com.hoan.pojo.Person">
<property name="id">
<value>12</value>
</property>
<property name="name">
<value>huahua</value>
</property>
</bean>
- 实例化
public void test(){
ClassPathXmlApplicationContext cxt = new ClassPathXmlApplicationContext("/applicationContext.xml");
Person person = (Person)cxt.getBean("person");
System.out.println(person.getId());
System.out.println(person.getName());
}
1.3注入原理(简易)
- Spring 底层通过调用对象属性对应的 set 方法,完成成员变量的赋值,这种方式也称为 Set注入。
2.SET注入详解–通过set赋值
Set注入的变量类型:
-
JDK内置类型
8种基本类型 + String、数组类型、set集合、list集合、Map集合、Properties集合。
-
用户自定义类型
2.1JDK内置类型
2.1.1String+8种基本类型
<property name="id">
<value>10</value>
</property>
<property name="name">
<value>yusael</value>
</property>
2.1.3数组
<property name="books">
<list>
<value>沉默的真相</value>
<value>沉默的羔羊</value>
<value>沉默的眼睛</value>
</list>
</property>
2.1.4Set集合
<property name="tels">
<set>
<value>12306</value>
<value>10086</value>
<value>10000</value>
<value>10000</value>
<value>1024</value>
</set>
</property>
2.1.5List集合
<property name="addresses">
<list>
<value>China</value>
<value>Earth</value>
<value>hell</value>
</list>
</property>
2.1.6Map集合
- Map的存在形式是 <K,V>,其对应属性为entry
<property name="qqs">
<map>
<entry>
<key><value>hello</value></key>
<value>12312312312</value>
</entry>
<entry>
<key><value>world</value></key>
<value>21314214214</value>
</entry>
</map>
</property>
2.1.7Properties
<property name="properties">
<props>
<prop key="1">让我再看你一眼</prop>
<prop key="2">从南到北</prop>
<prop key="3">像是北五环路</prop>
<prop key="4">蒙住的双眼</prop>
</props>
</property>
2.2复杂JDK类型(Date、…)
- 需要程序员自定义类型转换器,处理。
2.3用户自定义类型
-
Way One
为成员变量提供set get方法
配置文件中进行注入
public class Work {// person中 private Work work;
private String workName;
private int solar;
}
<bean id="work" class="com.hoan.pojo.Work">
<property name="workName">
<value>singer</value>
</property>
<property name="solar">
<value>1000</value>
</property>
</bean> 为Work类赋值
<bean id="person" class="com.hoan.pojo.Person">
<property name="work">
<bean class="com.hoan.pojo.Work"></bean>
</property>
</bean>通过上面的work类 来给 Person 中的Work类赋值
-
Way Two
第一种赋值存在问题:
1.配置代码 太多啦,如果有多个 对象都包含了Work类,则需要写的代码太多
2.标签太多,在XML文件中,bean标签每次被创建都会 新建对象,所以会占用内存和JVM资源
-
step 1 提供 **set get方法 **
-
step 2 配置文件中 新建类对象 Work
<bean id="work" class="com.hoan.pojo.Work">
<property name="workName">
<value>singer</value>
</property>
<property name="solar">
<value>1000</value>
</property>
</bean>
- step 3 为Person类 中的 Work类属性赋值
<bean id="person" class="com.hoan.pojo.Person">
<property name="work">
<ref bean="work"/>
</property>
</bean>通过上面的work类 来给 Person 中的Work类赋值
3.注入的简化
3.1属性的简化
- JDK属性注入
<property name="id">
<value>10</value>
</property>
- 简化方法
<property name="id" value="10"/>
3.2自定义类型的转化
- 简化方法
<property name="work" ref="work"/>
3.3基于P命名空间的简化
-
准备工作:
需要先声明 命名空间,在 写标签时 会报错,然后按照编译器要求 创建命名空间
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mOxCG64n-1631513849643)(C:\Users\dancerHoan\AppData\Roaming\Typora\typora-user-images\image-20210911145749966.png)]
4.构建注入–通过构造函数赋值
- 提供有参构造方法
public class Customer {
private String name;
private int age;
public Customer(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Customer{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
- Spring配置文件
<bean id="customer" class="com.yusael.constructor.Customer">
<constructor-arg>
<value>zhenyu</value>
</constructor-arg>
<constructor-arg>
<value>21</value>
</constructor-arg>
</bean>
形参个数不同时,通过控制 <constructor-arg>
标签的数量进行区分;
一个参数的话,只需要一对 <constructor-arg>
标签:
<bean id="customer" class="com.yusael.constructor.Customer">
<constructor-arg>
<value>zhenyu</value>
</constructor-arg>
</bean>
如果有两个参数的话,用两对 <constructor-arg>
标签,以此类推。
<bean id="customer" class="com.yusael.constructor.Customer">
<constructor-arg>
<value>zhenyu</value>
</constructor-arg>
<constructor-arg>
<value>22</value>
</constructor-arg>
</bean>
<bean id="customer" class="com.yusael.constructor.Customer">
<constructor-arg type="int">
<value>20</value>
</constructor-arg>
</bean>
zhenyu
22
- ### 形参个数相同---`type` 属性区分
```xml
<bean id="customer" class="com.yusael.constructor.Customer">
<constructor-arg type="int">
<value>20</value>
</constructor-arg>
</bean>