Spring對beanFactory的處理java
public void refresh() throws BeansException, IllegalStateException { synchronized (this.startupShutdownMonitor) { // Prepare this context for refreshing. prepareRefresh(); // Tell the subclass to refresh the internal bean factory. ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); // Prepare the bean factory for use in this context. prepareBeanFactory(beanFactory); try { // Allows post-processing of the bean factory in context subclasses. postProcessBeanFactory(beanFactory); // Invoke factory processors registered as beans in the context. invokeBeanFactoryPostProcessors(beanFactory); // Register bean processors that intercept bean creation. registerBeanPostProcessors(beanFactory); // Initialize message source for this context. initMessageSource(); // Initialize event multicaster for this context. initApplicationEventMulticaster(); // Initialize other special beans in specific context subclasses. onRefresh(); // Check for listener beans and register them. registerListeners(); // Instantiate all remaining (non-lazy-init) singletons. finishBeanFactoryInitialization(beanFactory); // Last step: publish corresponding event. finishRefresh(); }catch (BeansException ex) { if (logger.isWarnEnabled()) { logger.warn("Exception encountered during context initialization-cancelling refresh attempt: " + ex); } // Destroy already created singletons to avoid dangling resources. destroyBeans(); // Reset 'active' flag. cancelRefresh(ex); // Propagate exception to caller. throw ex; }finally { // Reset common introspection caches in Spring's core, since we // might not ever need metadata for singleton beans anymore... resetCommonCaches(); } } }
prepareRefresh()
這裏不用細看就是自身進行些配置和參數校驗什麼的spring
obtainFreshBeanFactory()
NameSpaceHandler
加載過程的解析已經寫過就再也不寫了; 參看前面的文章//返回也沒用,應該定義爲void的,parserContext的registry就是beanFactory public BeanDefinition parse(Element element, ParserContext parserContext) { //獲取具體的BeanDefinitionParser,好比說ComponentScanBeanDefinitionParser return findParserForElement(element, parserContext).parse(element, parserContext); }
ComponentScanBeanDefinitionParser
這是個樣板例子,一看就知道怎麼回事public BeanDefinition parse(Element element, ParserContext parserContext) { String basePackage = element.getAttribute(BASE_PACKAGE_ATTRIBUTE);//獲取basepackage設定的包名 basePackage = parserContext.getReaderContext().getEnvironment().resolvePlaceholders(basePackage);//有可能使用了$ String[] basePackages = StringUtils.tokenizeToStringArray(basePackage,ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS);//解析出所有的package // Actually scan for bean definitions and register them. ClassPathBeanDefinitionScanner scanner = configureScanner(parserContext, element);//配置掃描器 Set<BeanDefinitionHolder> beanDefinitions = scanner.doScan(basePackages);//掃包 registerComponents(parserContext.getReaderContext(), beanDefinitions, element);//向beanFactory註冊 return null; }
主要是完成BeanFactoryPostProcessors的初始化app
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) { ... //注意這是LTW,加載時代碼織入進行加強AOP if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) { beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory)); } ... }
對BeanFactory啓動處理流程post
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) { PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors()); //須要注意的有個AspectJWeavingEnabler比較特殊,這個類的目的在於啓用ClassLoader級別的Aop,和之前的Instrument In Jvm 有點相似, // 檢測是否有LTW支持, if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) { beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory)); beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader())); } }
就是bean的初始化什麼的了;this
其實想抓下Transactional的實現代碼的;(這個有點不太明白和JVM redifineClass是怎麼對活動棧幀進行方法棧的替換)spa
但我對AspectJ實在不熟,先放棄吧.等我點了ApsectJ的科技樹再回來補充;code
ContextLoaderListener 初始化orm
new DefaultListableBeanFactory() 建立beanFactroyxml
new XmlBeanDefinitionReader(beanFactory) 建立解析器token
new BeanDefinitionDocumentReader
加載配置文件applicationContext.xml
根據 配置文件內的tag的namespace 及 lib下全部jar的/META-INF/spring.handlers 肯定NamespaceHandler 並對其初始化
根據 tag的具體值肯定BeanDefinitionParser();調用parser.parse(Element element, ParserContext parserContext) 完成BeanDefinition的註冊,parserContext的registry 就是最開始建立的beanFactory;
postProcessBeanFactory()完成各類beanFatoryPostProcessor的初始化
執行這些完成各類beanFatoryPostProcessor 注意裏面有個比較特殊屬的AspectJWeavingEnabler 是負責啓用ClassLoader級別Aop的核心邏輯(就是在ClassLoader上注入ClassFileTransformer)
後面就是bean的各類加載邏輯了...不寫了