Spring-IOC:复杂值注入、各种类型赋值、bean的复用

复杂值注入准备工作

从这里开始我们要进行复杂值的注入

创建 Car

public class Car {
    // 写入有参无参setget...
    private String carName;
    private Integer price;
    private String color;
}

创建Book

public class Book {
    // 写入有参无参setget...
    private String bookName;
    private Integer price;
}

Person类

public class Person {
    // 写入有参无参setget ToString...
    private String lastName;
    private String gender;
    private Integer age;
    private String email;

    private Car car;
    private List<Book> books;
    private Map<String,Object> maps;
    private Properties properties;
}

测试空值null

当注入bean不赋值

<bean id="person01" class="com.jiang.bean.Person">

</bean>

此时我们仅仅只是注册了 这个bean,但我们是没有进行任何赋值操作的

我们进行打印输出会得到

Person{lastName=‘null‘, gender=‘null‘, age=null, email=‘null‘, car=null, books=null, maps=null, properties=null}

会将他们的默认值输出,即为null

设置初始值

但此时我将Person 中的lastName设置初始值 "小姜"

public class Person {
    private String lastName = "小姜";
    ......

再次进行输出

Person{lastName=‘小姜‘, gender=‘null‘, age=null, email=‘null‘, car=null, books=null, maps=null, properties=null}

那么打印出来的话,则是 lastname="小姜"....

但如果我此时 我希望默认值小姜变成null 怎么做

<bean id="person01" class="com.jiang.bean.Person">
	可以在这里使用porperty进行赋值
    <property name="lastName" value="null"></property>
</bean>

此时打印

Person{lastName=‘null‘, gender=‘null‘, age=null, email=‘null‘, car=null, books=null, maps=null, properties=null}

好像是变成了lastname=null

但是当我们进行判断

Person person01 = app.getBean("person01", Person.class);
System.out.println(person01.getLastName() == null);

输出false 即不是真正的null 只是一个字符串null而已

解决方法

<bean id="person01" class="com.jiang.bean.Person">
	可以在这里使用porperty进行赋值
    <!-- <property name="lastName" value="null"></property> -->
    通过null 标签进行设置空值
	<property name="lastName">
		<null/>
    </property>
</bean>

复杂类型的赋值 在标签体里进行赋值

System.out.println(person01.getLastName() == null);

此时判断则为true

ref引入外部bean

ref :引用外面的值

<beans>
	<bean id="person01" class="com.jiang.bean.Person">
   	 	<property name="car" ref="car01"></property>
	</bean>

    <!--2.ref引用的car-->
    <bean id="car01" class="com.jiang.bean.Car">
        <property name="carName" value="milk"></property>
        <property name="color" value="white"></property>
        <property name="price" value="2000"></property>
    </bean>
</beans>

那么我们在person对象里 有private Car car 也就是在Person类中有Car对象

我们之前通过property赋值 ,都是赋给某个属性的值 :比如 name、age..... 那么我们此时如何赋给对象值呢

我们可以先将我们的car对象注册为一个bean 然后通过ref 引用我们这个bean

注意点:

? 1.我们在这里的ref 就是引用的下面car01的值

? 2.这个car 虽然是person01中的car,但其实他是引用的ioc容器中的car01

? 3.所以car == car01 当car01进行修改时,car的值也会随着改变


引入内部bean

其实就是在我们person01下 new了一个新的car对象

<beans >
    <bean id="person01" class="com.jiang.bean.Person">
        <!--3.bean标签在内部创建
            直接就是在这个person01下面新new了一个car对象
              -->
        <property name="car">
            <bean id="carbean" class="com.jiang.bean.Car">
                <property name="price" value="200"></property>
                <property name="color" value="black"></property>
                <property name="carName" value="mmm~"></property>
            </bean>
        </property>
    </bean>
</beans>

很简单 我们的car是个对象 不是个属性

那么我们就在property里注册一个新的bean


List类型赋值

1.在list标签中添加元素

    <bean id="person02" class="com.jiang.bean.Person">
        <property name="books">

            <list>
                <!--list标签中添加一个元素-->
                <bean class="com.jiang.bean.Book">
                    <property name="price" value="50"></property>
                    <property name="bookName" value="Spring5核心原理"></property>
                </bean>
            </list>
        </property>
    </bean>

<list></list> 其实就是books = new ArrayList<Book>()

为books赋值 就说向list集合books中添加元素

第一种方法就是直接通过bean标签 添加属性值 比较简单

2.ref引用

<bean id="book" class="com.jiang.bean.Book">
    <property name="bookName" value="高性能Netty"></property>
    <property name="price" value="55"></property>
</bean>

<bean id="person02" class="com.jiang.bean.Person">
    <property name="books">
        <!--books = new ArrayList<Book>()-->
        <list>
            <!--list标签中添加一个元素-->
            <bean class="com.jiang.bean.Book">
                <property name="price" value="50"></property>
                <property name="bookName" value="Spring5核心原理"></property>
            </bean>
            <!--ref引用-->
            <ref bean="book"></ref>
        </list>
    </property>
</bean>

首先在外面注册一个book的bean 赋于对应的值

然后在list内部 通过ref引用外面注册的这个bean 即ref引用的book

记得写法是 ref bean="book"

PS: 内部写的bean是不需要name的

你在beans下,也就是外面的bean是全局的 大家都可以用 你写name可以输出打印

但是你在property下的bean是内部的,不可以被随便打印,所以不需要name


Map类型赋值

<property name="maps">
    <!--map = new LinkedHashMap()-->
    <map>
        <!--一个entry 就代表一个键值对-->
        <entry key="key01" value="张三"></entry>
        <entry key="key02" value="18"></entry>
        <entry key="key03" value-ref="book"></entry>
        <entry key="key04">
            <bean class="com.jiang.bean.Book">
                <property name="bookName" value="SpringBoot实战开发"></property>
            </bean>
        </entry>
        <entry key="key05">
            <map></map>
        </entry>
    </map>
</property>

当你在property下,写一个map标签时,其实在底层就是给你new 了一个LinkedHaskMap()

每个entry 都代表一个键值对

  • 第一种方式就是 <entry key="键名" value="值">
  • 第二种方式是 key键名不变,值通过value-ref引入外面的值
  • 第三种方式是 在entry标签内部,键名不变,值是通过bean标签重新注入
  • 第四种方式是在map里集成map.....用的不多 省略

Properties

<property name="properties">
    <!--props = new Properties() -->
    <props>
        <!--所有的key=value 都是String类型 所以值都写在标签体中-->
        <prop key="username" >root</prop>
        <prop key="password">123456</prop>
    </props>
</property>

当你在property下,写一个props标签时,其实在底层就是给你new 了一个Properties()

所有的key=value 都是String类型 所以值都写在标签体中


util方式的map引用

引入util命名空间

<?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:util="http://www.springframework.org/schema/util"
        xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
        http://www.springframework.org/schema/util
        http://www.springframework.org/schema/util/spring-util-4.1.xsd">

在bean标签外创建util标签

    <util:map id="utilmap">
        <!--一个entry 就代表一个键值对-->
        <entry key="key01" value="王五"></entry>
        <entry key="key02" value="18"></entry>
        <entry key="key03" value-ref="book"></entry>
        <entry key="key04">
            <bean class="com.jiang.bean.Book">
                <property name="bookName" value="SpringBoot实战开发"></property>
            </bean>
        </entry>
        <entry key="key05">
            <map></map>
        </entry>

    </util:map>

Ps:我们这个util:map 是可以在全局进行访问的

map通过ref引入

<property name="maps" ref="utilmap"></property>

级联属性赋值

级联属性:属性的属性 比如Car.price

<bean id="person03" class="com.jiang.bean.Person">
    <!-- 为car赋值的时候 我要改变price -->
    <property name="car" ref="carbean"></property>
    <!--我们可以通过car.price 进行单独的修改 -->
    <property name="car.price" value="150"></property>
    <!--但是此时就出现了问题,我们发现无论是ioc中的car还是person03中的car的price都进行了改变
        这是因为我们获取car的方式是引用,所以我们进行修改的时候,其实是修改的引用地址的那个price
        所以级联属性可以对属性的属性进行修改,但可能会改变原来的值
        -->
</bean>
  • 我们可以通过car.price 进行单独的修改
  • 但是此时就出现了问题,我们发现无论是ioc中的car还是person03中的car的price都进行了改变
  • 这是因为我们获取car的方式是引用,所以我们进行修改的时候,其实是修改的引用地址的那个price
  • 所以级联属性可以对属性的属性进行修改,但可能会改变原来的值

继承实现bean的复用

<bean id="person01" class="com.jiang.bean.Person" abstract="true">
    <property name="lastName" value="马云"></property>
    <property name="age" value="50"></property>
    <property name="email" value="[email protected]"></property>
    <property name="gender" value="男"></property>

</bean>

此刻 我们希望有一个person02 他的属性值和person01相同

<!--parent:指定当前bean的配置信息继承于那个-->
<bean id="person02" class="com.jiang.bean.Person" parent="person01"></bean>

我们就可以使用parent属性

parent:指定当前bean的配置信息继承于那个

如果我们只希望person01只允许被继承,不允许被获取实例怎么办?

我们可以通过 abstrac=true来实现这个效果

<bean id="person01" class="com.jiang.bean.Person" abstract="true">
    <property name="lastName" value="马云"></property>
    <property name="age" value="50"></property>
    <property name="email" value="[email protected]"></property>
    <property name="gender" value="男"></property>
</bean>

原文地址:https://www.cnblogs.com/pengcode/p/12501000.html

时间: 2024-10-10 06:19:40

Spring-IOC:复杂值注入、各种类型赋值、bean的复用的相关文章

Spring根据XML配置文件注入对象类型属性

这里有dao.service和Servlet三个地方 通过配过文件xml生成对象,并注入对象类型的属性,降低耦合 dao文件代码: package com.swift; public class DaoUser { public void fun() { System.out.println("I'm dao's fun()...................."); } } service文件代码:(提供setter方法,xml文件可通过这种方法配置) package com.sw

spring ioc三种注入方式

spring ioc三种注入方式 IOC ,全称 (Inverse Of Control) ,中文意思为:控制反转 什么是控制反转? 控制反转是一种将组件依赖关系的创建和管理置于程序外部的技术. 由容器控制程序之间的关系,而不是由代码直接控制 由于控制权由代码转向了容器,所以称为反转 接口注入 Setter 注入 构造器注入 三种依赖注入方式的比较 : 接口注入: 接口注入模式因为历史较为悠久,在很多容器中都已经得到应用.但由于其在灵活性.易用性上不如其他两种注入模式,因而在 IOC 的专题世界

spring框架IOC设值注入

spring以动态的形式来管理对象,注入分为两种: 1. 设置注入:直观  自然 2.构造注入:可以在构造器中决定依赖顺序 以下就是示例: 1.User实体类 package com.domain; import java.io.Serializable; /** * * @author Mr * 实体类 */ public class User implements Serializable { private Integer id; private String uname; private

关于Spring IOC (DI-依赖注入)

<Spring入门经典>这本书无论对于初学者或者有经验的工程师还是很值一看的,最近花了点时间回顾了Spring的内容,在此顺带记录一下,本篇主要与spring IOC相关 ,这篇博文适合初学者也适合spring有过开发经验的工程师,前者可用于全面了解Spring IOC的知识点,后者且过目进而查漏补缺,ok~,以下是主要内容: Spring IOC 的原理概述 快速入门案例 Spring 容器装配BeanXML配置方式和注解配置方式 Spring 依赖注入 Setter注入 构造函数注入 循环

Spring IOC容器中注入bean

一.基于schema格式的注入 1.基本的注入方式 (属性注入方式) 根据setXxx()方法进行依赖注入,Spring只会检查是否有setter方法,是否有对应的属性不做要求 <bean id="student" class="com.lq.ioc.Student"> <property name="name" value="zhansan"></property> <propert

Spring Ioc和依赖注入

总结一下近来几天的学习,做个笔记 以下是Spring IoC相关内容: IoC(Inversion of Control):控制反转: 其主要功能可简单概述为:将 用 new 去创建实例对象,转换为让Spring通过配置xml文件去创建实例化 对象. 其实现原理大致为: 配置xml文件,通过解析xml文件,利用工厂模式和Java反射机制,实现对象实例的创建. 这一系列过程只需要我们配置相应的xml文件即可,其他的实现交由Spring容器. DI(Dependency Injection):依赖注

Spring 4.2 方法注入解决单例Bean的原型Bean依赖问题

当你在单例Bean中使用原型Bean依赖时,注意,依赖在实例化时解析.因此,如果你依赖注入一个原型Bean到单例Bean中,新的原型Bean被实例化然后依赖注入到单例Bean中.提供给单例Bean的原型实例是唯一的. 然而,假设你想单例Bean在运行时多次获取一个新的原型Bean的实例.你不能依赖注入一个原型Bean到你的单例Bean中,因为注入只发生一次,当Spring容器实例化单例Bean时解析并注入它的依赖.如果你在运行时多次需要一个新的原型Bean,可以使用方法注入. 在大多数应用程序情

Spring IOC 容器源码分析 - 创建原始 bean 对象

1. 简介 本篇文章是上一篇文章(创建单例 bean 的过程)的延续.在上一篇文章中,我们从战略层面上领略了doCreateBean方法的全过程.本篇文章,我们就从战术的层面上,详细分析doCreateBean方法中的一个重要的调用,即createBeanInstance方法.在本篇文章中,你将看到三种不同的构造 bean 对象的方式.你也会了解到构造 bean 对象的两种策略.如果你对这些内容感兴趣,那么不妨继续往下读.我会在代码进行大量的注解,相信能帮助你理解代码逻辑.好了,其他的就不多说了

浅析Spring IOC、依赖注入(DI)和依赖查找(DL)

为什么要用IOC? 第一:对象的实例化不是一件简单的事情,比如对象的关系比较复杂,依赖关系往往需要程序员去维护,这是一件非常头疼的事. 第二:解耦,由容器去维护具体的对象 第三:托管了类的产生过程,比如我们需要在类的产生过程中做一些处理,最直接的例子就是代理,如果有容器程序可以把这部分过程交给容器,应用程序则无需去关心类是如何完成代理的 控制反转(Inverse of Control) 控制反转即IoC(Incersion of Control),从字面上理解就是控制反转,将对在自身对象中的一个

【SSH系列】深入浅出spring IOC中三种依赖注入方式

spring的核心思想是IOC和AOP,IOC-控制反转,是一个重要的面向对象编程的法则来消减计算机程序的耦合问题,控制反转一般分为两种类型,依赖注入和依赖查找,依赖什么?为什么需要依赖?注入什么?控制什么?依赖注入和控制反转是一样的概念吗?接触新的知识,小编的脑袋中全是大大的问号,不过没有关系,今天这篇博文,小编主要来简单的介绍一下在spring IOC中依赖注入的方法. 依赖注入和控制反转,目的是为了使类与类之间解耦合,提高系统的可扩展性和可维护性.我们可以从以下几个方面理解: a.参与者都