知识点的梳理:
-
Bean工厂(com.springframework.beans.factory.BeanFactory),提供了IOC的配置机制;
- BeanFactory可以被称为IOC容器;
-
应用上下文(com.springframework.context.ApplicationContext)建立在BeanFactory基础之上,提供了国际化支持和框架事件体系;
- AppcationContext被称为应用上下文,或者Spring容器;
-
两者的用途:
- BeanFactory是Spring框架的基础设施,面向Spring本身;
- ApplicationContext面向使用Spring框架的开发者;
-
我们更多的使用ApplicationContext,而非BeanFactory;
-
BeanFactory
-
BeanFactory是类的通用工厂,用来创建各种类的对象。这些类仅仅是一个POJO,Spring称它们为Bean;
- Spring中的Bean,比JavaBean规范,更加宽泛。所有被Spring容器实例化并管理的Java类都可以成为Bean;
-
体系结构:下图中,XmlBeanFactory是最为常用的。
- BeanFactory接口位于类结构树的顶端,主要的方法是getBean(String beanName),该方法从容器中返回特定名称的Bean,BeanFactory的功能通过其他的接口得到不断扩展;
- ListableBeanFactory:该接口定义了访问容器中Bean基本信息的方法。如查看Bean的个数,获取某一类型Bean的配置名,查看容器中是否包括某一Bean等方法;
- HierarchicalBeanFactory:父子级联IOC容器的接口,子容器可以通过接口方法访问父容器;
- ConfigurableBeanFactory:该接口增强了IOC容器的可定制性,它定义了设置类装载器,属性编辑器,容器初始化后置处理器等方法;
- AutowireCapableBeanFactory:定义了将容器中的Bean按某种规则(如按名字匹配,按类型匹配等)进行自动装配的方法;
- SingletonBeanRegistry:定义了允许在运行期间向容器注册单实例Bean的方法;
- BeanDefinitionRegistry:Spring配置文件中每一个<bean>节点元素在Spring容器里都通过一个BeanDefinition对象表示,它描述了Bean的配置信息。而BeanDefinitionRegistry接口提供了向容器手工注册BeanDefinition对象的方法;
-
初始化BeanFactory
- 示例:使用Spring配置文件为Car提供配置信息,然后通过BeanFactory装载配置文件,启动Spring IOC容器
- bean.xml:Car的配置文件
-
<?xml version="1.0" encoding="UTF-8" ?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> <bean id="car" class="com.baobaotao.Car" init-method="myInit" destroy-method="myDestory" p:brand="红旗CA72" p:maxSpeed="200" /> <!-- bean id="car" class="com.baobaotao.beanfactory.Car" init-method="myInit" destroy-method="myDestory" p:brand="红旗CA72"/ --> </beans> |
- 通过XmlBeanFactory实现类启动Spring IOC容器:(不了解PathMatchingResourcePatternResolver的话看这里:资源加载器)
import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.xml.XmlBeanFactory; import org.springframework.core.io.Resource; import org.springframework.core.io.support.PathMatchingResourcePatternResolver; import org.springframework.core.io.support.ResourcePatternResolver;
import com.baobaotao.Car;
public class BeanFactoryTest { public static void main(String[] args) throws Throwable{ ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(); Resource res = resolver.getResource("classpath:com/baobaotao/beanfactory/beans.xml"); System.out.println(res.getURL()); BeanFactory bf = new XmlBeanFactory(res); System.out.println("init BeanFactory."); Car car = bf.getBean("car",Car.class); System.out.println("car bean is ready for use!"); car.introduce(); } } |
XmlBeanFactory通过Resource装载Spring配置信息并启动IOC容器,然后就可以通过BeanFactory的getBean方法从IOC容器中获取bean了。 |
-
ApplicationContext
- ApplicationContext由BeanFactory派生而来;BeanFactory的许多功能需要编程实现,而在ApplicationContext中则可以通过配置的方式实现;
-
ApplicationContext体系结构
-
主要实现类:
- ClassPathXmlApplicationContext:默认从类路径加载配置文件
- FileSystemXmlApplicationContext:默认从文件系统中装载配置文件
-
继承体系图:
-
其他类与接口:
- ApplicationEventPublisher:让容器拥有发布应用上下文事件的功能,包括容器启动事件,关闭事件等。实现了ApplicationListener事件监听接口的Bean可以接收到容器事件,并对事件进行响应处理。在ApplicationContext抽象实现类AbstractApplicationContext中,存在一个ApplicationEventMulticaster,它负责保存所有监听器,以便在容器产生上下文事件时通知这些事件监听器;
- MessageSource:为应用提供 i18n国际化消息访问的功能;
- ResourcePatternResolver:所有ApplicationContext实现类都实现了类似于PathMatchingResourcePatternResolver的功能,可以通过带前缀的Ant风格的资源文件路径装载Spring的配置文件;
- LifeCycle:该接口是Spring2.0加入的,该接口提供了start()和stop()两个方法们主要用于控制异步处理过程。在具体使用时,ApplicationContext及具体的Bean都必须同时实现该接口,ApplicationContext会将start/stop的信息传递给容器中所有实现该接口的Bean,以达到管理和控制JMX,任务调度等目的;
- ConfigurableApplicationContext扩展于ApplicationContext,它增加了refresh()和close()方法,让ApplicationContext具有启动,刷新和关闭应用上下文的能力;
-
-
ApplicationContext的初始化:
-
如果配置文件放置在类路径下,可以优先使用ClassPathXmlApplicationContext实现类:
- ApplicationContext ctx = new ClassPathXmlApplicationContext("com/baobaotao/context/beans.xml");
- 对于ClassPathXmlApplicationContext来说,"com/baobaotao/context/beans.xml"等同于"classpath:com/baobaotao/context/beans.xml"
-
如果配置文件放置在文件系统路径下,则可以优先考虑使用FilySystemXmlApplicationContext实现类:
- ApplicationContext ctx = new FilySystemXmlApplicationContext("com/baobaotao/context/beans.xml");
-
-
ApplicationContext的初始化和BeanFactory的区别:
- BeanFactory在初始化容器时,并未实例化Bean,直到第一次访问某个Bean时才实例目标Bean;
- ApplicationContext则在初始化应用上下文时就实例化所有单实例的Bean;因为ApplicationContext的实例化时间会比BeanFactory稍长一些;
- 示例1:通过注解@Configuration标注的POJO即可提供Spring所需的Bean配置信息:
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import com.baobaotao.Car; @Configuration public class Beans { @Bean(name = "car") public Car buildCar() { Car car = new Car(); car.setBrand("红旗CA72"); car.setMaxSpeed(200); return car; } } |
接上例:通过@Configuration标注的配置类启动容器 import org.springframework.context.annotation.AnnotationConfigApplicationContext; import com.baobaotao.Car; public class AnnotationApplicationContext {
public static void main(String[] args) { ApplicationContext ctx = new AnnotationConfigApplicationContext(Beans.class); Car car =ctx.getBean("car",Car.class); } } |
分析:AnnotationConfigApplicationContext将加载Beans.class中的Bean定义并调用Beans.class中的方法实例化Bean,启动容器并装配Bean; |