Spring--Bean对象详解

在Spring中,对象无需自己查找或创建与其所关联的其他对象(解耦合)。
Spring容器负责创建应用程序中的bean并通过DI来协调Java对象之间的关系。
创建应用对象之间协作关系的行为通常称为装配(wiring),这也是依赖注入(DI)的本质。

总而言之,bean对象就是应用程序中的Java对象,Spring容器创建并封装这些Java对象为容器中的bean对象,在需要时自动注入到变量中,赋予对应Java对象的实例。

Spring配置bean的三种方式

  • 1.在XML中进行显式配置。
  • 2.在Java中进行显式配置。
  • 3.隐式的bean发现机制和自动装配。

本文以XML中的显式配置介绍bean对象的创建方式、作用范围、生命周期等。

创建bean的方式

1 通过构造函数创建Java对象对应的bean
1.1 无参构造函数(默认构造函数)
<bean id="accountService" class="com.simple.service.impl.AccountServiceImpl" ></bean>

如上,通过AccountServiceImpl的默认构造函数创建了AccountServiceImpl实例化的bean对象。在Java代码中定义的 AccountServiceImpl 类或其父类对象变量,会根据变量名对应bean的id自动注入。

1.1 带参构造函数
<bean id="accountDao" class="com.simple.Dao.impl.AccountDaoImpl" ></bean>

<bean id="accountService" class="com.simple.service.impl.AccountServiceImpl" >
	<constructor-arg ref="accountDao"></constructor-arg>
	<constructor-arg value="#{T(其他各种类型,如string等等)}"></constructor-arg>
</bean>        

accountDao代表在AccountServiceImpl类构造函数中需要注入的Java对象,ref 属性的值为该Java对象对应的bean的id值;#{T}是Spring中的EL表达式,T表示构造函数中带有的其他类型参数(基本类型,如String等等)。

2 使用普通工厂中的方法创建对象,并存入指定的bean

使用某个工厂类中的方法创建Java对象,并存入spring容器。

工厂类:

public class InitFactory {
    public IAccountService getAccountService(){
        return new AccountServiceImpl();
    }
}

XML配置:

<bean id="initFactory" class="com.simple.factory.InitFactory"></bean>
<bean id="accountService" factory-bean="initFactory" factory-method="getAccountService"></bean>
3 使用工厂中的静态方法创建对象,并存入指定的bean

使用某个类中的静态方法创建Java对象,并存入spring容器。由于使用的是工厂中的静态方法,所以不需要实例化工厂。

工厂类:

public class staticFactory {
    public static IAccountService getAccountService(){
        return new AccountServiceImpl();
    }
}

XML配置:

<bean id="accountService" class="com.simple.factory.staticFactory" factory-method="getAccountService"></bean>

上述三种创建bean的方式中,一般使用第1种方法通过构造函数创建bean。

bean的作用范围

bean的作用范围由 bean 标签的 scope 属性来指定。其属性值包括:

属性值 说明
singleton 默认值,指定bean为单例的
prototype 指定bean为多例的
request web项目中,作用于request域
session web项目中,作用于session域
global-session web项目中,作用于集群环境的session域;若不是集群环境,则相当于session

一般常用的是 singleton ,即单例的。

单例的bean表示Spring容器中该bean只有一个对应的实例化Java对象;多例的bean表示Spring容器中该bean可以有对应类多个实例化Java对象(可通过其存储地址区分)。

bean对象的生命周期

1 单例bean
  1. 默认情况下,Spring读取XML配置文件创建Spring容器时bean对象就会被创建
  2. 在创建对象时,先执行对象的构造方法,然后调用bean标签的 init-method="..."属性值中指定的方法
  3. 在Spring容器销毁时,单例bean随之消亡。bean消亡即对象被销毁时,会调用bean标签的 destroy-method="..."属性值中指定的方法
  4. 可以设置bean标签的 lazy-init="true" 使该对象在第一次被访问时才创建

XML配置:创建单例bean,指定init-method="..."destroy-method="..."属性

<bean id="accountService" class="com.simple.service.impl.AccountServiceImpl"
	scope="singleton" init-method="init" destroy-method="destory">
</bean>

AccountServiceImpl 类:

public class AccountServiceImpl implements IAccountService {

    //默认无参构造器
    public AccountServiceImpl() {
        System.out.println("对象已创建!");
    }

    public void saveAccount() {
        System.out.println("Service中的saveAccount方法执行了!!");
    }

    //初始时执行方法
    public void init(){
        System.out.println("对象初始化了!!!");
    }

    //销毁时执行方法
    public void destory(){
        System.out.println("对象销毁了!!!");
    }
}

测试单例bean的生命周期:

public class Client {

    public static void main(String[] args) {
        //1.获取Spring核心容器对象
        ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");   //bean.xml放在根目录下,所有可以直接写文件名
        //2.根据id获取bean对象
        //可以使用强制类型转换
        //IAccountService as = (IAccountService) ac.getBean("accountService");
        //也可以指定对象类型
        IAccountService as = ac.getBean("accountService",IAccountService.class);
        //查看创建的as对象
        System.out.println(as);

		//执行as对象的方法
        as.saveAccount();

        //手动销毁Spring容器,查看as对象消亡过程
        ac.close();
        System.out.println("结束!");
    }
}

结果如下:
在这里插入图片描述

2 多例bean
  1. Spring读取XML配置文件创建Spring容器时,不会立刻创建多例bean对应的对象
  2. 在每一次访问这个多例bean对应的对象的时,spring容器都会创建该对象,并且调用init-method=".."属性值中所指定的方法
  3. Spring容器销毁时,多例bean对应创建的对象也不会消亡。因为是多例的(该类型的对象可以有多个),所以在Spring容器创建该对象并将它赋予给Java变量后,该对象就由Java的进行管理,销毁该对象也由垃圾回收机制进行回收。spring容器一旦把这个对象交给Java之后,就不再管理这个对象了
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章