读书人

Spring2.5.6源代码分析(1):IOC容器

发布时间: 2012-09-08 10:48:07 作者: rapoo

Spring2.5.6源代码分析(一):IOC容器

1. BeanFactory是最顶层的类,从它下手最合适不过。

?

package org.springframework.beans.factory;import org.springframework.beans.BeansException;public interface BeanFactory {     //假如有个bean名字叫myJndiObject是个FactoryBean,用&myJndiObject返回factory,      //不然返回factory的实例?         String FACTORY_BEAN_PREFIX = "&";        //根据名字返回bean    Object getBean(String name) throws BeansException;    //返回的bean要符合类的类型   ?Object getBean(String name, Class requiredType) throws BeansException;    //带构造函数参数返回bean    Object getBean(String name, Object[] args) throws BeansException;    //是否含有某个bean    boolean containsBean(String name);    //某个bean是不是单例    boolean isSingleton(String name) throws NoSuchBeanDefinitionException;    //某个bean是不是原型,就是有多个实例    boolean isPrototype(String name) throws NoSuchBeanDefinitionException;    //检查bean是否是某个类的类型    boolean isTypeMatch(String name, Class targetType) throws NoSuchBeanDefinitionException;    //返回某个bean的类的类型    Class getType(String name) throws NoSuchBeanDefinitionException;    //得到bean的别名    String[] getAliases(String name);}

?

2. FileSystemXmlApplicationContext

从本地读取配置

public FileSystemXmlApplicationContext(String[] configLocations,boolean refresh, ApplicationContext parent) throws BeansException {// 交给父类super(parent);// 调用爷爷类AbstractRefreshableConfigApplicationContext的方法,// 父类AbstractXmlApplicationContext里是一些beanFactory的reader方法,// 用ApplicationContext直接进爷爷类setConfigLocations(configLocations);if (refresh) {// AbstractApplicationContext的刷新方法是重头戏,里面调用N个方法refresh();}}

?

3. AbstractRefreshableConfigApplicationContext

这个类没多大用,主要把配置文件的路径赋给自身的configLocations字段

public void setConfigLocations(String[] locations) {if (locations != null) {// 断言没有null值,否则报所带msg的异常,这个断言我也可以用用Assert.noNullElements(locations,"Config locations must not be null");this.configLocations = new String[locations.length];for (int i = 0; i < locations.length; i++) {// 路径如果是${...}这样的,就需要处理成系统路径this.configLocations[i] = resolvePath(locations[i]).trim();}} else {this.configLocations = null;}}

?

4. AbstractApplicationContext

public void refresh() throws BeansException, IllegalStateException {synchronized (this.startupShutdownMonitor) {//记录启动时间,active标识变为true,输出个日志到控制台??????????????????????? prepareRefresh();// 在这一步里,所有的xml信息都设置到beandefinition中了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) {// Destroy already created singletons to avoid dangling resources.beanFactory.destroySingletons();// Reset 'active' flag.cancelRefresh(ex);// Propagate exception to caller.throw ex;}}}
?

4.开始读文档里的Element子节点

??? org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader

public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) {this.readerContext = readerContext;logger.debug("Loading bean definitions");Element root = doc.getDocumentElement();                                //设置default值BeanDefinitionParserDelegate delegate = createHelper(readerContext, root);                                //对预定义的节点做预处理,暂时为空方法 preProcessXml(root);parseBeanDefinitions(root, delegate);postProcessXml(root);}
?

?

5. 文档里面的节点设置成类的字段

??? org.springframework.beans.factory.xml.BeanDefinitionParserDelegate一个一个解析文档中的节点,属性

public void initDefaults(Element root) {DocumentDefaultsDefinition defaults = new DocumentDefaultsDefinition();defaults.setLazyInit(root.getAttribute(DEFAULT_LAZY_INIT_ATTRIBUTE));defaults.setMerge(root.getAttribute(DEFAULT_MERGE_ATTRIBUTE));defaults.setAutowire(root.getAttribute(DEFAULT_AUTOWIRE_ATTRIBUTE));defaults.setDependencyCheck(root.getAttribute(DEFAULT_DEPENDENCY_CHECK_ATTRIBUTE));if (root.hasAttribute(DEFAULT_AUTOWIRE_CANDIDATES_ATTRIBUTE)) {defaults.setAutowireCandidates(root.getAttribute(DEFAULT_AUTOWIRE_CANDIDATES_ATTRIBUTE));}if (root.hasAttribute(DEFAULT_INIT_METHOD_ATTRIBUTE)) {defaults.setInitMethod(root.getAttribute(DEFAULT_INIT_METHOD_ATTRIBUTE));}if (root.hasAttribute(DEFAULT_DESTROY_METHOD_ATTRIBUTE)) {defaults.setDestroyMethod(root.getAttribute(DEFAULT_DESTROY_METHOD_ATTRIBUTE));}defaults.setSource(this.readerContext.extractSource(root));this.defaults = defaults;this.readerContext.fireDefaultsRegistered(defaults);}

?

6. 一开始初始化所有单例的bean

??? org.springframework.beans.BeanUtils

public static Object instantiateClass(Constructor ctor, Object[] args) throws BeanInstantiationException {Assert.notNull(ctor, "Constructor must not be null");try {ReflectionUtils.makeAccessible(ctor);                                                //在这一行真正实例化                       ?return ctor.newInstance(args);}catch (InstantiationException ex) {throw new BeanInstantiationException(ctor.getDeclaringClass(),"Is it an abstract class?", ex);}catch (IllegalAccessException ex) {throw new BeanInstantiationException(ctor.getDeclaringClass(),"Has the class definition changed? Is the constructor accessible?", ex);}catch (IllegalArgumentException ex) {throw new BeanInstantiationException(ctor.getDeclaringClass(),"Illegal arguments for constructor", ex);}catch (InvocationTargetException ex) {throw new BeanInstantiationException(ctor.getDeclaringClass(),"Constructor threw exception", ex.getTargetException());}}
?

zz

读书人网 >编程

热点推荐