Spring框架之beans管理


前言

上文说道Spring IOC的思想:

Spring IOC容器通过读取配置文件,帮助我们创建各种各样的对象,以实现调用方和被调用方在编译阶段的解耦 ,这些由Spring IOC创建出来的对象统称为Bean;

在程序运行阶段,多个bean之间存在依赖关系(某1个Bean需要调用另外1个Bean),程序员如何告诉Spring IOC容器,如何管理它们呢?

当bean的控制权由调用方转交给IOC容器之后,我们可以通过Spring的xml配置文件和注解,控制bean的生命周期,进行Bean依赖的注入,实现对bean的管理;

一、Bean的作用域

在Spring中,bean支持多种作用域如下所示,我们可以通过配置文件和注解进行配置;

  • singleton(默认) 单例模式:即对象创建1次,创建之后一直存在,除非Spring IOC容器关闭;
  • prototype 多例模式:即每次获取bean的时候,IOC都给我们创建一个新对象
  • request域中生效:Spring创建一个Bean的对象,将对象存入到request域中
  • session域中生效:Spring创建一个Bean的对象,将对象存入到session域中

 1.Bean单例模式配置

<bean scope="singleton" id="UserDao" class="com.zhanggen.dao.impl.UserDaoImpl">

 2.Bean多例模式配置

<bean scope="prototype" id="UserDao" class="com.zhanggen.dao.impl.UserDaoImpl">

二、Bean的生命周期

生命周期指得是1个事物,从创建到销毁的过程; 

在Spring中,bean的作用范围会影响到其生命周期,所以我们要分单例和多例对象来研究bean的生命周期

init-method:指定的方法在当前对象(bean)创建之后执行

destroy-method指定的方法在当前对象(bean)销毁之前执行

 <bean init-method="UserDao" destroy-method="destory" id="UserDao" class="com.zhanggen.dao.impl.UserDaoImpl">

1.单例模式下bean的生命周期

创建:在容器创建的时候

销毁:在容器销毁的时候

2.多例模式下bean的生命周期

创建:每次调用getBean获取对象的时候

销毁:Spring不知道多例模式下,对象什么时候销毁;(bean创建之后Spring IOC容器就把对象交出去了,此时Spring IOC容器不再拥有bean的控制权);

三、Bean的依赖注入

依赖注入(Dependency Injection,DI) 其实就是给对象(bean)中的属性赋值

以下两种方式,都可以实现依赖注入,使用原则是能用set方法进行依赖注入尽量不使用构成函数;

  • 使用构造函数:如果类是别人写的,没有set方法时使用;
  • set方法:          推荐使用

1.通过构造函数进行依赖注入

在bean标签中嵌套constructor-arg标签可以完成bean对象构造函数赋值; 

1.1.在类中添加有参构造

public class UserDaoImpl implements UserDao {
    private String name;
    private Integer age;
    private Date brithday; //对象属性

    //添加无参构造器
    public UserDaoImpl() {

    }

    //添加全参构造器
    public UserDaoImpl(String name, Integer age, Date brithday) {
        this.name = name;
        this.age = age;
        this.brithday = brithday;
    }

1.2.通过配置文件配置属性的值

 
    <bean id="date" class="java.util.Date">bean>
    
    <bean id="UserDao" class="com.zhanggen.dao.impl.UserDaoImpl">
        <constructor-arg name="name" value="张根">constructor-arg>
        <constructor-arg name="age" value="18">constructor-arg>
        <constructor-arg name="brithday" ref="date">constructor-arg>
    bean>

1.3.测试

UserDaoImpl{name='张根', age=18, brithday=Wed May 18 21:08:06 CST 2022}

2.通过set方法进行依赖注入

在bean标签中嵌套property 标签可以完成bean对象构造函数赋值; 

2.1.在类中提供属性的set方法

//在类中提供属性的set()方法
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public Date getBrithday() {
        return brithday;
    }

    public void setBrithday(Date brithday) {
        this.brithday = brithday;
    }

2.2.在配置文件中设置属性的值

  
    <bean id="date" class="java.util.Date">bean>
    
    <bean id="UserDao" class="com.zhanggen.dao.impl.UserDaoImpl">
        <property name="name" value="张根">property>
        <property name="age" value="18">property>
        <property name="brithday" ref="date">property>
    bean>

2.3.测试

UserDaoImpl{name='张根', age=18, brithday=Wed May 18 21:27:22 CST 2022}

3.注入集合属性

在property 标签嵌套list、set、array、map标签,可以对bean对象的集合属性赋值;

3.1.增加集合复杂属性

package com.zhanggen.dao.impl;

import com.zhanggen.dao.UserDao;

import java.util.*;

public class UserDaoImpl implements UserDao {
    //简单类型属性
    private String name;
    private Integer age;
    //对象属性
    private Date brithday;
    //集合复杂属性
    private Set mySet;
    private List myList;
    private String[] myArr;
    private Map myMap;

    //在类中提供属性的set()方法
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public Date getBrithday() {
        return brithday;
    }

    public void setBrithday(Date brithday) {
        this.brithday = brithday;
    }

    public Set getMySet() {
        return mySet;
    }

    public void setMySet(Set mySet) {
        this.mySet = mySet;
    }

    public List getMyList() {
        return myList;
    }

    public void setMyList(List myList) {
        this.myList = myList;
    }

    public String[] getMyArr() {
        return myArr;
    }

    public void setMyArr(String[] myArr) {
        this.myArr = myArr;
    }

    public Map getMyMap() {
        return myMap;
    }

    public void setMyMap(Map myMap) {
        this.myMap = myMap;
    }

    public void save() {
        System.out.println("用户保存成功");
    }

    @Override
    public String toString() {
        return "UserDaoImpl{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", brithday=" + brithday +
                ", mySet=" + mySet +
                ", myList=" + myList +
                ", myArr=" + Arrays.toString(myArr) +
                ", myMap=" + myMap +
                '}';
    }
}
UserDaoImpl.java

3.2.配置文件赋值

   <bean id="UserDao" class="com.zhanggen.dao.impl.UserDaoImpl">
        <property name="name" value="张根">property>
        <property name="age" value="18">property>
        <property name="brithday" ref="date">property>
        <property name="myList">
            <list>
                <value>林心如value>
                <value>范冰冰value>
            list>
        property>
        <property name="mySet">
            <set>
                <value>CCvalue>
                <value>DDvalue>
            set>
        property>
        <property name="myArr">
            <array>
                <value>奔驰value>
                <value>宝马value>
            array>
        property>
        <property name="myMap">
            <map>
                <entry key="key1" value="18">entry>
                <entry key="key2" value="19">entry>
            map>
        property>
    bean>

3.3.测试


UserDaoImpl{name='张根', age=18, brithday=Wed May 18 21:50:56 CST 2022, mySet=[CC, DD], myList=[林心如, 范冰冰], myArr=[奔驰, 宝马], myMap={key1=18, key2=19}}

 

四、多配置文件使用

我们现在的配置都集中配在了一个applicationContext.xml文件中,这样会使这个文件很难维护。

针对这个问题,Spring给我们提供了两种解决方案:

  • 在创建springIOC容器的时,同时引入多个配置文件
  • 在主配置文件中引入其他配置文件

 注意:

  • 同一个xml文件中不允许出现相同id的bean,如果出现会报错
  • 多个xml文件如果出现相同id的bean,不会报错,但是后加载的会覆盖前加载,所以尽量保证bean的名称是唯一的

1.同时引入多个配置文件

在创建spring IOC容器时一次读取多个配置文件

 //1.读取多个配置文件,初始化SpringIOC容器
 ClassPathXmlApplicationContext act = new ClassPathXmlApplicationContext("applicationContext.xml","dateBean.xml");

2.引入1个主配置文件

spring IOC使用1个主配置文件,在主配置文件中引入其他配置文件


<import resource="dateBean.xml">import>

参考