1 spring-context 模塊概要
該模塊主要實現在spring-beans 模塊的擴展,主要對aop支持及el表達式的實現
分析示例
public static void main(String[] args){ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring-aop.xml");TestBean testBean = (TestBean) context.getBean("testBean");testBean.test();System.out.println(testBean);}
xml配置
<?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:aop="http://www.springframework.org/schema/aop"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans-3.2.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop-3.2.xsd"><aop:aspectj-autoproxy proxy-target-class="false"/><bean id="testBean" class="com.xie.java.aop.TestBean"/><bean id="aspectJTest" class="com.xie.java.aop.AspectJTest"/>
</beans>
從ClassPathXmlApplicationContext 入手,先看下該類的繼承結構
2 applicationcontext 初始化
從上面來看該類繼承還是非常復雜的,不管怎么樣,先從調用的地方入手
public ClassPathXmlApplicationContext(String configLocation) throws BeansException {this(new String[] {configLocation}, true, null);}public ClassPathXmlApplicationContext(String... configLocations) throws BeansException {this(configLocations, true, null);}public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent)throws BeansException {super(parent);//處理配置資源初始化setConfigLocations(configLocations);if (refresh) {//這是真正的核心入口refresh();}}
上面都是一些非常簡單的代碼,無需多解釋,接下來主要是看AbstractApplicationContext.refresh方法,context 絕大部分功能由AbstractApplicationContext去實現,下面是主線實現代碼,包括利用beanfactory加載beandefinitions 及實例化這些beans 以及aop的實現
@Overridepublic void refresh() throws BeansException, IllegalStateException {synchronized (this.startupShutdownMonitor) {//刷新前一些準備prepareRefresh();//獲得beafactory,并加載beandefinitionConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();//準備一下beanfactory的信息prepareBeanFactory(beanFactory);try {// Allows post-processing of the bean factory in context subclasses.postProcessBeanFactory(beanFactory);// Invoke factory processors registered as beans in the context.//調用beanfactoryPostProcessorsinvokeBeanFactoryPostProcessors(beanFactory);// Register bean processors that intercept bean creation.//注冊bean processors 用于攔截bean的創建registerBeanPostProcessors(beanFactory);// Initialize message source for this context.//初始化容器消息源initMessageSource();// Initialize event multicaster for this context.//初始化事件廣播者initApplicationEventMulticaster();// Initialize other special beans in specific context subclasses.//初始化子容器其它特定beans onRefresh();// Check for listener beans and register them.//注冊監聽者registerListeners();// Instantiate all remaining (non-lazy-init) singletons.//實例化所有擁有非懶加載的單例finishBeanFactoryInitialization(beanFactory);// Last step: publish corresponding event.//最后一步,發布對應的事件finishRefresh();}//省略一些代碼}}
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {refreshBeanFactory();ConfigurableListableBeanFactory beanFactory = getBeanFactory();if (logger.isDebugEnabled()) {logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);}return beanFactory;}@Overrideprotected final void refreshBeanFactory() throws BeansException {if (hasBeanFactory()) {destroyBeans();closeBeanFactory();}try {//創建beafactoryDefaultListableBeanFactory beanFactory = createBeanFactory();beanFactory.setSerializationId(getId());customizeBeanFactory(beanFactory);//加載beandefinitions loadBeanDefinitions(beanFactory);synchronized (this.beanFactoryMonitor) {this.beanFactory = beanFactory;}}catch (IOException ex) {throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);}}@Overrideprotected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {// Create a new XmlBeanDefinitionReader for the given BeanFactory.//創建xml beandefinition readerXmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);// Configure the bean definition reader with this context's// resource loading environment.beanDefinitionReader.setEnvironment(this.getEnvironment());beanDefinitionReader.setResourceLoader(this);beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));// Allow a subclass to provide custom initialization of the reader,// then proceed with actually loading the bean definitions.initBeanDefinitionReader(beanDefinitionReader);//通過xml reader 讀取xml配置文件 loadBeanDefinitions(beanDefinitionReader);}
protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {Resource[] configResources = getConfigResources();if (configResources != null) {reader.loadBeanDefinitions(configResources);}//獲得所有配置資源String[] configLocations = getConfigLocations();if (configLocations != null) {//正式通過xmlreader解釋xml 配置,并把解釋到的beandedinition//注冊到beanfactory里,接下來就是beans模塊已講過的了reader.loadBeanDefinitions(configLocations);}}
3 預實例化beanfactory里單例對象
接下要分析如何把上面得到的beandefinitions 進行實例化
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {// Initialize conversion service for this context.if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {//省略一大波代碼// Instantiate all remaining (non-lazy-init) singletons.//預實例化單例,beanFactory.preInstantiateSingletons();
}
獲取beanfactory里所有beanNames進行實例化
@Override
public void preInstantiateSingletons() throws BeansException {//獲得所有beanNames List<String> beanNames = new ArrayList<String>(this.beanDefinitionNames);//逐個遍歷,實例化預加載單例對象for (String beanName : beanNames) {RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {//判斷要創建的實例是否為FactoryBeanif (isFactoryBean(beanName)) {final FactoryBean<?> factory = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName);boolean isEagerInit;if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {isEagerInit = AccessController.doPrivileged(new PrivilegedAction<Boolean>() {@Overridepublic Boolean run() {return ((SmartFactoryBean<?>) factory).isEagerInit();}}, getAccessControlContext());}else {isEagerInit = (factory instanceof SmartFactoryBean &&((SmartFactoryBean<?>) factory).isEagerInit());}if (isEagerInit) {getBean(beanName);}}else {//開始他建實例,這塊是beans模塊內容,不再重述了getBean(beanName);}}}//這里省略一些代碼
}