spring有两个核心接口:BeanFactory和ApplicationContext,其中ApplicationContext是BeanFactory的子接口。它们都可代表spring容器,spring容器是生成Bean实例的工厂,并管理容器中的Bean,所有的组件都被当成Bean处理。

1.Spring容器

spring容器最基本的接口是BeanFactory,BeanFactory负责配置、创建、管理Bean。有一个子接口:ApplicationContext,被称为spring上下文。spring容器还负责管理Bean与Bean之间的依赖关系。
Bean接口包含如下几个基本方法:

  • boolean containsBean(String name)
  • <T> T getBean(Class<T> requiredType)
  • Object getBean(String name)
  • <T> T getBean(String name,Class requiredType)
  • Class<?> getType(String name)
    BeanFactory常用的实现类是DefaultListableBeanFactory。
    ApplicationContext常用的实现类是FileSystemXmlApplicationContext、ClassPathXmlApplicationContext、AnnotationConfigApplicationContext。如果在Web应用中使用spring容器,则通常有XmlWebApplicationContext、AnnotationConfigWebApplicationContext两个实现类。
2.使用ApplicationContext

ApplicationContext允许以声明式方式操作容器,无须手动创建它。可利用如ContextLoader的支持类,在Web应用启动时自动创建ApplicationContext。
当系统创建ApplicationContext容器时,默认会预初始化所有的singleton Bean,包括调用构造器创建该Bean的实例,并根据<property.../>元素执行setter方法。
如果为<bean.../>元素指定了lazy-init=”true”,那么即使使用ApplicationContext作为容器,spring也不会预初始化该singleton Bean。

3.ApplicationContext的国际化支持

ApplicationContext接口继承了MessageSource接口,因此具有国际化功能。
MessageSource接口中定义的两个用于国际化的方法:

  • String getMessage(String code,Object[] args,Local loc)
  • String getMessage(String code,Object[] args,String default,Local loc)
    当程序创建ApplicationContext容器时,Spring自动查找配置文件中名为messageSource的Bean实例,一旦找到了这个Bean实例,上述两个方法的调用就被委托给该messageSource Bean。如果没有该Bean,ApplicationContext会查找其父容器中的messageSource Bean,如果还是无法找到,系统将会创建一个空的StaticMessageSource Bean,该Bean能接受上述两个方法的调用。
    在spring中配置messageSource Bean时通常使用ResourceBundleMessageSource类。
<bean id="messageSource" class="org.framework.context.support.ResourceBundleMessageSource">
        <property name="basenames">
            <list>
                <value>message</value>
            </list>
        </property>
    </bean>

message.properties
hello=欢迎你,{0}
now=现在的时间是:{0}

springTest.java
main{
    ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
    String hello = ctx.getMessage("hello",new String[]{"猴子"},Locale.getDefault(Locale.Category.FORMAT));
    String now = ctx.getMessage("now",new Object[]{new Date()},Local.getDefault(Local.Category.FORMAT));
}
4.ApplicationContext的事件机制

ApplicationContext的事件机制是观察者设计模式的实现,通过ApplicationEvent类和ApplicationListener接口,可以实现ApplicationContext的事件处理。如果容器中有一个ApplicationListener Bean,每当ApplicationContext发布ApplicationEvent时,ApplicationListener Bean将自动被触发。

  • ApplicationEvent:容器事件,必须由ApplicationContext发布。
  • ApplicationListener:监听器,可由容器中的任何监听器Bean担任。
    spring的事件机制与所有的事件机制都基本相似,它们都需要由事件源、事件和事件监听器组成。此处的事件源是ApplicationContext,且事件必须由Java程序显示触发。
    只要一个Java类继承了ApplicationEvent基类,那该对象就可作为spring容器的容器事件。

容器事件的监听器类必须实现ApplicationListener接口,必须实现如下方法:

  • onApplicationEvent(ApplicationEvent event):每当容器内发生任何事件时,此方法都会被触发。
    监听器需要在容器中配置。当系统创建spring容器、加载spring容器时会自动触发容器事件,容器事件监听器可以监听到这些事件,程序也可调用ApplicationContext的pulishEvent()方法来主动触发容器事件。
5.让Bean获取spring容器

让Bean获取它所在的spring容器,可以让该Bean实现BeanFacotryAware接口。

  • setBeanFactory(BeanFactory beanFactory):该方法有一个参数beanFactory,该参数只想创建它的BeanFactory。
    与BeanFactoryAware接口类似的有AppliactionContextAware接口,实现该接口的Bean需要实现setApplicationContext(AppliactionContext applicationContext)方法。
public class Person implements ApplicationContextAware{
        private ApplicationContext ctx;

        public void setApplicationContext(ApplicationContext ctx) throws BeansException{
            this.ctx = ctx;
        }

    }

Spring容器会检测容器中所有的Bean,如果发现某个Bean实现了AppliactionContextAware接口,spring容器会在创建该Bean之后,自动调用该方法,调用该方法是,会将容器本身作为参数传给该实现方法。