spring日记(二):Ioc容器

本人博客已搬家,新地址为:http://yidao620c.github.io/

spring在DefaultSingletonBeanRegistry类提供了一个用于缓存单例Bean的缓存器,它是一个用HashMap实现的缓存器,单实例的Bean以beanName为键保存在这个HashMap中。在初始化BeanFactory的时候,必须为其指定一个日志框架,一般来讲使用Log4j或者lsf4J即可。

如果说BeanFactory是spring的心脏,那么ApplicationContext就是完整的身躯了。ApplicationContext由BeanFactory派生而来,提供了更多面向实际应用的功能。在BeanFactory中,很多功能需要编程实现,但是ApplicationContext可以配置实现。

ApplicationContext的主要派生类是ClassPathXmlApplicationContext和FileSystemXmlApplicationContext,前者默认从类路径加载配置文件,后者默认从文件系统装载配置文件。

ApplicationContext跟BeanFactory的很大一个区别是:ApplicationContext在初始化的时候就实例化了所有单例Bean,而BeanFactory的策略是lazy load。

Bean的生命周期详解:

1,通过getBean()调用某一个Bean

2,* 如果容器注册了InstantiationAwareBeanPostProcessor接口,调用InstantiationAwareBeanPostProcessor的postProcessBeforeInstantiation()方法

3,根据配置调用Bean构造函数或者是工厂方法实例化Bean

4,* 如果容器注册了InstantiationAwareBeanPostProcessor接口,调用InstantiationAwareBeanPostProcessor的postProcessAfterInstantiation()方法

5,* 如果容器注册了InstantiationAwareBeanPostProcessor接口,在设置每个属性之前会先调用InstantiationAwareBeanPostProcessor的postProcessPropertyValues()方法,这个和下面的6在一个属性设置循环体中

6,根据配置文件设置属性值

7,如果Bean实现了BeanNameAware接口,调用BeanNameAware的setBeanName()方法,将配置文件中该Bean对应的名称设置到Bean中

8,如果Bean实现了BeanFactoryAware接口,调用BeanFactoryAware的setBeanFactory()方法,将BeanFactory容器实例设置到Bean中

9,* 如果BeanFactory装配了BeanPostProcessor后处理器,调用BeanPostProcessor的postProcessBeforeInitialization()方法,对Bean进行加工处理。用户可以使用该方法对某些Bean进行特殊处理,甚至改变Bean的行为,BeanPostProcessor在spring里面占用特殊地位,spring容器所提供的AOP,动态代理等都是通过BeanPostProcessor实施的

10,如果Bean实现了InitializationBean的接口,调用InitializationBean的afterPropertiesSet()方法

11,如果Bean定义了init-method,通过init-method属性配置调用相应的初始化方法

12,* 如果BeanFactory装配了BeanPostProcessor后处理器,容器再次获得对Bean进行加工处理的机会,调用BeanPostProcessor的postProcessAfterInitialization()方法

13-1,如果是singleton的bean就放入spring缓冲池,然后容器销毁的时候,如果Bean实现了DisposableBean接口,此时会调用DisposableBean的afterPropertiesSet()方法,然后再调用destory-method方法,Bean周期结束。

13-2,如果是prototype的话就将准备就绪的Bean交给调用者

注:

Bean级生命周期接口方法:BeanNameAware、BeanFactoryAware、InitializationBean、DisposableBean,这些接口方法友Bean类直接实现

容器级生命周期接口方法:在上面带*号的都是,由InstantiationAwareBeanPostProcessor和BeanPostProcessor这两个接口实现,一般称它们为后处理器。它们独立于Bean,实现类以容器附加装置的形式注册到spring容器中并通过接口反射为spring容器预先识别。当spring容器创建任何Bean的时候,这些后处理器都会发生作用,所以是全局性的。

从spring3.0开始支持基于类注解的配置方式:

 

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
 
import com.springzoo.Car;
 
@Configuration
public class Beans {
 
    @Bean(name = "car")
    public Car buildCar() {
        Car car = new Car();
        car.setBrand("红旗CA72");
        car.setMaxSpeed(200);
        return car;
    }
}
 

 

spring为基于注解类的配置提供了专门的ApplicationContext实现类:AnnotationConfigApplicationContext,来看看怎么使用的:

 

ApplicationContext ctx = new AnnotationConfigApplicationContext(Beans.class);
Car car =ctx.getBean("car",Car.class);

 

WebApplicationContext是专门为Web应用准备的,它允许从相对于Web根目录装载配置文件来完成初始化工作,有个工具类WebApplicationContextUtils,通过它的getWebApplicationContext(ServletContext sc)方法,可以从ServletContext中获取WebApplicationContext实例。spring2.0还在WebApplicationContext中为Bean增加了三个新的作用域:request、session、global session,在非web环境下,只有singleton和prototyoe两种作用域。

WebApplicationContext中有一个常量:ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE,以此为键存在ServletContext中,如此实现了WebApplicationContext和ServletContext的互访:

ServletContext sc = WebApplicationContext.getServletContext()

WebApplicationContext wac = WebApplicationContextUtils.getWebApplicationContext(sc)

ConfigurableWebApplicationContext扩展了WebApplicationContext,它允许通过配置文件实例化WebApplicationContext,它有两个重要方法:

* setServletContext(ServletContext sc):为spring设置Web应用上下文

* setConfigLocations(String[] configLocations):设置spring配置文件路径,一般都是现对于Web根目录,如:/WEB-INF/springzoo-dao.xml、/WEB-INF/springzoo-service.xml

初始化:

通过在web.xml中定义ContextLoaderServlet或者是ContextLoaderListener即可:

<!-- ① 从类路径下加载spring配置文件,classpath关键字特指类路径下加载
    多个配置文件用逗号,分开-->
<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:applicationContext.xml,/WEB-INF/springzoo-service.xml</param-value>
</context-param>
<!-- ② 负责启动spring容器的监听器,该监听器在web容器启动时候自动运行,
    它将引用①处的上下文参数获得的spring配置文件地址-->
<listener>
    <listener-class>
        org.springframework.web.context.ContextLoaderListener
    </listener-class>
</listener>

你可能感兴趣的:(spring)