Spring原始碼解析-beanfactory
準備寫幾篇spring原始碼的文章,整理自己看《spring原始碼深度解析》過程,方便後面學習,希望年前完成吧。上次看過一些,不夠深入,這次又看了下,目的:
1. 只關心書中前半部分,spring IOC和AOP核心部分,後半部分暫不關心;
2. 只關注主流程流轉,細節部分了解功能,太細的不管。
spring的版本號3.1的。
Demo
public class MyBeanTest {
public static void main(String[] args) {
BeanFactory ctx = new XmlBeanFactory(new ClassPathResource("spring.xml" ));
MyBean testBean = (MyBean)ctx.getBean("testBean");
System.out.println(testBean.getTestStr());
}
}
package qbb.spring.bean;
public class MyBean {
private String testStr = "testStr";
public MyBean(){
}
public MyBean(String testStr){
this.testStr = testStr;
}
public String getTestStr() {
return testStr;
}
public void setTestStr(String testStr) {
this.testStr = testStr;
}
}
<?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:context ="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<bean name="testBean" class="qbb.spring.bean.MyBean" ></bean>
</beans>
uml類圖
上次看的時候就畫過這個圖,這次做了細化和調整。
XmlBeanFactory繼承關係
- AliasRegistry定義對Alias的簡單增刪改等操作;
- SimpleAliasRegistry使用currenthashmap作為快取,並對介面AliasRegisty進行實現;
- SingletonBeanRegistry定義對單例的獲取及獲取;
- DefaultSingletonBeanRegistry是SingletonBeanRegistry的實現;
- FactoryBeanRegistrySupport在DefaultSingletonBeanRegistry基礎上,增加對FactorBean的特殊處理功能;
- BeanFactory定義獲取bean及bean的各種屬性;
- HierarchicalBeanFactory繼承BeanFactory,增加對parentFactory的支援;
- ConfigurableBeanFactory提供配置各種factory的方法;
- ListableBeanFactory根據不同條件獲取bean的配置清單;
- AutowireCapableBeanFactory提供建立bean,自動注入,初始化已經應用bean後的處理器;
- AbstractBeanFactory綜合FactoryBeanRegistrySupport和ConfigurableBeanFactory功能;
- ConfigurableListableBeanFactory是BeanFactory的配置清單,指定忽略型別和介面等;
- AbstractAutowireCapableBeanFactory綜合AbstractBeanFactory並對介面AutowireCapalbeBeanFactory的實現;
- BeanDefinitionRegistry定義對BeanDefinition的curd操作;
- DefaultListableBeanFactory綜合所有功能,主要是bean註冊後的處理;
- XmlBeanFactory對DefaultListableBeanFactory類進行了擴充套件,主要是從xml文件讀取BeanDefinition,對於註冊以及獲取Bean都是從父類DefaultLisstableBean繼承的方法去實現,與父類的不同就是增加了XmlBeanDefinitionReader型別的reader屬性,在XmlBeanFactory中主要使用reader屬性對資原始檔進行讀取和註冊;
XmlBeanDefinitionReader
- EnvironmentCapable定義獲取Environment的方法;
- BeanDefinitionReader主要定義資原始檔讀取並轉化為BeanDefinition的各種功能;
- AbstractBeanDefinitionReader對介面的實現;
- ResourceLoader資源載入器,根據給定的資原始檔地址返回對應的Resource;
- DocumentLoader資原始檔轉化為Document的功能;
- BeanDefinitionDocumentReader讀取Document並註冊BeanFinition的功能;
- BeanDefinitionParserDelegate定義解析element的各種方法;
BeanDefinition
- BeanDefinition配置檔案bean元素在容器的內部表現形式;
- ChildBeanDefinition父子bean中的子bean;
- GenericBeanDefinition2.5後加入,一站式的服務類;
- RootBeanDefinition對應一般性的bean元素標籤,父子bean中的父bean可以用此表示,沒有父bean的bean也使用來表示;
xml解析beanDefinition
BeanFactory ctx = new XmlBeanFactory(new ClassPathResource("spring.xml"));
資原始檔抽象
new ClassPathResource("spring.xml")
spring將外部的資源封裝成內部使用Resource,可以從檔案,class,jar,還有context上下文:
我這裡使用ClassPathResource載入spring檔案,當然也可以使用FileSystemResource從檔案系統路徑載入。
loadBeanDefinition
new XmlBeanFactory(new ClassPathResource("spring.xml"));
呼叫XmlBeanFactory構造
// XmlBeanFactory
public XmlBeanFactory(Resource resource) throws BeansException {
this(resource, null);
}
public XmlBeanFactory(Resource resource, BeanFactory parentBeanFactory) throws BeansException {
super(parentBeanFactory);
this.reader.loadBeanDefinitions(resource);
}
在條用super的時候會設定parentBeanFactory,好像只要mvc的時候才看到設定,其他地方基本沒用到。
//AbstractAutowireCapableBeanFactory
public AbstractAutowireCapableBeanFactory(BeanFactory parentBeanFactory) {
this();
setParentBeanFactory(parentBeanFactory);
}
public AbstractAutowireCapableBeanFactory() {
super();
//忽略一些依賴,在getbean的時候,在例項化屬性填充後,會檢查設定這些依賴關係,
//然後再去呼叫實現InitializingBean的afterPropertiesSet方法和自定義的Init-Method
ignoreDependencyInterface(BeanNameAware.class);
ignoreDependencyInterface(BeanFactoryAware.class);
ignoreDependencyInterface(BeanClassLoaderAware.class);
}
//AbstractBeanFactory
public void setParentBeanFactory(BeanFactory parentBeanFactory) {
if (this.parentBeanFactory != null && this.parentBeanFactory != parentBeanFactory) {
throw new IllegalStateException("Already associated with parent BeanFactory: " + this.parentBeanFactory);
}
this.parentBeanFactory = parentBeanFactory;
}
在這些完了後會呼叫
//xmlbeanfactory
this.reader.loadBeanDefinitions(resource);
XmlBeanFactory使用XmlBeanDefinitionReader來解析和註冊bean定義。
//XmlBeanDefinitionReader
public int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException {
//EncodedResource做了編碼處理,getReader時如果有編碼就使用,沒有就不適用
return loadBeanDefinitions(new EncodedResource(resource));
}
public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException {
...
try {
InputStream inputStream = encodedResource.getResource().getInputStream();
try {
InputSource inputSource = new InputSource(inputStream);
if (encodedResource.getEncoding() != null) {
inputSource.setEncoding(encodedResource.getEncoding());
}
return doLoadBeanDefinitions(inputSource, encodedResource.getResource());
}
finally {
inputStream.close();
}
}
...
}
看了下,spring中習慣doXXX來表示真正幹活的程式碼,XXX來做主流程控制。自己寫程式碼的時候有時流程會不清晰,會亂,後來還是從spring裡面學會這招,先提煉主流程,然後再分配。
//XmlBeanDefinitionReader
protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource)
throws BeanDefinitionStoreException {
try {
int validationMode = getValidationModeForResource(resource);
Document doc = this.documentLoader.loadDocument(
inputSource, getEntityResolver(), this.errorHandler, validationMode, isNamespaceAware());
return registerBeanDefinitions(doc, resource);
}
...
}
xml檔案校驗和解析
//XmlBeanDefinitionReader
int validationMode = getValidationModeForResource(resource);
Document doc = this.documentLoader.loadDocument(
inputSource, getEntityResolver(), this.errorHandler, validationMode, isNamespaceAware());
xml文件的2種校驗方式:DTD和XSD,通過getValidationModeForResource來獲取,DTD的會包含DOCTYPE,所以通過解析這個是否存在判斷。校驗過後就是通過DefaultDocumentLoader將xml檔案解析Document,xml檔案解析一般就是SAX、Dom、jdom,dom4j。
registerBeanDefinitions
//XmlBeanDefinitionReader
public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
//將DefaultBeanDefinitionDocumentReader轉為BeanDefinitionDocumentReader
BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();
//this.getEnvironment()獲取到的是StandardEnvironment,可以用來獲取系統變數和環境變數
documentReader.setEnvironment(this.getEnvironment());
int countBefore = getRegistry().getBeanDefinitionCount();
//使用DefaultBeanDefinitionDocumentReader解析document
documentReader.registerBeanDefinitions(doc, createReaderContext(resource));
return getRegistry().getBeanDefinitionCount() - countBefore;
}
protected XmlReaderContext createReaderContext(Resource resource) {
if (this.namespaceHandlerResolver == null) {
//DefaultNamespaceHandlerResolver,主要用來獲取標籤的解析,
//特別是自定義標籤的解析,後面單獨講下這個,裡面最重要的方法NamespaceHandler resolve(String namespaceUri)
this.namespaceHandlerResolver = createDefaultNamespaceHandlerResolver();
}
return new XmlReaderContext(resource, this.problemReporter, this.eventListener,
this.sourceExtractor, this, this.namespaceHandlerResolver);
}
最終還是委託DefaultBeanDefinitionDocumentReader來解析Document。
//DefaultBeanDefinitionDocumentReader
public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) {
this.readerContext = readerContext;
logger.debug("Loading bean definitions");
Element root = doc.getDocumentElement();
doRegisterBeanDefinitions(root);
}
protected void doRegisterBeanDefinitions(Element root) {
//profile屬性,類似maven -p,可以定義不同環境下的bean定義,配合環境變數spring.profiles.active使用
String profileSpec = root.getAttribute(PROFILE_ATTRIBUTE);
if (StringUtils.hasText(profileSpec)) {
Assert.state(this.environment != null, "environment property must not be null");
String[] specifiedProfiles = StringUtils.tokenizeToStringArray(profileSpec, BeanDefinitionParserDelegate.MULTI_VALUE_ATTRIBUTE_DELIMITERS);
if (!this.environment.acceptsProfiles(specifiedProfiles)) {
return;
}
}
// any nested <beans> elements will cause recursion in this method. In
// order to propagate and preserve <beans> default-* attributes correctly,
// keep track of the current (parent) delegate, which may be null. Create
// the new (child) delegate with a reference to the parent for fallback purposes,
// then ultimately reset this.delegate back to its original (parent) reference.
// this behavior emulates a stack of delegates without actually necessitating one.
BeanDefinitionParserDelegate parent = this.delegate;
// BeanDefinitionParserDelegate
this.delegate = createHelper(readerContext, root, parent);
preProcessXml(root); //子類實現
parseBeanDefinitions(root, this.delegate);
postProcessXml(root); //子類實現
this.delegate = parent;
}
protected BeanDefinitionParserDelegate createHelper(XmlReaderContext readerContext, Element root, BeanDefinitionParserDelegate parentDelegate) {
BeanDefinitionParserDelegate delegate = new BeanDefinitionParserDelegate(readerContext, environment);
delegate.initDefaults(root, parentDelegate);
return delegate;
}
//BeanDefinitionParserDelegate
public void initDefaults(Element root, BeanDefinitionParserDelegate parent) {
populateDefaults(this.defaults, (parent != null ? parent.defaults : null), root);
this.readerContext.fireDefaultsRegistered(this.defaults);
}
//收集一些預設屬性
protected void populateDefaults(DocumentDefaultsDefinition defaults, DocumentDefaultsDefinition parentDefaults, Element root) {
String lazyInit = root.getAttribute(DEFAULT_LAZY_INIT_ATTRIBUTE);
if (DEFAULT_VALUE.equals(lazyInit)) {
lazyInit = parentDefaults != null ? parentDefaults.getLazyInit() : FALSE_VALUE;
}
defaults.setLazyInit(lazyInit);
String merge = root.getAttribute(DEFAULT_MERGE_ATTRIBUTE);
if (DEFAULT_VALUE.equals(merge)) {
merge = parentDefaults != null ? parentDefaults.getMerge() : FALSE_VALUE;
}
defaults.setMerge(merge);
String autowire = root.getAttribute(DEFAULT_AUTOWIRE_ATTRIBUTE);
if (DEFAULT_VALUE.equals(autowire)) {
autowire = parentDefaults != null ? parentDefaults.getAutowire() : AUTOWIRE_NO_VALUE;
}
defaults.setAutowire(autowire);
// don't fall back to parentDefaults for dependency-check as it's no
// longer supported in <beans> as of 3.0. Therefore, no nested <beans>
// would ever need to fall back to it.
defaults.setDependencyCheck(root.getAttribute(DEFAULT_DEPENDENCY_CHECK_ATTRIBUTE));
if (root.hasAttribute(DEFAULT_AUTOWIRE_CANDIDATES_ATTRIBUTE)) {
defaults.setAutowireCandidates(root.getAttribute(DEFAULT_AUTOWIRE_CANDIDATES_ATTRIBUTE));
}
else if (parentDefaults != null) {
defaults.setAutowireCandidates(parentDefaults.getAutowireCandidates());
}
if (root.hasAttribute(DEFAULT_INIT_METHOD_ATTRIBUTE)) {
defaults.setInitMethod(root.getAttribute(DEFAULT_INIT_METHOD_ATTRIBUTE));
}
else if (parentDefaults != null) {
defaults.setInitMethod(parentDefaults.getInitMethod());
}
if (root.hasAttribute(DEFAULT_DESTROY_METHOD_ATTRIBUTE)) {
defaults.setDestroyMethod(root.getAttribute(DEFAULT_DESTROY_METHOD_ATTRIBUTE));
}
else if (parentDefaults != null) {
defaults.setDestroyMethod(parentDefaults.getDestroyMethod());
}
defaults.setSource(this.readerContext.extractSource(root));
}
parseBeanDefinitions
//DefaultBeanDefinitionDocumentReader
protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
//預設是bean
if (delegate.isDefaultNamespace(root)) {
NodeList nl = root.getChildNodes();
for (int i = 0; i < nl.getLength(); i++) {
Node node = nl.item(i);
if (node instanceof Element) {
Element ele = (Element) node;
if (delegate.isDefaultNamespace(ele)) {
//解析預設bean定義
parseDefaultElement(ele, delegate);
}
else {
//自定義
delegate.parseCustomElement(ele);
}
}
}
}
else {
//自定義
delegate.parseCustomElement(root);
}
}
private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {
//import
if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) {
importBeanDefinitionResource(ele);
}
//別名
else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) {
processAliasRegistration(ele);
}
//bean
else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) {
processBeanDefinition(ele, delegate);
}
//beans裡面巢狀的bean解析
else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) {
// recurse
doRegisterBeanDefinitions(ele);
}
}
//BeanDefinitionParserDelegate
public boolean isDefaultNamespace(String namespaceUri) {
//BEANS_NAMESPACE_URI = "http://www.springframework.org/schema/beans";
return (!StringUtils.hasLength(namespaceUri) || BEANS_NAMESPACE_URI.equals(namespaceUri));
}
public boolean isDefaultNamespace(Node node) {
return isDefaultNamespace(getNamespaceURI(node));
}
可以看到這裡的Document解析節點是先校驗是否為預設bean的namespace,是的話就判斷節點是import、alias、bean,不是就按照自定義namespace方式解析。
對於import的解析時迴圈解析import的Resource檔案,alias是註冊別名到map(會校驗是否存在別名的迴圈定義),最核心的還是bean的解析。
processBeanDefinition
//DefaultBeanDefinitionDocumentReader
protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
//委託DefaultBeanDefinitionDocumentReader完成bean解析,最終bdHolder持有beanDefinition和beanName,別名
BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
if (bdHolder != null) {
//是否有自定義屬性需要處理
bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
try {
// Register the final decorated instance.
BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
}
catch (BeanDefinitionStoreException ex) {
getReaderContext().error("Failed to register bean definition with name '" +
bdHolder.getBeanName() + "'", ele, ex);
}
// Send registration event.
getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
}
}
//註冊beanDefinition和別名
public static void registerBeanDefinition(
BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
throws BeanDefinitionStoreException {
// Register bean definition under primary name.
String beanName = definitionHolder.getBeanName();
registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
// Register aliases for bean name, if any.
String[] aliases = definitionHolder.getAliases();
if (aliases != null) {
for (String aliase : aliases) {
registry.registerAlias(beanName, aliase);
}
}
}
delegate-parseBeanDefinitionElement(ele)
//BeanDefinitionParserDelegate
public BeanDefinitionHolder parseBeanDefinitionElement(Element ele) {
return parseBeanDefinitionElement(ele, null);
}
public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, BeanDefinition containingBean) {
//bean的id和name屬性
String id = ele.getAttribute(ID_ATTRIBUTE);
String nameAttr = ele.getAttribute(NAME_ATTRIBUTE);
//name多個的情況,放入別名
List<String> aliases = new ArrayList<String>();
if (StringUtils.hasLength(nameAttr)) {
String[] nameArr = StringUtils.tokenizeToStringArray(nameAttr, MULTI_VALUE_ATTRIBUTE_DELIMITERS);
aliases.addAll(Arrays.asList(nameArr));
}
String beanName = id;
if (!StringUtils.hasText(beanName) && !aliases.isEmpty()) {
beanName = aliases.remove(0);
if (logger.isDebugEnabled()) {
logger.debug("No XML 'id' specified - using '" + beanName +
"' as bean name and " + aliases + " as aliases");
}
}
if (containingBean == null) {
//檢查名稱是否用過,會有Set儲存用過的名稱
checkNameUniqueness(beanName, aliases, ele);
}
//解析bean的element成最終的beanDefinition
AbstractBeanDefinition beanDefinition = parseBeanDefinitionElement(ele, beanName, containingBean);
if (beanDefinition != null) {
//名稱不存在就spring生成一個
if (!StringUtils.hasText(beanName)) {
try {
if (containingBean != null) {
beanName = BeanDefinitionReaderUtils.generateBeanName(
beanDefinition, this.readerContext.getRegistry(), true);
}
else {
beanName = this.readerContext.generateBeanName(beanDefinition);
// Register an alias for the plain bean class name, if still possible,
// if the generator returned the class name plus a suffix.
// This is expected for Spring 1.2/2.0 backwards compatibility.
String beanClassName = beanDefinition.getBeanClassName();
if (beanClassName != null &&
beanName.startsWith(beanClassName) && beanName.length() > beanClassName.length() &&
!this.readerContext.getRegistry().isBeanNameInUse(beanClassName)) {
aliases.add(beanClassName);
}
}
if (logger.isDebugEnabled()) {
logger.debug("Neither XML 'id' nor 'name' specified - " +
"using generated bean name [" + beanName + "]");
}
}
catch (Exception ex) {
error(ex.getMessage(), ele);
return null;
}
}
String[] aliasesArray = StringUtils.toStringArray(aliases);
//返回一個BeanDefinitionHolder持有bean定義,beanname和別名陣列
return new BeanDefinitionHolder(beanDefinition, beanName, aliasesArray);
}
return null;
}
//最核心的方法:完成bean定義的element的元素解析
public AbstractBeanDefinition parseBeanDefinitionElement(
Element ele, String beanName, BeanDefinition containingBean) {
this.parseState.push(new BeanEntry(beanName));
String className = null;
if (ele.hasAttribute(CLASS_ATTRIBUTE)) {
className = ele.getAttribute(CLASS_ATTRIBUTE).trim();
}
try {
String parent = null;
if (ele.hasAttribute(PARENT_ATTRIBUTE)) {
parent = ele.getAttribute(PARENT_ATTRIBUTE);
}
//建立GenericBeanDefinition並設定beanclass或beanclassname
AbstractBeanDefinition bd = createBeanDefinition(className, parent);
//bean的屬性收集,如scope,inti-method,factory-method,注入方式、依賴等
parseBeanDefinitionAttributes(ele, beanName, containingBean, bd);
//提取description
bd.setDescription(DomUtils.getChildElementValueByTagName(ele, DESCRIPTION_ELEMENT));
//提取meta
parseMetaElements(ele, bd);
//處理override-mthod和replace-method子元素
parseLookupOverrideSubElements(ele, bd.getMethodOverrides());
parseReplacedMethodSubElements(ele, bd.getMethodOverrides());
//處理構造注入元素
parseConstructorArgElements(ele, bd);
//處理屬性注入
parsePropertyElements(ele, bd);
//qualifier提取,@Qualifier註解的xml配置方式
parseQualifierElements(ele, bd);
bd.setResource(this.readerContext.getResource());
bd.setSource(extractSource(ele));
return bd;
}
...
}
到這裡完成spring檔案的bean解析和註冊。
bean獲取
getBean
//AbstractBeanFactory
public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
}
protected <T> T doGetBean(
final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)
throws BeansException {
//轉換beanName,存在name為別名或者factorybean的name的情況,
//如果為factoryBean,你可能想獲取的是factorybean本身,也可能是factorybean的getObject返回的真實bean
final String beanName = transformedBeanName(name);
Object bean;
// Eagerly check singleton cache for manually registered singletons.
// 從快取獲取下
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
if (logger.isDebugEnabled()) {
if (isSingletonCurrentlyInCreation(beanName)) {
logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +
"' that is not fully initialized yet - a consequence of a circular reference");
}
else {
logger.debug("Returning cached instance of singleton bean '" + beanName + "'");
}
}
//getObjectForBeanInstance在獲取bean後都會呼叫,主要處理factorybean情況還有後處理器
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
else {
// Fail if we're already creating this bean instance:
// We're assumably within a circular reference.
// spring解決不了scope為prototype的bean迴圈依賴,丟擲異常
// spring只能解決Singleton的屬性注入情況下迴圈依賴
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
// Check if bean definition exists in this factory.
BeanFactory parentBeanFactory = getParentBeanFactory();
//如果parentbeanfactory存在並且當前beanfactory不包含,那就從parent獲取
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
// Not found -> check parent.
String nameToLookup = originalBeanName(name);
if (args != null) {
// Delegation to parent with explicit args.
return (T) parentBeanFactory.getBean(nameToLookup, args);
}
else {
// No args -> delegate to standard getBean method.
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
}
if (!typeCheckOnly) {
markBeanAsCreated(beanName);
}
//之前的GenericBeanDefinition轉為RootBeanDefinition,涉及到父子bean的合併處理
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
//校驗mbd不為抽象,如果getbean給定引數的話,mbd必須為prototype
checkMergedBeanDefinition(mbd, beanName, args);
// Guarantee initialization of beans that the current bean depends on.
// 依賴bean先處理
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
for (String dependsOnBean : dependsOn) {
getBean(dependsOnBean);
registerDependentBean(dependsOnBean, beanName);
}
}
// Create bean instance.
// 單例bean的建立
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
public Object getObject() throws BeansException {
try {
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
// Explicitly remove instance from singleton cache: It might have been put there
// eagerly by the creation process, to allow for circular reference resolution.
// Also remove any beans that received a temporary reference to the bean.
destroySingleton(beanName);
throw ex;
}
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
else if (mbd.isPrototype()) {
//prototypebean建立
// It's a prototype -> create a new instance.
Object prototypeInstance = null;
try {
beforePrototypeCreation(beanName);
prototypeInstance = createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}
else {
//指定scope的bean建立,還沒過這種
String scopeName = mbd.getScope();
final Scope scope = this.scopes.get(scopeName);
if (scope == null) {
throw new IllegalStateException("No Scope registered for scope '" + scopeName + "'");
}
try {
Object scopedInstance = scope.get(beanName, new ObjectFactory<Object>() {
public Object getObject() throws BeansException {
beforePrototypeCreation(beanName);
try {
return createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
}
});
bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
}
catch (IllegalStateException ex) {
throw new BeanCreationException(beanName,
"Scope '" + scopeName + "' is not active for the current thread; " +
"consider defining a scoped proxy for this bean if you intend to refer to it from a singleton",
ex);
}
}
}
// getbean指定型別,需要校驗和轉換
if (requiredType != null && bean != null && !requiredType.isAssignableFrom(bean.getClass())) {
try {
return getTypeConverter().convertIfNecessary(bean, requiredType);
}
catch (TypeMismatchException ex) {
if (logger.isDebugEnabled()) {
logger.debug("Failed to convert bean '" + name + "' to required type [" +
ClassUtils.getQualifiedName(requiredType) + "]", ex);
}
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
}
return (T) bean;
}
裡面最需要關心的幾個處理:
- 從快取獲取beanInstance:getSingleton(beanName)
- 獲取bean後的處理:getObjectForBeanInstance(sharedInstance, name, beanName, null);
- 單例bean建立:getSingleton中createBean方法;
Object sharedInstance = getSingleton(beanName)
//DefaultSingletonBeanRegistry
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
synchronized (this.singletonObjects) {
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {
ObjectFactory singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
singletonObject = singletonFactory.getObject();
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
return (singletonObject != NULL_OBJECT ? singletonObject : null);
}
- singletonObjects:beanName和建立bean例項之前關係;
- earlySingletonObjects:beanName和建立bean例項之前關係,此時可以通過getBean獲取到,主要是為了解決迴圈依賴;
- singletonFactories:beanName和建立bean的factory的關係,提前暴露建立bean的factory;
- registeredSingletons:已經註冊的beanName。
singleton的getSingleton建立
//AbstractBeanFactory
sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
public Object getObject() throws BeansException {
try {
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
...
}
}
});
//DefaultSingletonBeanRegistry
public Object getSingleton(String beanName, ObjectFactory singletonFactory) {
Assert.notNull(beanName, "'beanName' must not be null");
synchronized (this.singletonObjects) {
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
if (this.singletonsCurrentlyInDestruction) {
throw new BeanCreationNotAllowedException(beanName,
"Singleton bean creation not allowed while the singletons of this factory are in destruction " +
"(Do not request a bean from a BeanFactory in a destroy method implementation!)");
}
if (logger.isDebugEnabled()) {
logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
}
//加到singletonsCurrentlyInCreation
beforeSingletonCreation(beanName);
boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
if (recordSuppressedExceptions) {
this.suppressedExceptions = new LinkedHashSet<Exception>();
}
try {
//呼叫objectfactory的getObject方法的createBean
singletonObject = singletonFactory.getObject();
}
catch (BeanCreationException ex) {
if (recordSuppressedExceptions) {
for (Exception suppressedException : this.suppressedExceptions) {
ex.addRelatedCause(suppressedException);
}
}
throw ex;
}
finally {
if (recordSuppressedExceptions) {
this.suppressedExceptions = null;
}
//從singletonsCurrentlyInCreation移除
afterSingletonCreation(beanName);
}
//
addSingleton(beanName, singletonObject);
}
return (singletonObject != NULL_OBJECT ? singletonObject : null);
}
}
//加入singletonObjects和registeredSingletons
protected void addSingleton(String beanName, Object singletonObject) {
synchronized (this.singletonObjects) {
this.singletonObjects.put(beanName, (singletonObject != null ? singletonObject : NULL_OBJECT));
this.singletonFactories.remove(beanName);
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.add(beanName);
}
}
控制createBean建立的主流程
createbean的主流程
//AbstractAutowireCapableBeanFactory
//核心建立bean
@Override
protected Object createBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)
throws BeanCreationException {
if (logger.isDebugEnabled()) {
logger.debug("Creating instance of bean '" + beanName + "'");
}
// beanDefinition的beanclass存在,之前beanDefinition會根據classloader是否存在,來儲存clas,
// 這裡,如果beanclass存在就返回,不存在就通過class.forname來載入beanclassname
resolveBeanClass(mbd, beanName);
// Prepare method overrides.
try {
// 預判override-method和replace-method方法是否過載,只是提前判斷下,不處理
mbd.prepareMethodOverrides();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(mbd.getResourceDescription(),
beanName, "Validation of method overrides failed", ex);
}
try {
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
// 呼叫例項化前處理器方法,可以在這裡切入代理,提前返回代理bean,
// 如果使用自定義的TargetSource,會在這裡走aop,否則是在處理後處理器呼叫走aop
Object bean = resolveBeforeInstantiation(beanName, mbd);
if (bean != null) {
return bean;
}
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"BeanPostProcessor before instantiation of bean failed", ex);
}
//建立bean例項
Object beanInstance = doCreateBean(beanName, mbd, args);
if (logger.isDebugEnabled()) {
logger.debug("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
//利用InstantiationAwareBeanPostProcessor的postProcessBeforeInstantiation提前建立bean例項
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
Object bean = null;
if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
// Make sure bean class is actually resolved at this point.
if (mbd.hasBeanClass() && !mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
bean = applyBeanPostProcessorsBeforeInstantiation(mbd.getBeanClass(), beanName);
if (bean != null) {
//應用初始化後方法
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
}
mbd.beforeInstantiationResolved = (bean != null);
}
return bean;
}
//postProcessBeforeInstantiation
protected Object applyBeanPostProcessorsBeforeInstantiation(Class beanClass, String beanName)
throws BeansException {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
if (result != null) {
return result;
}
}
}
return null;
}
真正幹活的doCreateBean
//AbstractAutowireCapableBeanFactory
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) {
// Instantiate the bean.
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
//例項化bean
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);
Class beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);
// Allow post-processors to modify the merged bean definition.
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
//書裡面說會在這裡處理@autowire註解,不過沒測試這種情況,這裡todo下
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
mbd.postProcessed = true;
}
}
// Eagerly cache singletons to be able to resolve circular references
// even when triggered by lifecycle interfaces like BeanFactoryAware.
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isDebugEnabled()) {
logger.debug("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
//如果容許提前暴露,addSingletonFactory,加入後,如果其他bean,需要當前bean例項填充屬性,就可以從objectFactory中getObject獲取到
addSingletonFactory(beanName, new ObjectFactory() {
public Object getObject() throws BeansException {