Spring学习(3)

来源:互联网 发布:英文发音软件 编辑:程序博客网 时间:2024/06/06 10:31

上一节中,我们深入了解了Spring中bean之间是如何进行关联的以及简单了解控制反转和依赖注入。这一节中,我们主要来说说bean。

一、从applicationContext应用上下文和bean工厂中获得bean有什么区别?

  1. bean的作用域(4种)

    singleton:在每个Spring IOC容器中一个bean定义对应一个对象实例。(只要容器存在,那么就只有一个bean。比如说
    Student st1 =(Student) ac.getBean(“student”);
    Student st2 =(Student) ac.getBean(“student”);
    这样创建出的只是一个Student对象。)

    prototype:一个bean定义对应多个 (每获得一个bean就是一个全新的bean。比如说
    Student st1 =(Student) ac.getBean(“student”);
    Student st2 =(Student) ac.getBean(“student”);
    这样创建出的却是两个不同的Student对象。))

    request:在一次http请求中,一个bean定义对应一个实例;即每次http请求将会有各自的bean实例,他们依据某个bean定义创建而成。该作用域仅在基于web的Spring ApplicationContext情形下有效。(一次请求有效)

    global Session:在一个全局http Session中,一个bean定义对应一个实例。典型情况下,仅在使用portlet context的时候有效。该作用域仅在基于web 的Spring applicationContext情形下有效。(只要Spring容器不关闭,那么他就一直有效)

  2. 创建bean的方式

    • 利用ApplicationContext创建

    当bean的scope是 singleton时,程序一旦执行

    ApplicationContext    ac=       new ClassPathXmlApplicationContext("applicationContext.xml");

    时,程序会自动加载Spring容器,并且将里面的bean实例化。 但是,当我们设置scope是prototype的时候,他依然是延时加载的。

    • 利用bean工厂来创建
      程序一旦执行

      BeanFactory factory = new XmlBeanFactory( new ClassPathResource("applicationContext.xml"));

    时,程序只是对该容器进行实例化,并不会马上实例化容器中的bean,当我们使用getbean方法去得到某个bean时,才会实时创建出该对象。

    从上面的描述中我们可以清楚地知道,利用ApplicationContext的方式(scope=”singleton”)获得bean可以增加程序的运行速度,因为他可以预先加载所有单例模式的bean,确保应用不需要等待他们被创建。利用bean工厂可以节省内存。
    但是我们通常还是用ApplicationContext的方式来获得bean。

二、bean的生命周期

1. 实例化
当程序加载.xml文件的时候就开始实例化。把我们的bean(单态的)实例化到内存中(使用无参的构造函数来实例化)。

    <bean id="userService" class="rogue.UserService" />

2. 设置属性
调用set方法设置属性
3. 如果实现了BeanNameAware接口并且实现了setBeanName()方法

    public void SetName(Stirng arg0){}

该方法可以用arg0表示正在被实例化的bean的id(返回的值取决于你在配置文件中的id设置的是什么。)
4. 如果实现了BeanFactoryAware接口并且调用了setBeanFactory()方法

    public void setBeanFactory(BeanFactory arg0) throws BeanException{}

该方法可以用arg0传递所使用的beanFactory对象
5. 如果实现了ApplicationContextAware接口并且调用了setApplicationContext()方法

    public void setApplicationContext(ApplicationContext arg0)  throws BeansException{}

那么可以通过arg0传递获取ApplicationContext的方式。(获取方式有三种,这里不细说,立一个flag)

6. 调用BeanPostProcessor(后置处理器)的预初始化方法(before)
这个处理器不是直接在该bean中实现的(也就是不能在bean中直接用implements),而是通过在.xml配置文件中配置来完成的。
如果实现了这个接口,则会自动调用Before方法。
使用方法如下:
a、首先创建一个类MyBeanPostProcessor,实现BeanPostProcessor接口
b、然后在MyBeanPostProcessor中的初始化方法

    @Override    public Object postProcessBeforeInitialization(Object arg0, String arg1)   throws BeansException {    // TODO Auto-generated method stub    return null;    }

中写入自己的功能函数。这里的arg0指的就是调用这个方法的对象,return的时候要将其返回,而不能是空。
c、在xml文件中配置

    <bean id="myBeanPostProcessor" class="rogue.MyBeanPostProcessor"/>

7. 如果实现了InitializingBean接口,则会调用afterPropertiesSet()方法。

    public void afterPropertiesSet() throws Ecception{}

8. 自定义初始化方法
我们还可以在自己的bean中配置初始化方法,如果我们在bean中配置了这样的方法

     <bean id="userService" init-method="init" class="rogue.UserService" />

这样,在自己UserService中添加一个

    public void init(){}

方法,则他会在第七步(如果有的话)执行完之后被调用

9. 调用BeanPostProcessor(后置处理器)的预初始化方法(after)

    public Object postProcessAfterInitialization(Object arg0, String arg1)  throws BeansException {    // TODO Auto-generated method stub    return null;    }

10、bean可以被使用

11、容器关闭

12、可以通过实现DisposableBean接口来调用方法destiny

13、容器销毁(我们可以关闭数据连接,socket,文件流,释放该bean占用的资源),也可以用自定义销毁方法来实现。如果没有,则程序自动销毁。

<bean id="userService" destroy-method="myDestroy" class="rogue.UserService" />

下面是执行的结果:
这里写图片描述
这里写图片描述


下面是bean执行顺序图
这里写图片描述

我们在实际开发中,往往用不到这么多的过程,常见的过程有:
1->2->6->9->10->11

三、利用BeanFactory来获取bean对象
以上是利用ApplicationContext来获取bean的过程,那么利用BeanFactory来获取bean对象是怎样的流程呢?
这里写图片描述

从运行结果中我们可以看出,运行的流程是这样的
这里写图片描述

0 0
原创粉丝点击