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