依赖注入的方法

构造注入

核心原理:通过调用构造方法来给属性赋值

public class OrderService {

    private OrderDao orderDao;
    private UserDao userDao;

    public OrderService(OrderDao orderDao, UserDao userDao) {
        this.orderDao = orderDao;
        this.userDao = userDao;
    }
    
    public void delete(){
    }
}
    <!--Spring配置文件-->
<bean id="orderDaoBean" class="com.powernode.spring6.dao.OrderDao"/>

<bean id="orderServiceBean" class="com.powernode.spring6.service.OrderService">
  <!--第一个参数下标是0-->
  <constructor-arg index="0" ref="orderDaoBean"/>
  <!--第二个参数下标是1-->
  <constructor-arg index="1" ref="userDaoBean"/>
</bean>

<bean id="userDaoBean" class="com.powernode.spring6.dao.UserDao"/>

或者不使用参数下标,使用参数名字:

<!--Spring配置文件-->
<bean id="orderDaoBean" class="com.powernode.spring6.dao.OrderDao"/>

<bean id="orderServiceBean" class="com.powernode.spring6.service.OrderService">
  <!--这里使用了构造方法上参数的名字-->
  <constructor-arg name="orderDao" ref="orderDaoBean"/>
  <constructor-arg name="userDao" ref="userDaoBean"/>
</bean>

<bean id="userDaoBean" class="com.powernode.spring6.dao.UserDao"/>

通过构造方法注入的时候:

  • 可以通过下标
  • 可以通过参数名
  • 也可以不指定下标和参数名,可以类型自动推断。

set注入

set注入

set注入,基于set方法实现的,底层会通过反射机制调用属性对应的set方法然后给属性赋值。这种方式要求属性必须对外提供set方法。
1、声明对应的Bean
2、为该Bean创造set方法
3、在Spring配置文件中,对应的Bean里,通过property 标签传入name和ref
4、name为set方法去掉“set”并且第一个字母小写,ref为传入set方法的bean的id

public class UserService {

    private UserDao userDao;

    // 使用set方式注入,必须提供set方法。
    // 反射机制要调用这个方法给属性赋值的。
    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }

    public void save(){
        userDao.insert();
    }
}
<!--Spring配置文件-->
	<bean id="userDaoBean" class="com.powernode.spring6.dao.UserDao"/>

    <bean id="userServiceBean" class="com.powernode.spring6.service.UserService">
    	<!--set方法名为:setUserDao,name为去掉set,后面字符串第一个字母小写,ref为要注入的bean的id-->
        <property name="userDao" ref="userDaoBean"/>
    </bean>

set注入外部Bean

上面的set注入方式就是注入的外部Bean,即bean定义到外面,在property标签中使用ref属性进行注入。
在这里插入图片描述

set注入内部Bean

内部Bean的方式:在bean标签中嵌套bean标签

<!--Spring配置文件-->
    <bean id="userServiceBean" class="com.powernode.spring6.service.UserService">
        <property name="userDao">
            <bean class="com.powernode.spring6.dao.UserDao"/>
        </property>
    </bean>

在这里插入图片描述

set注入简单类型

set方法中不是类对象,是int等简单类型也可以注入

public class User {

    private int age;
    //set方法里面是简单类型int
    public void setAge(int age) {
        this.age = age;
    }
}
<!--Spring配置文件-->
	<bean id="userBean" class="com.powernode.spring6.beans.User">
        <!--简单类型在注入的时候要使用value属性,不能使用ref-->
        <property name="age">
            <value>20</value>
        </property>
    </bean>

或者

<!--Spring配置文件-->
	<bean id="userBean" class="com.powernode.spring6.beans.User">
        <!--简单类型在注入的时候要使用value属性,不能使用ref-->
        <property name="age" value="20"/>
    </bean>

简单类型包括:

  • 基本数据类型
  • 基本数据类型对应的包装类
  • String或其他的CharSequence子类
  • Number子类
  • Date子类
  • Enum子类
  • URI
  • URL
  • Temporal子类
  • Locale
  • Class
  • **另外还包括以上简单值类型对应的数组类型

需要注意的是:

如果把Date当做简单类型的话,日期字符串格式不能随便写。格式必须符合Date的toString()方法格式。显然这就比较鸡肋了。如果我们提供一个这样的日期字符串:2010-10-11,在这里是无法赋值给Date类型的属性的。

spring6之后,当注入的是URL,那么这个url字符串是会进行有效性检测的。如果是一个存在的url,那就没问题。如果不存在则报错。

级联属性赋值

级联属性赋值就是给 注入的Bean 的属性赋值,看下图:
在这里插入图片描述
一般ClazzBean的属性应该在自己的bean标签下赋值,若是在StudentBean标签下赋值,就是级联属性赋值:
是需要注意:
1、

<!--Spring配置文件-->
	<bean id="clazzBean" class="com.powernode.spring6.beans.Clazz"/>
    <bean id="student" class="com.powernode.spring6.beans.Student">
        <property name="name" value="张三"/>
        
        <!--要点1:以下两行配置的顺序不能颠倒-->
        <property name="clazz" ref="clazzBean"/>
        <!--要点2:clazz属性必须有getter方法-->
        <property name="clazz.name" value="高三一班"/>
    </bean>

2、

public class Clazz {
    private String name;
    public Clazz() {
    }
	//使用级联属性赋值,级联赋值的属性,例如clazz.name必须有get方法
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}

注入数组

1、当数组中的元素是简单类型:

public class Person {
    private String[] favariteFoods;

    public void setFavariteFoods(String[] favariteFoods) {
        this.favariteFoods = favariteFoods;
    }
}

标签使用property,属性name对应set方法。array标签包裹一组数据,数组每个元素的赋值用value标签:

	<bean id="person" class="com.powernode.spring6.beans.Person">
        <property name="favariteFoods">
            <array>
                <value>鸡排</value>
                <value>汉堡</value>
                <value>鹅肝</value>
            </array>
        </property>
    </bean>

2、当数组中的元素是非简单类型:一个订单中包含多个商品:

public class Order {
	//数组中的元素非简单类型
    private Goods[] goods;

    public void setGoods(Goods[] goods) {
        this.goods = goods;
    }
}

标签使用property,属性name对应set方法。array标签包裹一组数据,数组每个元素的赋值用ref标签,
ref标签内的bean属性为需要赋值的bean的id

	1、先创造不同的非简单类型对象
	<bean id="goods1" class="com.powernode.spring6.beans.Goods">
        <property name="name" value="西瓜"/>
    </bean>
    <bean id="goods2" class="com.powernode.spring6.beans.Goods">
        <property name="name" value="苹果"/>
    </bean>
	2、通过ref标签给数组的每个元素赋值
    <bean id="order" class="com.powernode.spring6.beans.Order">
        <property name="goods">
            <array>
                <!--这里使用ref标签即可-->
                <ref bean="goods1"/>
                <ref bean="goods2"/>
            </array>
        </property>
    </bean>

注入List集合

List集合:有序可重复

public class People {
    // 一个人有多个名字
    private List<String> names;

    public void setNames(List<String> names) {
        this.names = names;
    }
}

标签使用property,属性name对应set方法。list标签包裹一组数据,数组每个元素的赋值用value标签。
如果List集合中是简单类型使用value标签,反之使用ref标签:

	<bean id="peopleBean" class="com.powernode.spring6.beans.People">
        <property name="names">
            <list>
                <!--非简单类型可以使用ref,简单类型使用value-->
                <value>铁锤</value>
                <value>张三</value>
                <value>张三</value>
                <value>张三</value>
                <value></value>
            </list>
        </property>
    </bean>

注入set集合

Set集合:无序不可重复

public class People {
    // 一个人有多个电话
    private Set<String> phones;

    public void setPhones(Set<String> phones) {
        this.phones = phones;
    }
}

标签使用property,属性name对应set方法。set标签包裹一组数据,数组每个元素的赋值用value标签。
如果Set集合中是简单类型使用value标签,反之使用ref标签:

	<bean id="peopleBean" class="com.powernode.spring6.beans.People">
        <property name="phones">
            <set>
                <!--非简单类型可以使用ref,简单类型使用value-->
                <value>110</value>
                <value>110</value>
                <value>120</value>
                <value>120</value>
                <value>119</value>
                <value>119</value>
            </set>
        </property>
    </bean>

注入Map集合

键值对

public class People {
    // 一个人有多个住址
    private Map<Integer, String> addrs;

    public void setAddrs(Map<Integer, String> addrs) {
        this.addrs = addrs;
    }
}

标签使用property,属性name对应set方法。map标签包裹一组数据,数组每个元素的赋值用entry标签,属性key为Map的键,属性value为Map的值。
如果key不是简单类型,使用 key-ref 属性;如果value不是简单类型,使用 value-ref 属性:

	<bean id="peopleBean" class="com.powernode.spring6.beans.People">
        <property name="addrs">
            <map>
                <!--如果key不是简单类型,使用 key-ref 属性-->
                <!--如果value不是简单类型,使用 value-ref 属性-->
                <entry key="1" value="北京大兴区"/>
                <entry key="2" value="上海浦东区"/>
                <entry key="3" value="深圳宝安区"/>
            </map>
        </property>
    </bean>

注入Properties

java.util.Properties继承java.util.Hashtable,所以Properties也是一个Map集合。

public class People {

    private Properties properties;

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

标签使用property,属性name对应set方法。props标签包裹一组数据,数组每个元素的赋值用prop标签,属性key为Properties 的键,prop标签包裹的内容为Properties的值。

	<bean id="peopleBean" class="com.powernode.spring6.beans.People">
        <property name="properties">
            <props>
                <prop key="driver">com.mysql.cj.jdbc.Driver</prop>
                <prop key="url">jdbc:mysql://localhost:3306/spring</prop>
                <prop key="username">root</prop>
                <prop key="password">123456</prop>
            </props>
        </property>
    </bean>

注入null和空字符串

1、注入空字符串:使用<value/ > 或者 value=“”

public class Vip {
    private String email;

    public void setEmail(String email) {
        this.email = email;
    }
}

两种方式:
(1)标签使用property,属性name对应set方法。value=“”
(2)标签使用property,属性name对应set方法。嵌套一个 <value/ >

	<bean id="vipBean" class="com.powernode.spring6.beans.Vip">
        1、空串的第一种方式
        <property name="email" value=""/>
        2、空串的第二种方式
        <property name="email">
            <value/>
        </property>
    </bean>

2、注入null: 或者 不为该属性赋值

	方式1、不为email属性赋值,即没有<property>标签
    <bean id="vipBean" class="com.powernode.spring6.beans.Vip" />
	方式2、在<property>标签内嵌套 <null/>
	<bean id="vipBean" class="com.powernode.spring6.beans.Vip">
        <property name="email">
            <null/>
        </property>
    </bean>

注入的值中含特殊符号

XML中有5个特殊字符,分别是:< 和 > 和 ’ 和 "和 &
以上5个特殊符号在XML中会被特殊对待,会被当做XML语法的一部分进行解析,如果这些特殊符号直接出现在注入的字符串当中,会报错。

解决方案包括两种:

  • 第一种:特殊符号使用转义字符代替。
    在这里插入图片描述
  • 第二种:将含有特殊符号的字符串放到:<![CDATA[]]> 当中。因为放在CDATA区中的数据不会被XML文件解析器解析。
    注意:使用CDATA时,不能使用value属性,只能使用value标签。
	<bean id="mathBean" class="com.powernode.spring6.beans.Math">
        <property name="result">
            <!--只能使用value标签-->
            <value><![CDATA[2 < 3]]></value>
        </property>
    </bean>

P命名空间注入

目的:简化 set注入。
注意:

  • 第一:在XML头部信息中添加p命名空间的配置信息:xmlns:p=“http://www.springframework.org/schema/p”
  • 第二:p命名空间注入是基于setter方法的,所以需要对应的属性提供 setter方法
	<?xml version="1.0" encoding="UTF-8"?>
	<beans xmlns="http://www.springframework.org/schema/beans"
		1、加入p命名空间的配置信息
       	xmlns:p="http://www.springframework.org/schema/p"
       	
       	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">
		2、使用p命名空间方法,注入
    	<bean id="customerBean" class="com.powernode.spring6.beans.Customer" p:name="zhangsan" p:age="20"/>
	</beans>

C命名空间注入

目的:简化 构造注入。
注意:
第一:需要在xml配置文件头部添加信息:xmlns:c=“http://www.springframework.org/schema/c”
第二:需要提供构造方法。

	<?xml version="1.0" encoding="UTF-8"?>
	<beans xmlns="http://www.springframework.org/schema/beans"
		1、加入c命名空间的配置信息
       	xmlns:c="http://www.springframework.org/schema/c"
       	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">
       	2、使用c命名空间方法,注入。(带参数名称)
    	<bean id="myTimeBean" class="com.powernode.spring6.beans.MyTime" c:year="1970" c:month="1" c:day="1"/>
		3、使用c命名空间方法,注入。(不带参数名称)
    	<bean id="myTimeBean" class="com.powernode.spring6.beans.MyTime" c:_0="2008" c:_1="8" c:_2="8"/>
</beans>

Util命名空间

目的:配置复用
注意:
1、在spring配置文件头部添加配置信息
在这里插入图片描述

2、提供set方法

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       1、util配置信息
       xmlns:util="http://www.springframework.org/schema/util"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
       						1、util配置信息
                           	http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
	2、复用内容,id自定义,set方法为:setProperties()
    <util:properties id="prop">
        <prop key="driver">com.mysql.cj.jdbc.Driver</prop>
        <prop key="url">jdbc:mysql://localhost:3306/spring</prop>
        <prop key="username">root</prop>
        <prop key="password">123456</prop>
    </util:properties>

    <bean id="dataSource1" class="com.powernode.spring6.beans.MyDataSource1">
    	3、ref为复用体的id,set方法为:setProperties()
        <property name="properties" ref="prop"/>
    </bean>

    <bean id="dataSource2" class="com.powernode.spring6.beans.MyDataSource2">
        <property name="properties" ref="prop"/>
    </bean>
</beans>

基于XML的自动装配

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

益生李佳菌

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值