前言:
上一篇文章,我们分析实现了BeanFactoryPostProcessor
和BeanPostProcessor
两个重要级接口,这两个接口都是spring提供的容器扩容机制,他们的区别是BeanFactoryPostProcessor
接口是在bean实例化之前修改beanDefinition信息,BeanPostProcessor
是在bean实例化之后对bean做修改,而且BeanPostProcessor是后面实现AOP的关键。这一节我们将引入ApplicationContext
,ApplicationContext
能自动识别BeanFactoryProcessor
和BeanPostProcessor
,这样就可以通过直接在xml中进行配置,不用手动添加到BeanFactory了。
ApplicationContext:
ApplicationContext是Spring中较BeanFactory更为先进的IOC容器,ApplicationContext除了拥有BeanFactory的所有功能外,还支持特殊类型bean如上一节中的BeanFactoryPostProcessor和BeanPostProcessor的自动识别、资源加载、容器事件和监听器、国际化支持、单例bean自动初始化等。
BeanFactory是spring的基础设施,面向spring自身;而ApplicationContext面向spring的使用者,应用场合使用ApplicationContext。
具体实现:
我们先来看几个新增的几个应用上下文相关接口类的关系。
可以看到最上层的是ApplicationContext
,中间多个抽象类和接口,最下层的是ClassPathXmlApplicationContext
,Xml文件的应用上下文。我们就是最终通过ClassPathXmlApplicationContext
来完成我们之前所有的一系列操作,加载xml文件中的内容,并且对bean实例化前后进行扩展操作。
直接从测试Demo看,我们之前所有的先创建beanFactory对象,再加载xml文件,然后手动去创建BeanFactoryPostProcessor/BeanPostProcessor实例,再调用各自的方法这些步骤,都省去了,简化成了一行代码就是ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:spring.xml");
测试:
public class ApplicationContextTest {
@Test
public void testApplicationContext() throws Exception {
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:spring.xml");
Person person = applicationContext.getBean("person", Person.class);
System.out.println(person);
//name属性在CustomBeanFactoryPostProcessor中被修改为ivy
assertThat(person.getName()).isEqualTo("ivy");
Car car = applicationContext.getBean("car", Car.class);
System.out.println(car);
//brand属性在CustomerBeanPostProcessor中被修改为lamborghini
assertThat(car.getBrand()).isEqualTo("lamborghini");
}
}
复制代码
来看下ClassPathXmlA