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

ApplicationContext与BeanFactory的关系

在这里插入图片描述

  • 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 有效果
    在这里插入图片描述
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"/>
发布了48 篇原创文章 · 获赞 1 · 访问量 1053

猜你喜欢

转载自blog.csdn.net/laonxs/article/details/104998118