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