前几篇博客给大家介绍了Spring框架的IOC和AOP的源码,那怎么把这两个核心组件连接起来对外提供更好用的接口呢?这时context包里的ApplicationContext就登场了。
简单使用
我们先看个ApplicationContext使用的demo:
ClassPathXmlApplicationContext context=new ClassPathXmlApplicationContext("bean.xml");
Person person=(Person)context.getBean("person");
person.sayHello();
就是这么简单,ApplicationContext封装了IOC和AOP的两大核心功能,对外提交了简单的接口。
分析源码
我们先看ClassPathXmlApplicationContext的源码:
public class ClassPathXmlApplicationContext extends AbstractXmlApplicationContext {
private String[] configLocations;
public ClassPathXmlApplicationContext(String configLocation) throws BeansException {
this.configLocations = new String[] {configLocation};
refresh();
}
public ClassPathXmlApplicationContext(String[] configLocations) throws BeansException {
this.configLocations = configLocations;
refresh();
}
public ClassPathXmlApplicationContext(String[] configLocations, ApplicationContext parent)
throws BeansException {
super(parent);
this.configLocations = configLocations;
refresh();
}
protected String[] getConfigLocations() {
return this.configLocations;
}
}
这里关键代码都在refresh()里
public abstract class AbstractApplicationContext extends DefaultResourceLoader
implements ConfigurableApplicationContext {
其他代码
public void refresh() throws BeansException {
this.startupTime = System.currentTimeMillis();
// 加载BeanFactory,子类去实现
refreshBeanFactory();
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
beanFactory.registerCustomEditor(Resource.class, new ContextResourceEditor(this));
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
beanFactory.ignoreDependencyType(ResourceLoader.class);
beanFactory.ignoreDependencyType(ApplicationContext.class);
postProcessBeanFactory(beanFactory);
// invoke factory processors registered with the context instance
for (Iterator it = getBeanFactoryPostProcessors().iterator(); it.hasNext();) {
BeanFactoryPostProcessor factoryProcessor = (BeanFactoryPostProcessor) it.next();
factoryProcessor.postProcessBeanFactory(beanFactory);
}
if (getBeanDefinitionCount() == 0) {
logger.warn("No beans defined in ApplicationContext [" + getDisplayName() + "]");
}
else {
logger.info(getBeanDefinitionCount() + " beans defined in ApplicationContext [" + getDisplayName() + "]");
}
// 执行BeanFactory的PostProcessors
invokeBeanFactoryPostProcessors();
// 注册bean的beanProcessors实现拦截器,AOP
registerBeanPostProcessors();
// 初始化MessageSource,支持国际化
initMessageSource();
// 调用子类里的自定义刷新代码
onRefresh();
// 加载所有监听器
refreshListeners();
// 预处理单例
beanFactory.preInstantiateSingletons();
// 调用上下文刷新事件
publishEvent(new ContextRefreshedEvent(this));
}
}
AbstractXmlApplicationContext里的refreshBeanFactory
protected void refreshBeanFactory() throws BeansException {
try {
DefaultListableBeanFactory beanFactory = createBeanFactory();
XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
initBeanDefinitionReader(beanDefinitionReader);
loadBeanDefinitions(beanDefinitionReader);
this.beanFactory = beanFactory;
if (logger.isInfoEnabled()) {
logger.info("Bean factory for application context '" + getDisplayName() + "': " + beanFactory);
}
}
catch (IOException ex) {
throw new ApplicationContextException("I/O error parsing XML document for application context [" +
getDisplayName() + "]", ex);
}
}
这里封装了IOC的核心实现代码,看过IOC源码的应该很容易看懂,可以看我前几篇关于IOC的博客!
我们在前面介绍AOP的博客里知道AOP主要是通过BeanPostProcessor接口实现的,在refresh()方法里调用了registerBeanPostProcessors()
private void registerBeanPostProcessors() throws BeansException {
String[] beanNames = getBeanDefinitionNames(BeanPostProcessor.class);
if (beanNames.length > 0) {
List beanProcessors = new ArrayList();
for (int i = 0; i < beanNames.length; i++) {
beanProcessors.add(getBean(beanNames[i]));
}
Collections.sort(beanProcessors, new OrderComparator());
for (Iterator it = beanProcessors.iterator(); it.hasNext();) {
getBeanFactory().addBeanPostProcessor((BeanPostProcessor) it.next());
}
}
}
好了,现在我们知道context的主要作用是封装Spring的IOC和AOP两大核心功能,对外提供接口,其实这也类似设计模式里的门面模式!
下篇博客重点给大家介绍context的又一个核心功能:事件机制。