Spring之DI依赖注入

举报
楠羽 发表于 2022/10/10 23:08:10 2022/10/10
【摘要】 Spring之DI依赖注入

6、(DI)依赖注入

DI与IOC的关系:

相同问题不同角度分析。

在这里插入图片描述

  • 名称:property

  • 类型:标签

  • 归属:bean标签

  • 作用:使用set方法的形式为bean提供资源

  • 格式:

    <bean>
    	<property />
    </bean>
    
  • 基本属性:

    <property name="propertyName" value="propertyValue" ref="beanId"/>
    

​ name:对应bean中的属性名,要求该属性必须提供可访问的set方法(严格规范为此名称是set方法对应名称)

​ value:设定非引用类型属性对应的值,不能与ref同时使用

​ ref:设定引用类型属性对应bean的id ,不能与value同时使用

  • 注意:一个bean可以有多个property标签
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd">
    <!--1.创建spring控制的资源-->
    <!--bean可以使用多个名称,使用那么属性完成,中间使用,隔开-->
    <bean id="userService" name="userService1" class="com.DI.service.Impl.UserServiceImpl">
        <!--3.将要租注入的引用类型的变量通过property属性进行注入,对应的name是要注入的变量名 使用ref属性声明要注入的bean的id-->
        <property name="userDao" ref="userDao"/>
        <property name="num" value="666"/>
        <property name="version" value="楠木"/>
    </bean>
    <!--将要注入的资源声明为bean,引用类型需要声明,非引用类型的不用声明,直接赋值-->
    <bean id="userDao" class="com.DI.service.Impl.UserDaoImpl"/>
</beans>

6.1、构造器注入

  • 名称:constructor-arg

  • 类型:标签

  • 归属:bean标签

  • 作用:使用构造方法的形式为bean提供资源,兼容早期遗留系统的升级工作

  • 格式:

    <bean>
    	<constructor-arg />
    </bean>
    
  • 基本属性:

    <constructor-arg name="argsName" value="argsValue />
    

​ name:对应bean中的构造方法所携带的参数名

​ value:设定非引用类型构造方法参数对应的值,不能与ref同时使用

其他属性:

<constructor-arg index="arg-index" type="arg-type" ref="beanId"/>

​ ref:设定引用类型构造方法参数对应bean的id ,不能与value同时使用

​ type :设定构造方法参数的类型,用于按类型匹配参数或进行类型校验

​ index :设定构造方法参数的位置,用于按位置匹配参数,参数index值从0开始计数

  • 注意:一个bean可以有多个constructor-arg标签
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd">
    <!--将要注入的资源声明为bean,引用类型需要声明,非引用类型的不用声明,直接赋值-->
    <bean id="userDao" class="com.DI.service.Impl.UserDaoImpl"/>
    
    <bean id="userService" name="userService1" class="com.DI.service.Impl.UserServiceImpl">
        <!--不加name,也可以加index:从0开始-->
       <constructor-arg name="userDao" ref="userDao"/>
        <constructor-arg name="num" value="66666"/>
        <constructor-arg name="version" value="楠木"/>
    </bean>
</beans>

6.2、Set方式注入【重点】

依赖注入:Set注入!

  • 依赖:bean对象的创建依赖于容器!
  • 注入: 上bean对象中的所有属性,由容器来注入!

【环境搭建】

1.复杂类型

package com.blue.pojo;

public class Address {

    private String address;

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }
}

2.真实测试对象

public class Student {

    private String name;
    private Address address;
    private String[] books;
    private List<String> hobbies;
    private Map<String,String> card;
    private Set<String> games;
    private String wife;
    private Properties into;

beans.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       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">

    <bean id="student" class="com.blue.pojo.Student">
        <!-- 第一种,普通注入,value  -->
        <property name="name" value="blue"/>
    </bean>
</beans>

MyTest

public class MyTest {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        Student student = (Student) context.getBean("student");
        System.out.println(student.getName());
    }
}

集合注入方式:

  • 名称:array,list,set,map,props

  • 类型:标签

  • 归属:property标签 或 constructor-arg标签

  • 作用:注入集合数据类型属性

  • 格式:

    <property>
    	<list></list>
    </property>
    

(1)集合类型数据注入——list

<property name="al">
    <list>
        <value>itheima</value>
        <value>66666</value>
    </list>
</property>

(2)集合类型数据注入——props

<property name="properties">
    <props>
        <prop key="name">itheima666</prop>
        <prop key="value">666666</prop>
    </props>
</property>

(3)集合类型数据注入——array (了解)

<property name="arr">
    <array>
        <value>123456</value>
        <value>66666</value>
    </array>
</property>

(4)集合类型数据注入——set(了解)

 <property name="hs">
     <set>
         <value>itheima</value>
         <value>66666</value>
     </set>
</property>

(5)集合类型数据注入——map(了解)

<property name="hm">
    <map>
        <entry key="name" value="itheima66666"/>
        <entry key="value" value="6666666666"/>
    </map>
</property>

掌握:props、list

案例:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd">
    <!--1.创建spring控制的资源-->
    <!--bean可以使用多个名称,使用那么属性完成,中间使用,隔开-->
    <!-- <bean id="userService" name="userService1" class="com.DI.service.Impl.UserServiceImpl">
         &lt;!&ndash;3.将要租注入的引用类型的变量通过property属性进行注入,对应的name是要注入的变量名 使用ref属性声明要注入的bean的id&ndash;&gt;
         <property name="userDao" ref="userDao"/>
         <property name="num" value="666"/>
         <property name="version" value="楠木"/>
     </bean>-->
    <!--将要注入的资源声明为bean,引用类型需要声明,非引用类型的不用声明,直接赋值-->
    <!--<bean id="userDao" class="com.DI.Dao.Impl.UserDaoImpl">
        &lt;!&ndash;不加name,也可以加index:从0开始&ndash;&gt;
        <constructor-arg name="password" value="12345"/>
        <constructor-arg name="username" value="root"/>
        <constructor-arg name="driver" value="123"/>
    </bean>

    &lt;!&ndash;构造注入&ndash;&gt;

    <bean id="userService" name="userService1" class="com.DI.service.Impl.UserServiceImpl">
        &lt;!&ndash; 使用构造方法进行set注入,需要保障注入的属性与bean中定义的属性一致&ndash;&gt;
        &lt;!&ndash;一致指顺序一致或类型一致或使用index解决问题&ndash;&gt;
        <constructor-arg name="userDao" ref="userDao"/>
        <constructor-arg name="num" value="66666"/>
        <constructor-arg name="version" value="楠木"/>
    </bean>-->

    <!--其余类型注入-->

    <bean id="userDao" class="com.DI.Dao.Impl.UserDaoImpl">
        <!--不加name,也可以加index:从0开始-->
        <constructor-arg name="password" value="12345"/>
        <constructor-arg name="username" value="root"/>
        <constructor-arg name="driver" value="123"/>
    </bean>

    <bean id="userService" name="userService1" class="com.DI.service.Impl.UserServiceImpl">
        <property name="userDao" ref="userDao"/>
        <property name="bookDao" ref="bookDao"/>
    </bean>
    <bean id="bookDao" name="bookDao" class="com.DI.Dao.Impl.BookDaoImpl">
        <property name="al">
            <list>
                <value>楠木1</value>
                <value>楠木2</value>
            </list>
        </property>
        <property name="props">
            <props>
                <prop key="name">小米</prop>
                <prop key="value">大米</prop>
            </props>
        </property>
        <property name="arr">
            <array>
                <value>6666</value>
                <value>9999</value>
            </array>
        </property>
        <property name="hs">
            <set>
                <value>楠木3</value>
                <value>楠木4</value>
            </set>
        </property>
        <property name="hm">
            <map>
                <entry key="name" value="楠木5"></entry>
                <entry key="name" value="楠木6"></entry>
            </map>
        </property>
    </bean>

</beans>

6.3、拓展方式注入

  • 名称:p:propertyName,p:propertyName-ref

  • 类型:属性

  • 归属:bean标签

  • 作用:为bean注入属性值

  • 格式:

    <bean p:propertyName="propertyValue" p:propertyName-ref="beanId"/>
    
  • 注意:使用p命令空间需要先开启spring对p命令空间的的支持,在beans标签中添加对应空间支持

    <beans xmlns="http://www.springframework.org/schema/beans"    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    xmlns:p="http://www.springframework.org/schema/p"       xsi:schemaLocation="http://www.springframework.org/schema/beans     https://www.springframework.org/schema/beans/spring-beans.xsd">
    

    后续课程中还将开启其他的命名空间,方式同上

  • 案例:

     <bean
           id="userService"
           class="com.itheima.service.impl.UserServiceImpl"
           p:userDao-ref="userDao"
           p:bookDao-ref="bookDao"
           />
    

标签P

简化书写,直接注入属性值

xmlns:p="http://www.springframework.org/schema/p"

注意点:p命名和c命名空间不能直接使用,需要导入xml约束!

xmlns:p="http://www.springframework.org/schema/p"
xmlns:c="http://www.springframework.org/schema/c"
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="user" class="com.lfs.pojo.User" p:name="blue" p:age="18"/>
    
</beans>

加配置–测试:

test:

public class MyTest {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("userbeans.xml");
        User user = context.getBean("user", User.class);
        System.out.println(user);
    }
}

标签C

c标签:通过构造器注入

 xmlns:c="http://www.springframework.org/schema/c"
public class User {
    private String name;
    private int age;

    public User() {
    }

    public User(String name, int age) {
        this.name = name;
        this.age = age;
    }

 <bean id="user" class="com.blue.pojo.User" p:name="blue" p:age="18"/>

 <bean id="user" class="com.blue.pojo.User" c:age="18" c:name="blue"/>

SpEL

  • Spring提供了对EL表达式的支持,统一属性注入格式

  • 类型:属性值

  • 归属:value属性值

  • 作用:为bean注入属性值

  • 格式:

    <property value="EL表达式"></bean>
    
  • 注意:所有属性值不区分是否引用类型,统一使用value赋值

  • 所有格式统一使用 value=“********”

    • 常量 #{10} #{3.14} #{2e5} #{‘itcast’}

    • 引用bean #{beanId}

    • 引用bean属性 #{beanId.propertyName}

    • 引用bean方法 beanId.methodName().method2()

    • 引用静态方法 T(java.lang.Math).PI

    • 运算符支持 #{3 lt 4 == 4 ge 3}

    • 正则表达式支持 #{user.name matches‘[a-z]{6,}’}

    • 集合支持 #{likes[3]}

  • 案例:

     <bean id="userService" class="com.itheima.service.impl.UserServiceImpl">
         <property name="userDao" value="#{userDao}"/>
         <property name="bookDao" value="#{bookDao}"/>
         <property name="num" value="#{666666666}"/>
         <property name="version" value="#{'itcast'}"/>
    </bean>
    

properties文件加载

  • Spring提供了读取外部properties文件的机制,使用读取到的数据为bean的属性赋值

  • 操作步骤

    1.准备外部properties文件

    2.开启context命名空间支持

    xmlns:context="http://www.springframework.org/schema/context"
    

​ 3.加载指定的properties文件

<context:property-placeholder location="classpath:filename.properties">

​ 4.使用加载的数据

<property name="propertyName" value="${propertiesName}"/>
  • 注意:如果需要加载所有的properties文件,可以使用*.properties表示加载所有的properties文件

  • 注意:读取数据使用**${propertiesName}格式进行,其中propertiesName**指properties文件中的属性名

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        https://www.springframework.org/schema/context/spring-context.xsd

    ">
    <!--1.加载context标签命名空间的支持-->
    <!--xmlns:context="http://www.springframework.org/schema/context"
      http://www.springframework.org/schema/context
      https://www.springframework.org/schema/context/spring-context.xsd
    -->

    <!--2.加载配置文件-->

    <context:property-placeholder location="classpath:*.properties"/>

    <!--1.创建spring控制的资源-->
    <!--bean可以使用多个名称,使用那么属性完成,中间使用,隔开-->
    <bean id="bookDao" class="com.properties.dao.Impl.BookDaoImpl"/>
    
    <!--scope用于控制bean创建后的对象是否是单列-->
    <bean id="userDao" class="com.properties.dao.Impl.UserDaoImpl">
        <property name="name" value="${username}"/>
        <property name="pass" value="${password}"/>
    </bean>

    <bean id="userService" class="com.properties.service.Impl.UserServiceImpl">
        <property name="userDao" ref="userDao"/>
        <property name="bookDao" ref="bookDao"/>
    </bean>
</beans>

团队开发

  • 名称:import

  • 类型:标签

  • 归属:beans标签

  • 作用:在当前配置文件中导入其他配置文件中的项

  • 格式:

    <beans>
        <import />
    </beans>
    
  • 基本属性:

    <import resource=“config.xml"/>
    

​ resource:加载的配置文件名

  • Spring容器加载多个配置文件

    new ClassPathXmlApplicationContext("config1.xml","config2.xml");
    
  • Spring容器中的bean定义冲突问题

    • 同id的bean,后定义的覆盖先定义的

    • 导入配置文件可以理解为将导入的配置文件复制粘贴到对应位置

    • 导入配置文件的顺序与位置不同可能会导致最终程序运行结果不同

ApplicationContext

  • 1.ApplicationContext是一个接口,提供了访问spring容器的API

  • 2.ClassPathXmlApplicationContext是一个类,实现了上述功能

  • 3.ApplicationContext的顶层接口是BeanFactory

  • 4.BeanFactory定义了bean相关的最基本操作

  • 5.ApplicationContext在BeanFactory基础上追加了若干新功能

对比BeanFactory

  • 1.BeanFactory创建的bean采用延迟加载形式,使用才创建

  • 2.ApplicationContext创建的bean默认采用立即加载形式

FileSystemXmlApplicationContext

  • 可以加载文件系统中任意位置的配置文件,而ClassPathXmlApplicationContext只能加载类路径下的配置文件

BeanFactory

Resource res = new ClassPathResource("applicationContext.xml");
BeanFactory bf = new XmlBeanFactory(res);
UserService userService = (UserService)bf.getBean("userService");

第三方资源配置—>Druid

  • 阿里数据源方案Druid

    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
        <property name="url" value="jdbc:mysql://localhost:3306/spring_ioc"></property>
        <property name="username" value="root"></property>
        <property name="password" value="root"></property>
    </bean>
    
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。