欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

spring系列:三、Bean的实例化和获取

程序员文章站 2022-03-12 17:11:34
...

ApplicationContext与BeanFactory的关系

spring系列:三、Bean的实例化和获取

  • BeanFactory就是一个ioc容器,它采用的是延迟加载的策略,也就是只有在getBean的时候才会实例化bean
  • ApplicationContext是BeanFactory的扩展接口,它采用的是立即加载的策略,也就是在配置文件加载的时候就会实例化bean。它提供了不同应用层的context的实现,例如在web开发中可以使用的WebApplicationContext
  • FileSystemXmlAppliCationContext,ApplicationContext的实现类,根据文件路径获取获取配置文件
  • ClassPathXmlApplicationContext,ApplicationContext的实现类,根据文件名称在classpath路径下查找

Bean的实例化

  • 方式一:无参数构造

    <!-- 此种方式创建的bean必须提供无参构造 -->
    <bean name="bean1" class="cn.ade.domain.Bean1"/>
    
  • 方式二:静态工厂方法

    public class Bean3Factory {
    
        /**
         * 使用静态方法获取对象
         *
         * @return
         */
        public static Bean3 createBean3() {
            return new Bean3();
        }
    
    }
    
    <!-- 使用静态工厂的方法实例化对象 -->
    <bean name="bean3" class="cn.ade.utils.Bean3Factory" factory-method="createBean3"/>
    
  • 方式三:实例工厂方式

    public class Bean4Factory {
    
        /**
         * 使用非静态方法获取对象
         *
         * @return
         */
        public Bean4 getBean4() {
            return new Bean4();
        }
    
    }
    
    <!-- 使用实例工厂的方法实例化对象 -->
    <bean name="bean4Factory" class="cn.ade.utils.Bean4Factory"/>
    <bean name="bean4" factory-bean="bean4Factory" factory-method="getBean4"/>
    

bean的作用域

在创建bean的时候,有一个scope属性,可取的值:

  • singleton,默认,单例模式,ioc容器中只有一个bean的实例
  • prototype,多例模式,每次从ioc容器中获取bean的时候,都会实例化一个新的bean
  • request,用在web开发中,将bean存储在request域中。简单来讲,request可以看做prototype的一种特例,除了场景更加具体之外,语意上差不多。
  • session,用在web开发中,将bean存储在session域中。
  • global session,只有应用在基于porlet的web应用程序中才有意义,它映射到porlet的global范围的session,如果普通的servlet的web 应用中使用了这个scope,容器会把它作为普通的session的scope对待。

bean的生命周期

  • 第一步,instantiate bean,对象实例化 - 构造函数
  • 第二步,populate properties,封装属性 - set方法
  • 第三步,如果实现了BeanNameAware接口,执行方法setBeanName
  • 第四步,如果实现了 BeanFactoryAwar 或 ApplicationContextAwar 接口,在这里设置工厂 setBeanFactory 或上下文对象 setApplicationContext
  • 第五步,如果存在类实现 BeanPostProcess(后处理 Bean),执行 postProcessBeforeInitialization
  • 第六步,如果实现了InitializingBean接口,执行 afterPropertiesSet - 增强
  • 第七步,调用自定义的 init-method 方法
  • 第八步,如果存在类实现 BeanPostProcessor(处理 Bean),执行 postProcessAfterInitialization - 增强
  • 第九步,执行业务方法
  • 第十步,如果实现了 DisposableBean 执行 destroy
  • 第十一步,调用自定义的 destroy-method,destroy-method 只对 scope=singleTon 有效果
    spring系列:三、Bean的实例化和获取
public class Bean5 implements BeanNameAware, ApplicationContextAware, InitializingBean, DisposableBean {

    /**
     * 成员变量
     */
    private String info;

    /**
     * 空参构造
     * 在加载配置文件的时候,或者getBean的时候
     */
    public Bean5() {
        System.out.println("第一步:Bean5的实例化");
    }

    /**
     * 对成员变量info进行赋值
     *
     * @param info
     */
    public void setInfo(String info) {
        System.out.println("第二步:Bean5的属性注入");
        this.info = info;
    }

    /**
     * 如果 Bean 实现 BeanNameAware 执行 setBeanName
     *
     * @param s
     */
    @Override
    public void setBeanName(String s) {
        System.out.println("第三步:获取bean的id或name值:"+s);
    }

    /**
     * 如果 Bean 实现 BeanFactoryAwar 或 ApplicationContextAwar 设置工厂 setBeanFactory 或上下文对象 setApplicationContext
     *
     * @param applicationContext
     * @throws BeansException
     */
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        System.out.println("第四步:得到ApplicationContext对象:"+applicationContext);
    }

    /**
     * 如果 Bean 实现 InitializingBean 执行 afterPropertiesSet
     *
     * @throws Exception
     */
    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("第六步:属性注入完成后···");
    }

    /**
     * 调用自定义的 init-method 方法
     */
    public void MyInitMethod() {
        System.out.println("第七步:自定义的初始化方法");
    }

    /**
     * 测试方法
     */
    public void show() {
        System.out.println("第九步:执行业务操作");
    }

    /**
     * 如果 Bean 实现 DisposableBean 执行 destroy
     *
     * @throws Exception
     */
    @Override
    public void destroy() throws Exception {
        System.out.println("第十步:销毁");
    }

    /**
     * 调用自定义的 destroy-method,destroy-method 只对 scope=singleTon 有效果
     */
    public void MyDestroyMethod() {
        System.out.println("第十一步:自定义的销毁方法");
    }

}

public class MyBeanPostProcess implements BeanPostProcessor {

    /**
     * 如果存在类实现 BeanPostProcess(后处理 Bean),执行 postProcessBeforeInitialization
     *
     * @param o
     * @param s
     * @return
     * @throws BeansException
     */
    @Override
    public Object postProcessBeforeInitialization(Object o, String s) throws BeansException {
        System.out.println("第五步:存在类实现 BeanPostProcess(后处理 Bean),执行 postProcessBeforeInitialization");
        return o;
    }

    /**
     * 如果存在类实现 BeanPostProcessor(处理 Bean),执行 postProcessAfterInitialization
     *
     * @param o
     * @param s
     * @return
     * @throws BeansException
     */
    @Override
    public Object postProcessAfterInitialization(Object o, String s) throws BeansException {
        System.out.println("第八步:存在类实现 BeanPostProcessor(处理 Bean),执行 postProcessAfterInitialization");
        return o;
    }

}
<!-- Bean的声明周期 -->
<bean name="bean5" class="cn.ade.domain.Bean5" init-method="MyInitMethod" destroy-method="MyDestroyMethod" scope="singleton">
	<property name="info" value="Bean5"/>
</bean>
<bean class="cn.ade.utils.MyBeanPostProcess"/>
相关标签: spring 4