Spring学习笔记:注入(injection)【Set注入、构造注入、反转控制 与 依赖注入】

Spring笔记汇总

注入

1、什么是注入

通过Spring工厂及配置文件为所创建对象的成员变量赋值

1.1 为什么需要注入

通跟代码直接为成员变量赋值,有耦合
在这里插入图片描述

1.2 如何进行注入[开发步骤]

  • 类的成员变量提供set get方法
  • 配置spring的配置文件
<bean id="person" name="p,p1" class="com.company.basic.Person">
    <property name="id">
        <value>100</value>
    </property>
    <property name="name">
        <value>李四</value>
    </property>
</bean>

1.3 注入的好处

解耦合

2、Spring注入的原理(非源码)

Spring通过底层调用对象属性对应的set方法,完成成员变量的赋值,这种方式我们也称之为set注入
在这里插入图片描述

Set注入详解

在这里插入图片描述

针对于不同类型的成员变量,在<property>标签,需要嵌套其他标签

<property>
	xxx
</property>

1、JDK内置类型

1.1 基本类型加String

<property name="name">
    <value>李四</value>
</property>

1.2 数组类型

<property name="emails">
    <list>
        <value>48484@qq.com</value>
        <value>48484dad@qq.com</value>
        <value>48484dsa@qq.com</value>
    </list>
</property>

集合注意事项

  • 集合里面不包含重复的数据
  • 集合如果没有限制泛型类型(则Object),那么里面的元素放置不受限制

1.3 set类型

<property name="tels">
    <set>
        <value>31231341221</value>
        <value>56654454545</value>
        <value>56654454545</value>
        <value>56654454545</value>
    </set>
</property>

<property name="tels">
    <set>
        <value>31231341221</value>
        <ref bean=""/>
    	<set></set>
    	...
    </set>
</property>

1.4 List集合

<property name="addresses">
    <list>
        <value>这里</value>
        <value>那里</value>
        <value>这里</value>
    </list>
</property>
    
<property name="addresses">
    <list>
        <value>这里</value>
        <ref bean=""/>
    	<set></set>
    	...
    </list>
</property>

1.5 Map集合

注意: map – entry

  • – key有特定的标签<key></key>
  • 值根据对应类型选择对应类型的标签
        <property name="qqs">
            <map>
                <entry>
                    <!-- key有一个限制的key标签,而value没有限制标签  -->
                    <key>
                        <value>我的qq</value>
                    </key>
                    <value>123456789</value>
                </entry>
                <entry>
                    <key>
                        <value>他的qq</value>
                    </key>
                    <value>12345678910</value>
                </entry>
            </map>
        </property>
            
        <map>
            <entry>
            	<key>
                        <value>我的qq</value>
                </key>
                <ref bean=""/>
            </entry>
        </map>

1.6 Properties

Properties类型特殊的 Map key=String value=String

        <property name="p">
            <props>
                <prop key="key1">value1</prop>
                <prop key="key2">value2</prop>
            </props>
        </property>

1.7 复杂的JDK类型(如:Date)

需要程序员自定义类型转换器,处理。

测试方法

    /**
     *  用于测试:测试JDK内置类型
     *
     */
    @Test
    public void test7(){
        ApplicationContext ctx = new ClassPathXmlApplicationContext("/applicationContext.xml");
        Person  person = (Person) ctx.getBean("person");

        String[] emails = person.getEmails();
        for (String email : emails) {
            System.out.println("email = " + email);
        }

        System.out.println("------------------------------------------");

        Set<String> tels = person.getTels();
        for (String tel : tels) {
            System.out.println("tel = " + tel);
        }

        System.out.println("------------------------------------------");

        List<String> addresses = person.getAddresses();
        for (String address : addresses) {
            System.out.println("address = " + address);
        }

        System.out.println("------------------------------------------");

        Map<String, String> qqs = person.getQqs();
        for (Map.Entry<String, String> entry : qqs.entrySet()) {
            System.out.println("key:" + entry.getKey() +" value:" +entry.getValue());
        }
//        或者这样遍历
        Set<String> keys = qqs.keySet();
        for (String key : keys) {
            System.out.println("key:" + key + " value:" + qqs.get(key));
        }

        System.out.println("------------------------------------------");

        Properties properties = person.getP();
        System.out.println("key is key1 value is " + properties.getProperty("key1"));
        System.out.println("key is key2 value is " + properties.getProperty("key2"));
    }

2、用户自定义类型

2.1 第一种方式

  • 为成员变量提供set get方法
  • 在配置文件里面进行注入
<bean id="userService" class="xxx.UserServiceImpl">
	<property name="UserDao">
        <bean class="xxx.UserDaoImpl"/>
    </property>
</bean> 

2.2 第二种方式

第一种赋值方式存在的问题

  • 配置文件代码冗余
  • 被注入的对象(UserDA0),多次创建,浪费(JVM)内存资源

在这里插入图片描述

方法:

  • 为成员变量提供set get方法
  • 在配置文件里面进行注入
<bean id="userDao" class="xxx.UserDaoImpl"/>

<bean id="userService" class="xxx.UserSerivceImpl">
	<property name="userDao">
    	<ref bean="userDao"/>
    </property>
</bean>

#Spring4.x废除了	<ref local=""/>	  基本等效	<ref bean=""/>

3、set注入的简化方式

3.1 基于属性简化

    <!--	原本	-->
<bean id="person" class="xxx.Person">
	<property name="name">
		<value>小明</value>
	</property>
</bean>

	JDK类型注入
    <bean id="person" class="com.company.basic.Person">
        <property name="name" value="小明"/>
        <property name="id" value="123456"/>
    </bean>

    <!--	原本	-->
<bean id="userService" class="xxx.UserServiceImpl>
    <property name="userDao">
        <ref bean="userDao"/>
    </property>
</bean>

    用户自定义类型注入
    <bean id="userDao" class="com.company.basic.UserDaoImpl"/>

    <bean id="userService" class="com.company.basic.UserServiceImpl">
        <property name="userDao" ref="userDao"/>
    </bean>

3.2 基于p命名空间的简化

注意: value属性只能简化8种基本类型+String注入标签

JDK类型注入
<bean id="person" class="com.company.basic.Person" p:name="小明" p:id="5"/>

用户自定义类型注入
<bean id="userDao" class="com.company.basic.UserDaoImpl"/>

<bean id="userService" class="com.company.basic.UserServiceImpl" p:userDao-ref="userDao"/>

测试方法


    @Test
    public void test8(){
        ApplicationContext ctx = new ClassPathXmlApplicationContext("/applicationContext.xml");
        UserService userService = (UserService) ctx.getBean("userService");

        userService.register(new User("第一个","1234"));
        userService.login("第一个","4567");
    }


    @Test
    public void test9(){
        ApplicationContext ctx = new ClassPathXmlApplicationContext("/applicationContext.xml");
        Person person = (Person) ctx.getBean("person");

        System.out.println("person = " + person);
    }

构造注入、反转控制 与 依赖注入

注入分类

注入:通过Spring的配置文件,为成员变量赋值

Set注入:Spring调用Set方法通过配置文件为成员变量赋值

构造注入:Spring调用构造方法通过配置文件为成员变量赋值

1. 步骤

  • 提供有参构造方法
package com.company.basic.customer;

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

}

  • Spring的配置文件
    <bean id="customer" class="com.company.basic.customer.Customer">
        <constructor-arg>
            <value>张三</value>
        </constructor-arg>
        <constructor-arg>
            <value>123456</value>
        </constructor-arg>
    </bean>

2. 构造方法重载

参数个数不同时

通过控制<constructor-arg>标签的数量进行区分

构造参数个数相同时

通过在标签引入 type属性 进行类型的区分<constructor-arg type="">

3. 注入总结

未来的实战中, 应用set注入还是构造注入?

答案:set注入更多

  • 构造注入麻烦(重载)
  • Spring框架底层大量应用了set注入
    在这里插入图片描述

反转控制 与 依赖注入

1. 反转(转移)控制(IOC Inverse of Control)

控制:对于成员变量的控制权

反转控制:把对于成员变量赋值的控制权,从代码中反转(转移)到Spring工厂和配置文件中完成

  • 好处:解耦合

底层实现:工程设计模式
在这里插入图片描述

2.依赖注入(Dependency Injection DI)

注入:通过Spring的工厂及配置文件,为对象(bean, 组件)的成员变量赋值

依赖注入:当一个类需要另一个类时,就意味着依赖,一-旦出现依赖,就可以把另-个类作为本类的成员变量,最终通过Spring配置文件进行注入(赋值)。

  • 好处:解耦合
    在这里插入图片描述

Spring学习笔记:创建复杂对象、控制Spring工厂创建对象的次数

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值