ApplicationContext的作用与实现

依赖注入(控制反转)是需要依赖注入容器来实现的,ApplicationContext就是最基础的依赖注入容器,它的作用是让Spring能读取XML文件的配置,对bean对象进行创建,修改等。我们可以看下ApplicationContext接口的源码

public abstract interface ApplicationContext
		extends
			EnvironmentCapable,
			ListableBeanFactory,
			HierarchicalBeanFactory,
			MessageSource,
			ApplicationEventPublisher,
			ResourcePatternResolver {
	...
	public abstract AutowireCapableBeanFactory getAutowireCapableBeanFactory() throws IllegalStateException;
}

里面有用到抽象类AutowireCapableBeanFactory,他的基类就是beanFactory,beanFactory这个接口封装了一系列对配置文件中bean对象的操作方法

public interface BeanFactory {
	String FACTORY_BEAN_PREFIX = "&";
	Object getBean(String name) throws BeansException;
	<T> T getBean(String name, Class<T> requiredType) throws BeansException; //根据name获取配置文件中的bean对象
	<T> T getBean(Class<T> requiredType) throws BeansException;
	Object getBean(String name, Object... args) throws BeansException;
	boolean containsBean(String name);
	boolean isSingleton(String name) throws NoSuchBeanDefinitionException;
	boolean isPrototype(String name) throws NoSuchBeanDefinitionException;
	boolean isTypeMatch(String name, Class<?> targetType) throws NoSuchBeanDefinitionException;
	Class<?> getType(String name) throws NoSuchBeanDefinitionException;
	String[] getAliases(String name);
}

ApplicationContext接口有两个常用实现类,ClassPathXmlApplicationContext和FileSystemXmlApplicationContext,分别是从类加载路径和文件系统中加载配置文件。

那它们究竟是怎么读取这些配置文件的呢?已知配置文件以XML形式保存,那么这两个实现类中必然包含着使用SAX解析XML文件的方法,让我们看看ClassPathXmlApplicationContext的源码吧!


loadBeanDefinitions( )一看就是用来读取配置文件加载bean对象的,里面还有个工厂类,它非常可疑,让我们进去探索下有啥蛛丝马迹!


我们知道,sax解析xml是按从外到内进行解析的,先解析document(文件),再解析entity(实体),最后解析propertity(实体内的元素),所以DefaultDocumentLoader,就是他没跑了,进去看看!

进去后第一眼就能看到这个方法和他的注释

/**
	 * Load the {@link Document} at the supplied {@link InputSource} using the standard JAXP-configured
	 * XML parser.
	 */
	@Override
	public Document loadDocument(InputSource inputSource, EntityResolver entityResolver,
			ErrorHandler errorHandler, int validationMode, boolean namespaceAware) throws Exception {

		DocumentBuilderFactory factory = createDocumentBuilderFactory(validationMode, namespaceAware);
		if (logger.isDebugEnabled()) {
			logger.debug("Using JAXP provider [" + factory.getClass().getName() + "]");
		}
		DocumentBuilder builder = createDocumentBuilder(factory, entityResolver, errorHandler);
		return builder.parse(inputSource);
	}

注释的意思是,用JAXP来解析绑定的XML文件,这是什么意思呢?这里不得不提到InputSource,因为使用sax API时,所有输入都从使用 org.xml.sax.InputSource 类开始,详情见https://blog.csdn.net/linminqin/article/details/6456476

由于水平原因,再底层就脱离Spring的JAR包了,所以就不一一赘述了。不过这一趟探索ApplicationContext还是很有收获的,一言以蔽之,依赖注入是通过SAX读取XML配置文件,再用反射生成bean对象实现的。

猜你喜欢

转载自blog.csdn.net/qq_26950567/article/details/80277067