Spring随笔(04)

1、IoC容器

  ObjectFactory与ApplicationContext(继承ObjectFactory);

  BeanFactory这个接口是Spring中最底层的接口,只提供最简单的IoC功能(创建Bean、获取Bean、销毁Bean)。

  在一般的应用当中,一般不使用BeanFactory,推荐用ApplicationContext(应用上下文)。

    1)ApplicationContext继承了BeanFactory,提供了基本的IoC功能;

    2)ApplicationContext还提供了其他功能:

      ①支持国际化;

      ②支持消息机制;

      ③支持统一的资源加载;

      ④支持AOP功能;

 

  Resource常见实现类:

    1)ClassPathResource:从classpath根路径开始找配置文件;

    2)FileSystemResource:从磁盘的文件路劲去找;

    3)ServletContextResource:应用于web中,从web中去找配置文件。

 

  ApplicationContext创建Bean步骤:

ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
HelloWorld helloWorld = ctx.getBean("helloWorld",HelloWorld.class);
helloWorld.sayHello();

 

  ApplicationContext常用实现类:

    1)ClassPathXmlApplicationContext:读取classpath中的资源;

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

    2)FileSystemXmlApplicationContext:读取指定路径的资源;

      ApplicationContext ac = new FileSystemXmlApplicationContext("c:/applicationContext.xml");

    3)XmlWebApplicationContext:需要在Web的环境下才能运行;

      XmlWebApplicationContext ac = new XmlWebApplicationContext(); // 这时并没有初始化容器

      ac.setServletContext(servletContext); // 需要指定ServletContext对象;

      ac.setConfigLocation("/WEB-INF/applicationContext.xml"); // 指定配置文件路径,开头的/表示根目录

      ac.refresh(); // 初始化容器

 

2、Bean的创建时机

  1)BeanFactory需要等到获取Bean的时候才会创建Bean(延迟初始化);(桌面程序建议使用)

  2)ApplicationContext在加载的时候就会创建所有的Bean;(web应用建议使用)

  ApplicationContext如何延迟加载:

  <bean id="helloWorld" class="com.test.HelloWorld"> // 默认不延迟初始化

  <bean id="helloWorld" class="com.test.HelloWorld" lazy-init="default"> // 默认不延迟初始化

  <bean id="helloWorld" class="com.test.HelloWorld" lazy-init="false"> // 不延迟初始化

  <bean id="helloWorld" class="com.test.HelloWorld" lazy-init="true"> // 延迟初始化

  针对当前xml中所有Bean:

  <beans default-lazy-init="default | false | true">

  针对指定的Bean:

  <bean lazy-init="default | false | true">

 

3、Bean的作用域(Bean对象可以存活多久)

  <bean id="" class="" scope="作用域"/>

  singleton:单例,在Spring Ioc容器中仅存在一个Bean实例(默认的scope);

  prototype:多例(原型),每次从容器中调用Bean时,都返回一个新的实例,即每次调用getBean()时,相当于执行new XxxBean(),不会在容器启动时创建对象;

  request:用于web开发,将Bean放入request范围,request.setAttribute("xxx"),在同一个request获得同一个Bean;

  session:用于web开发,将Bean放入Session范围,在同一个session中获得同一个Bean;

  globalSession:一般用于Porlet应用环境,分布式系统存在全局session概念(单点登录),如果不是porlet环境,globalSession等同于Session。

  在开发中主要使用scope="singleton"、scope="prototype",对于MVC中的Action使用prototype类型(否则会有安全性问题),其他使用singleton。

  

4、Bean的初始化和销毁方法

  <!--

    Class clz = Class.forName("com.test.HelloWorld");

    ①SomeBean bean = (SomBean) clz.newInstance();

    ②Method initMethod = clz.getMethod("init");

     initMethod.invoke(bean);

     ...bean的其他操作

    ③Method destroyMethod = clz.getMethod("destroy");

     destroyMethod.invoke(bean);

  -->

  <bean id="helloWorld" class="com.test.HelloWorld" init-method="init" destroy-method="destroy">

  如DataSource、SessionFactory等最终都需要关闭资源,在Bean销毁之前,都要调用close方法。

  <bean id="..." class="..." init-method="该类中的初始化方法名" destroy-method="该类中的销毁方法名"/>

  init-method:Bean生命周期初始化方法,对象创建后就进行调用;

  destroy-method:容器被销毁的时候,如果Bean被容器管理,会调用该方法。

  如果Bean的scope="prototype",那么容器只负责创建和初始化,它并不会被spring容器管理。

 

  如果不使用Spring容器进行测试,而使用传统测试,Spring容器将非正常关闭。

  单元测试的线程很短(获取网络信息时,不要使用单元测试,而要使用主方法)。

  若要正常关闭Spring容器,使用AbstractApplicationContext

  // 关闭上下文对象

  ctx.close();

  // 最好的方式是:把Spring线程昨晚JVM的子线程

  ctx.registerShutdownHook();

  

5、Bean的生命周期

 

posted @ 2017-02-17 18:01  LuoMsg  阅读(144)  评论(0编辑  收藏  举报