spring加载应用上下文的几种方式
1、AnnotationConfigApplicationContext:从一个或多个基于Java配置类中加载spring应用上下文,适用于Java注解方式;
如果想从Java配置中加载应用上线文,可以按照如下方式加载:
ApplicationContext context = new AnnotationConfigApplicationContext(com.springaction.knights.config.KnightCongig.class);
2、AnnotationConfigWebApplicationContext:从一个或多个基于Java配置类中加载Spring Web应用上下文,专门为web应用准备的,适用于注解方式;
3、ClassPathXmlApplicationContext:从类路径下的一个或者多个xml配置文件中加载上线文定义,把应用上下文的定义文件作为类资源,适用于xml配置方式;
ApplicationContext context = new ClassPathXmlApplicationContext("knight.xml");
4、FileSystemXmlApplicationContext:从文件系统下的一个或者多个xml配置文件中加载上下文定义
ApplicationContext context = new FileSystemXmlApplicationContext("c:/knight.xml");
5、XmlWebApplicationContext:从web应用的一个或者多个xml配置文件中加载上下文定义,适用于xml配置方式;
应用上下文准备好之后,我们就可以通过调用上下文的getBean()方法从spring容器中获取bean了。
bean的生命周期:
在spring中,从BeanFactory或ApplicationContext取得的实例为Singleton,也就是预设为每一个Bean的别名只能维持一个实例,而不是每次都产生一个新的对象使用Singleton模式产生单一实例,对单线程的程序说并不会有什么问题,但对于多线程的程序,就必须注意安全(Thread-safe)的议题,防止多个线程同时存取共享资源所引发的数据不同步问题。
然而在spring中 可以设定每次从BeanFactory或ApplicationContext指定别名并取得Bean时都产生一个新的实例:例如:
在spring中,singleton属性默认是true,只有设定为false,则每次指定别名取得的Bean时都会产生一个新的实例。
一个Bean从创建到销毁,如果是用BeanFactory来生成,管理Bean的话,会经历几个执行阶段(如图1.1):
- Bean的建立
容器寻找Bean的定义信息并将其实例化。相当于:Object obj = new Object(); - 属性注入
使用依赖注入,Spring按照Bean定义信息配置Bean所有属性 - BeanNameAware的setBeanName()
如果Bean类有实现org.springframework.beans.BeanNameAware接口,工厂调用Bean的setBeanName()方法传递Bean的ID。 - BeanFactoryAware的setBeanFactory():
如果Bean类有实现org.springframework.beans.factory.BeanFactoryAware接口,工厂调用setBeanFactory()方法传入工厂自身。 - BeanPostProcessors的ProcessBeforeInitialization().
如果有org.springframework.beans.factory.config.BeanPostProcessors和Bean关联,那么其postProcessBeforeInitialization()方法将被将被调用。 - initializingBean的afterPropertiesSet():
如果Bean类已实现org.springframework.beans.factory.InitializingBean接口,则执行他的afterProPertiesSet()方法 - Bean定义文件中定义init-method:
可以在Bean定义文件中使用”init-method”属性设定方法名称例如:如果有以上设置的话,则执行到这个阶段,就会执行initBean()方法 - BeanPostProcessors的ProcessaAfterInitialization()
如果有任何的BeanPostProcessors实例与Bean实例关联,则执行BeanPostProcessors实例的ProcessaAfterInitialization()方法
此时,Bean已经可以被应用系统使用,并且将保留在BeanFactory中知道它不在被使用。有两种方法可以将其从BeanFactory中删除掉
- DisposableBean的destroy()
在容器关闭时,如果Bean类有实现org.springframework.beans.factory.DisposableBean接口,则执行他的destroy()方法 - Bean定义文件中定义destroy-method
在容器关闭时,可以在Bean定义文件中使用”destroy-method”属性设定方法名称.
以上就是BeanFactory维护的一个Bean的生命周期。下面这个图可能更直观一些:
如果使用ApplicationContext来维护一个Bean的生命周期,则基本上与上边的流程相同,只不过在执行BeanNameAware的setBeanName()后,若有Bean类实现了org.springframework.context.ApplicationContextAware接口,则执行其setApplicationContext()方法,然后再进行BeanPostProcessors的processBeforeInitialization()
实际上,ApplicationContext除了向BeanFactory那样维护容器外,还提供了更加丰富的框架功能,如Bean的消息,事件处理机制等