Spring学习笔记05 - 注入详解

注入详解

注入分为两种,如下:

  1. Set 注入
  2. 构造注入

Set 注入详解

使用 <property> 标签。
对成员变量进行注入赋值。针对于 不同类型的成员变量。在<property> 标签中可以嵌套其他标签。

成员变量分为两类:

  1. JDK内置类型
  2. 用户自定义类型

JDK内置类型

JDK内置类型,Java本身定义的类型例如:
int
String[]
Set<String>
List<String>
Map<String>
Properties
怎么进行赋值呢?如下分别进行讨论。

  1. String + 8 种基本类型(char, boolean, byte、short、int、long、float、double )
    使用 <value>标签。
// private int id;
<property name="id">
	 <value>10</value>
</property>
// private String name;
<property name="name">
	 <value>Adam</value>
</property>
  1. 数组类型,需要新增<list>标签。
// private String[] emails;
<property name="emails">
	<list>
	     <value>sun@gamil.com</value>
	     <value>adam@gamil.com</value>
	     <value>bob@gamil.com</value>
	 </list>
</property> 
  1. set 集合
    配置集合,set集合无序,不重复。
    <set> 标签是set集合的核心。里面嵌套各种类型标签。这里是 <value> 标签是因为定义了set<String> String的泛型。
// private Set<String> tels;
<property name="tels">
    <set>
        <value>13231323123</value>
        <value>13231323123</value>
        <value>13661366166</value>
    </set>
</property>
//输出只有两个值,set会把重复的值过滤调,不可重复,且无序 
//13231323123
//13661366166
  1. List 集合
    有序,可重复,使用<list>标签,里面可嵌套其他标签。
// private List<String> addresses;
<property name="addresses">
     <list>
         <value>cpark</value>
         <value>askin</value>
         <value>partington</value>
         <value>askin</value>
     </list>
 </property>
 //ouput:
 //cpark
 //askin
 //partington
 //askin
  1. Map 集合
    需要有<map> <entry> <key>标签,值根据对应的类型选取标签。
    <entry>标签 里面对应一个键``值对。
    需要用一个<key>标签来标记,键的泛型是String类型,所以在嵌套一个<value>标签。
    没有特殊标签,值的泛型是String类型 用<value>标签。
// private Map<String,String> maps;
<property name="maps">
   <map>
       <entry>
           <key><value>key0</value></key>
           <value>123123</value>
       </entry>
       <entry>
           <key><value>key1</value></key>
           <value>456456</value>
       </entry>
   </map>
</property>
  1. Properties 类型
    Properties类型是特殊的map。 key value 都是String类型, key = String value=String
    使用<props><prop>标签。
    一个 <prop>标签里面就代表一个 对,
    写在 key属性里,
    直接写在 <prop> </prop>标签之间,本身就是string类型所以省去了<value>标签。
// private Properties p;
<property name="p">
    <props>
        <prop key="user">value1</prop>
        <prop key="user2">value2</prop>
    </props>
</property>

在这里插入图片描述

用户自定义类型

  1. 为用户提供set get方法
    但是还是需要创建set get 方法,因为Spring在底层反射创建的时候会 自动调用这些函数。
    我们所说的解藕,不是不需要这些函数,而是我们给对象属性赋值或更新值的时候,不需要在代码里修改(在代码里修改还需要重新编译),而是通过修改配置文件,并不需要重编代码。
package com.gogogo;

public class UserServiceImpl implements UserService{
    private UserDAO userDAO;

    public UserDAO getUserDAO() {
        return userDAO;
    }
    public void setUserDAO(UserDAO userDAO) {
        this.userDAO = userDAO;
    }
}
  1. 配置文件中进行注入(赋值)
    <property> 属性就是在为我们的成员变量 set 值。
//public class UserServiceImpl implements UserService{
//    private UserDAO userDAO;
//}
//
<bean id="userService" class="com.gogogo.UserServiceImpl">
    <property name="userDAO">
        <bean class="com.gogogo.UserDAOImpl"/>// 只使用一次,此处省略id配置
    </property>
</bean>
  1. 第二种赋值方式
    如下我们会发现,代码冗杂,每次都要重新创建 userDAO ,占用内存。
<bean id="userService" class="com.gogogo.UserServiceImpl">
    <property name="userDAO">
        <bean class="com.gogogo.UserDAOImpl"></bean>
    </property>
</bean>

<bean id="orderService" class="com.gogogo.OrderServiceImpl">
    <property name="userDAO">
        <bean class="com.gogogo.UserDAOImpl"></bean>
    </property>
</bean>

解决方案:
先创建 userDAO 增加 id 属性,方便被调用。

<bean id="userDAO" class="com.gogogo.UserDAOImpl"></bean>

使用<ref bean="bean_id"> 引用 userDAO 成员变量。

<bean id="userService" class="com.gogogo.UserServiceImpl">
    <property name="userDAO"> //成员属性名
        <ref bean="userDAO"></ref> // 引用上面定义的bean
    </property>
</bean>
<bean id="orderService" class="com.gogogo.OrderServiceImpl">
    <property name="userDAO"> //成员属性名
        <ref bean="userDAO"></ref> // 引用上面定义的bean
    </property>
</bean>

Set 注入简化写法

  1. 基于属性简化
  • JDK 类型注入
    value 属性替换 <value>标签。
    注意:只能是基于String类型 + 8种基本类型 (char, boolean, byte, short, int, long, float, double), 简化<value>标签。
//<property name="id">
//	<value>10</value>
//</property>-->
<property name="id" value="10"></property>

//<property name="name">
//	<value>Cristina</value>
//</property>-->
<property name="name" value="Cristina"></property>      
  • 用户自定义类型
    ref 属性替换 <ref> 标签。
<bean id="userDAO" class="com.gogogo.UserDAOImpl"></bean>
//<bean id="userService" class="com.gogogo.UserServiceImpl">
//    <property name="userDAO">
//        <ref bean="userDAO"></ref>
//    </property>
//</bean>

<bean id="userService" class="com.gogogo.UserServiceImpl">
    <property name="userDAO" ref="userDAO">
    </property>
</bean>
  1. 基于 命名空间 p 简化
    新增 命名空间 p:name="xiaowang" p:id="3" 即省去了后面的赋值,且需要引入xmlns:p="http://www.springframework.org/schema/p"
    格式如下:
    <bean id="" class="" p:name="" p:id ="" />
    <bean id="" class="" p:userDAO-ref=""></bean>
    在这里插入图片描述
<bean id="person" class="com.gogogo.Person" p:name="xiaowang" p:id="3">
//   <property name="id" value="10"></property>
//   <property name="name" value="Cristina"></property>
 </bean>
//<bean id="userService" class="com.gogogo.UserServiceImpl">
//    <property name="userDAO" ref="userDAO">
//    </property>
//</bean>
<bean id="userService" class="com.gogogo.UserServiceImpl" p:userDAO-ref="userDAO"/>

构造注入

Spring调用构造方法,通过配置文件为成员变量赋值。使用 <constructor-arg> 标签。

  1. 开发步骤
  • 提供有参构造方法
package com.gogogo.constructer;
import java.io.Serializable;

public class Customer implements Serializable {
    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 +
                '}';
    }
}
  • 提供配置文件
    因为不是set注入不提供set方法,那配置文件中就不能使用 <Property> 标签,构造注入使用 <constructor-arg> 标签, 一个 <constructor-arg> 标签 注入一个属性,且顺序要和类中定义的成员属性顺序一致,否则编译保存。
// private String name;
// private int age;
<bean id="customer" class="com.gogogo.constructer.Customer">
 	<constructor-arg name="name" value="jake"></constructor-arg>
    <constructor-arg name="age" value="22"></constructor-arg>  
</bean>

测试结果

public void Test4(){
    // 获得工厂
    ApplicationContext ctx = new ClassPathXmlApplicationContext("/applicationContext.xml");
    //获得对象
    Customer customer = (Customer) ctx.getBean("customer");
    System.out.println("customer: " + customer);
}
// ouput
// customer: Customer{name='jake', age=22}

构造方法重载
函数名相同(参数个数不同,参数类型不同)

  • 参数个数不同
    通过控制<constructor-arg> 标签个数来处理
  • 构造参数个数相同
    指定类型,引入 type 属性 进行区分

总结

Set 注入使用 <property> 标签
构造注入使用 <constructor-arg> 标签,顺序要一致
在这里插入图片描述
Set注入在实战中运用更多,构造注入要考虑重载,比较麻烦,Spring框架底层 也大量运用了set注入。

奥利给
祝学习开心❤️

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值