首先分析DefaultListableBeanFactory这个类
public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactor implements ConfigurableListableBeanFactory, BeanDefinitionRegistry /* */ { /* 85 */ private boolean allowBeanDefinitionOverriding = true; /* */ /* */ /* 88 */ private boolean allowEagerClassLoading = true; /* */ /* */ /* 91 */ private boolean configurationFrozen = false; /* */ /* */ /* 94 */ private final Map beanDefinitionMap = CollectionFactory.createConcurrentMapIfPossible(16); /* */ /* */ /* 97 */ private final List beanDefinitionNames = new ArrayList(); /* */ /* */ /* */ private String[] frozenBeanDefinitionNames; /* */ /* */ /* 103 */ private AutowireCandidateResolver autowireCandidateResolver = AutowireUtils.createAutowireCandidateResolver(); /* */ /* */ /* 106 */ private final Map resolvableDependencies = new HashMap(); /* */ /* */ |
DefaultListableBeanFactory这个类
/* */ public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) /* */ throws BeanDefinitionStoreException /* */ { /* 444 */ Assert.hasText(beanName, "'beanName' must not be empty"); /* 445 */ Assert.notNull(beanDefinition, "BeanDefinition must not be null"); /* */ /* 447 */ if ((beanDefinition instanceof AbstractBeanDefinition)) { /* */ try { /* 449 */ ((AbstractBeanDefinition)beanDefinition).validate(); /* */ } /* */ catch (BeanDefinitionValidationException ex) { /* 452 */ throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName, "Validation of bean definition failed", ex); /* */ } /* */ } /* */ /* */ /* 457 */ synchronized (beanDefinitionMap) { /* 458 */ Object oldBeanDefinition = beanDefinitionMap.get(beanName); /* 459 */ if (oldBeanDefinition != null) { /* 460 */ if (!allowBeanDefinitionOverriding) { /* 461 */ throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName, "Cannot register bean definition [" + beanDefinition + "] for bean '" + beanName + "': There is already [" + oldBeanDefinition + "] bound."); /* */ } /* */ /* 466 */ if (logger.isInfoEnabled()) { /* 467 */ logger.info("Overriding bean definition for bean '" + beanName + "': replacing [" + oldBeanDefinition + "] with [" + beanDefinition + "]"); /* */ } /* */ /* */ } /* */ else /* */ { /* 473 */ beanDefinitionNames.add(beanName); /* 474 */ frozenBeanDefinitionNames = null; /* */ } /* 476 */ beanDefinitionMap.put(beanName, beanDefinition); /* */ /* 478 */ resetBeanDefinition(beanName); /* */ } /* */ } |
CollectionFactory类
/* */ /* */ public static Map createConcurrentMapIfPossible(int initialCapacity) /* */ { /* 194 */ if (JdkVersion.isAtLeastJava15()) { /* 195 */ logger.trace("Creating [java.util.concurrent.ConcurrentHashMap]"); /* 196 */ return JdkConcurrentCollectionFactory.createConcurrentHashMap(initialCapacity); /* */ } /* 198 */ if (backportConcurrentAvailable) { /* 199 */ logger.trace("Creating [edu.emory.mathcs.backport.java.util.concurrent.ConcurrentHashMap]"); /* 200 */ return BackportConcurrentCollectionFactory.createConcurrentHashMap(initialCapacity); /* */ } /* */ /* 203 */ logger.debug("Falling back to plain synchronized [java.util.HashMap] for concurrent map"); /* 204 */ return Collections.synchronizedMap(new HashMap(initialCapacity)); /* */ } /* */ |
BeanDefinition 类
package org.springframework.beans.factory.config;
import org.springframework.beans.BeanMetadataElement; import org.springframework.beans.MutablePropertyValues; import org.springframework.core.AttributeAccessor;
public abstract interface BeanDefinition extends AttributeAccessor, BeanMetadataElement { public static final String SCOPE_SINGLETON = "singleton"; public static final String SCOPE_PROTOTYPE = "prototype"; public static final int ROLE_APPLICATION = 0; public static final int ROLE_SUPPORT = 1; public static final int ROLE_INFRASTRUCTURE = 2;
public abstract String getParentName();
public abstract void setParentName(String paramString);
public abstract String getBeanClassName();
public abstract void setBeanClassName(String paramString);
public abstract String getFactoryBeanName();
public abstract void setFactoryBeanName(String paramString);
public abstract String getFactoryMethodName();
public abstract void setFactoryMethodName(String paramString);
public abstract String getScope();
public abstract void setScope(String paramString);
public abstract boolean isAutowireCandidate();
public abstract void setAutowireCandidate(boolean paramBoolean);
public abstract ConstructorArgumentValues getConstructorArgumentValues();
public abstract MutablePropertyValues getPropertyValues();
public abstract boolean isSingleton();
public abstract boolean isAbstract();
public abstract boolean isLazyInit();
public abstract String getResourceDescription();
public abstract BeanDefinition getOriginatingBeanDefinition();
public abstract int getRole(); } |
IOC的配置文件数据都保存在HashMap中,
key值就是xml中bean的id,value就是class的对象
并且创建的Map对象都是 java.util.concurrent.ConcurrentHashMap
spring是利用反射生成类,怎么生成的呢?
AbstractBeanDefinitionReader类
/* */ public int loadBeanDefinitions(String location) throws BeanDefinitionStoreException { /* 149 */ return loadBeanDefinitions(location, null); /* */ } /* */ /* */ public int loadBeanDefinitions(String location, Set actualResources) /* */ throws BeanDefinitionStoreException /* */ { /* 168 */ ResourceLoader resourceLoader = getResourceLoader(); /* 169 */ if (resourceLoader == null) { /* 170 */ throw new BeanDefinitionStoreException("Cannot import bean definitions from location [" + location + "]: no ResourceLoader available"); /* */ } /* */ /* */ /* 174 */ if ((resourceLoader instanceof ResourcePatternResolver)) { /* */ try /* */ { /* 177 */ Resource[] resources = ((ResourcePatternResolver)resourceLoader).getResources(location); /* 178 */ int loadCount = loadBeanDefinitions(resources); /* 179 */ if (actualResources != null) { /* 180 */ for (int i = 0; i < resources.length; i++) { /* 181 */ actualResources.add(resources[i]); /* */ } /* */ } /* 184 */ if (logger.isDebugEnabled()) { /* 185 */ logger.debug("Loaded " + loadCount + " bean definitions from location pattern [" + location + "]"); /* */ } /* 187 */ return loadCount; /* */ } /* */ catch (IOException ex) { /* 190 */ throw new BeanDefinitionStoreException("Could not resolve bean definition resource pattern [" + location + "]", ex); /* */ } /* */ } /* */ /* 196 */ Resource resource = resourceLoader.getResource(location); /* 197 */ int loadCount = loadBeanDefinitions(resource); /* 198 */ if (actualResources != null) { /* 199 */ actualResources.add(resource); /* */ } /* 201 */ if (logger.isDebugEnabled()) { /* 202 */ logger.debug("Loaded " + loadCount + " bean definitions from location [" + location + "]"); /* */ } /* 204 */ return loadCount; /* */ } /* */ /* */ /* */ public int loadBeanDefinitions(Resource[] resources) throws BeanDefinitionStoreException /* */ { /* 140 */ Assert.notNull(resources, "Resource array must not be null"); /* 141 */ int counter = 0; /* 142 */ for (int i = 0; i < resources.length; i++) { /* 143 */ counter += loadBeanDefinitions(resources[i]); /* */ } /* 145 */ return counter; /* */ } /* */
|
XmlBeanDefinitionReader类
/* */ /* */ public int loadBeanDefinitions(Resource resource) /* */ throws BeanDefinitionStoreException /* */ { /* 310 */ return loadBeanDefinitions(new EncodedResource(resource)); /* */ } /* */ /* */ /* Error */ /* */ public int loadBeanDefinitions(EncodedResource encodedResource) /* */ throws BeanDefinitionStoreException /* */ { /* */ // Byte code: /* */ // 0: aload_1 /* */ // 1: ldc -31 |
我这里源码报错了,下面都注释掉了。。。。。。尴尬了
我看网上别的源码版本
@Override public int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException { return loadBeanDefinitions(new EncodedResource(resource)); }
public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException { Assert.notNull(encodedResource, "EncodedResource must not be null"); if (logger.isInfoEnabled()) { logger.info("Loading XML bean definitions from " + encodedResource.getResource()); }
Set<EncodedResource> currentResources = this.resourcesCurrentlyBeingLoaded.get(); if (currentResources == null) { currentResources = new HashSet<EncodedResource>(4); this.resourcesCurrentlyBeingLoaded.set(currentResources); } if (!currentResources.add(encodedResource)) { throw new BeanDefinitionStoreException( "Detected cyclic loading of " + encodedResource + " - check your import definitions!"); } 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(); } } catch (IOException ex) { throw new BeanDefinitionStoreException( "IOException parsing XML document from " + encodedResource.getResource(), ex); } finally { currentResources.remove(encodedResource); if (currentResources.isEmpty()) { this.resourcesCurrentlyBeingLoaded.remove(); } } } |
XmlBeanDefinitionReader类
* */ } /* */ /* */ public int loadBeanDefinitions(InputSource inputSource) /* */ throws BeanDefinitionStoreException /* */ { /* 367 */ return loadBeanDefinitions(inputSource, "resource loaded through SAX InputSource"); /* */ } /* */ /* */ /* */ public int loadBeanDefinitions(InputSource inputSource, String resourceDescription) /* */ throws BeanDefinitionStoreException /* */ { /* 381 */ return doLoadBeanDefinitions(inputSource, new DescriptiveResource(resourceDescription)); /* */ } /* */ /* */ /* */ protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource) /* */ throws BeanDefinitionStoreException /* */ { /* */ try /* */ { /* 395 */ int validationMode = getValidationModeForResource(resource); /* 396 */ Document doc = documentLoader.loadDocument(inputSource, getEntityResolver(), errorHandler, validationMode, isNamespaceAware()); /* */ /* 398 */ return registerBeanDefinitions(doc, resource); /* */ } /* */ catch (BeanDefinitionStoreException ex) { /* 401 */ throw ex; /* */ } /* */ catch (SAXParseException ex) { /* 404 */ throw new XmlBeanDefinitionStoreException(resource.getDescription(), "Line " + ex.getLineNumber() + " in XML document from " + resource + " is invalid", ex); /* */ } /* */ catch (SAXException ex) |
DefaultDocumentLoader是DocumentLoader接口的实现类
* */ /* */ /* */ public Document loadDocument(InputSource inputSource, EntityResolver entityResolver, ErrorHandler errorHandler, int validationMode, boolean namespaceAware) /* */ throws Exception /* */ { /* 70 */ DocumentBuilderFactory factory = createDocumentBuilderFactory(validationMode, namespaceAware); /* 71 */ if (logger.isDebugEnabled()) { /* 72 */ logger.debug("Using JAXP provider [" + factory.getClass().getName() + "]"); /* */ } /* 74 */ DocumentBuilder builder = createDocumentBuilder(factory, entityResolver, errorHandler); /* 75 */ return builder.parse(inputSource); /* */ } /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ protected DocumentBuilderFactory createDocumentBuilderFactory(int validationMode, boolean namespaceAware) /* */ throws ParserConfigurationException /* */ { /* 89 */ DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); /* 90 */ factory.setNamespaceAware(namespaceAware); /* */ /* 92 */ if (validationMode != 0) { /* 93 */ factory.setValidating(true); /* */ /* 95 */ if (validationMode == 3) /* */ { /* 97 */ factory.setNamespaceAware(true); /* */ try { /* 99 */ factory.setAttribute("http://java.sun.com/xml/jaxp/properties/schemaLanguage", "http://www.w3.org/2001/XMLSchema"); /* */ } /* */ catch (IllegalArgumentException ex) { /* 102 */ ParserConfigurationException pcex = new ParserConfigurationException("Unable to validate using XSD: Your JAXP provider [" + factory + "] does not support XML Schema. Are you running on Java 1.4 with Apache Crimson? " + "Upgrade to Apache Xerces (or Java 1.5) for full XSD support."); /* */ /* */ /* */ /* 106 */ pcex.initCause(ex); /* 107 */ throw pcex; /* */ } /* */ } /* */ } /* */ /* 112 */ return factory; /* */ } /* */ |
DefaultBeanDefinitionDocumentReader
/* */ /* */ public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) /* */ { /* 84 */ this.readerContext = readerContext; /* */ /* 86 */ logger.debug("Loading bean definitions"); /* 87 */ Element root = doc.getDocumentElement(); /* */ /* 89 */ BeanDefinitionParserDelegate delegate = createHelper(readerContext, root); /* */ /* 91 */ preProcessXml(root); /* 92 */ parseBeanDefinitions(root, delegate); /* 93 */ postProcessXml(root); /* */ } /* */ /* */ protected BeanDefinitionParserDelegate createHelper(XmlReaderContext readerContext, Element root) { /* 97 */ BeanDefinitionParserDelegate delegate = new BeanDefinitionParserDelegate(readerContext); /* 98 */ delegate.initDefaults(root); /* 99 */ return delegate; /* */ } /* */ /* */ /* */ |
BeanDefinitionParserDelegate
/* */ /* */ /* */ /* */ public void initDefaults(Element root) /* */ { /* 298 */ DocumentDefaultsDefinition defaults = new DocumentDefaultsDefinition(); /* 299 */ defaults.setLazyInit(root.getAttribute("default-lazy-init")); /* 300 */ defaults.setMerge(root.getAttribute("default-merge")); /* 301 */ defaults.setAutowire(root.getAttribute("default-autowire")); /* 302 */ defaults.setDependencyCheck(root.getAttribute("default-dependency-check")); /* 303 */ if (root.hasAttribute("default-autowire-candidates")) { /* 304 */ defaults.setAutowireCandidates(root.getAttribute("default-autowire-candidates")); /* */ } /* 306 */ if (root.hasAttribute("default-init-method")) { /* 307 */ defaults.setInitMethod(root.getAttribute("default-init-method")); /* */ } /* 309 */ if (root.hasAttribute("default-destroy-method")) { /* 310 */ defaults.setDestroyMethod(root.getAttribute("default-destroy-method")); /* */ } /* 312 */ defaults.setSource(readerContext.extractSource(root)); /* */ /* 314 */ this.defaults = defaults; /* 315 */ readerContext.fireDefaultsRegistered(defaults); /* */ } /* */ /* */ /* */ |
DocumentDefaultsDefinition 这里面包含spring的对象bean的各种属性
/* */ public class DocumentDefaultsDefinition implements DefaultsDefinition /* */ { /* */ private String lazyInit; /* */ private String merge; /* */ private String autowire; /* */ private String dependencyCheck; /* */ private String autowireCandidates; /* */ private String initMethod; /* */ private String destroyMethod; /* */ private Object source; /* */ /* */ public void setLazyInit(String lazyInit) /* */ { /* 52 */ this.lazyInit = lazyInit; /* */ } /* */ /* */ /* */ /* */ public String getLazyInit() /* */ { /* 59 */ return lazyInit; /* */ } /* */ /* */ /* */ /* */ public void setMerge(String merge) /* */ { /* 66 */ this.merge = merge; /* */ } /* */ /* */ /* */ |
这里面有个很重要的类 Element root
package org.w3c.dom;
/** * The <code>Element</code> interface represents an element in an HTML or XML * document. Elements may have attributes associated with them; since the * <code>Element</code> interface inherits from <code>Node</code>, the * generic <code>Node</code> interface attribute <code>attributes</code> may * be used to retrieve the set of all attributes for an element. There are * methods on the <code>Element</code> interface to retrieve either an * <code>Attr</code> object by name or an attribute value by name. In XML, * where an attribute value may contain entity references, an * <code>Attr</code> object should be retrieved to examine the possibly * fairly complex sub-tree representing the attribute value. On the other * hand, in HTML, where all attributes have simple string values, methods to * directly access an attribute value can safely be used as a convenience. * <p ><b>Note:</b> In DOM Level 2, the method <code>normalize</code> is * inherited from the <code>Node</code> interface where it was moved. * <p>See also the <a href='http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407'>Document Object Model (DOM) Level 3 Core Specification</a>. */ 通过有道词典翻译: *代码>元素</code>接口表示HTML或XML中的一个元素 *文档。元素可能具有与其相关联的属性;自 *代码>元素</code>接口继承自<code>节点</code>, *通用<code>Node</code> interface attribute <code>attributes</code> may . *用于检索元素的所有属性集。有 *方法在<code>元素</code>接口检索一个 * <code>Attr</code> object by name or an attribute value by name。在XML中, 属性值可能包含实体引用的地方,用 * <code>Attr</code>对象应该被检索来检查 表示属性值的相当复杂的子树。另一方面 * hand,在HTML中,所有属性都有简单的字符串值,方法到 *直接访问属性值可以作为一种便利而安全地使用。 * <p ><b>注:</b>在DOM Level 2,方法<code>normalize</code> is *继承自<code>Node</code> interface where it was moved。 * <p>参见<a href='http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407'>文档对象模型(DOM) 3级核心规范</a>。 public interface Element extends Node { /** * The name of the element. If <code>Node.localName</code> is different * from <code>null</code>, this attribute is a qualified name. For * example, in: * <pre> <elementExample id="demo"> ... * </elementExample> , </pre> * <code>tagName</code> has the value * <code>"elementExample"</code>. Note that this is case-preserving in * XML, as are all of the operations of the DOM. The HTML DOM returns * the <code>tagName</code> of an HTML element in the canonical * uppercase form, regardless of the case in the source HTML document. */ public String getTagName(); |
还有一个类:Document
package org.w3c.dom;
/** * The <code>Document</code> interface represents the entire HTML or XML * document. Conceptually, it is the root of the document tree, and provides * the primary access to the document's data. * <p>Since elements, text nodes, comments, processing instructions, etc. * cannot exist outside the context of a <code>Document</code>, the * <code>Document</code> interface also contains the factory methods needed * to create these objects. The <code>Node</code> objects created have a * <code>ownerDocument</code> attribute which associates them with the * <code>Document</code> within whose context they were created. * <p>See also the <a href='http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407'>Document Object Model (DOM) Level 3 Core Specification</a>. */ 通过有道词典翻译: 包org.w3c.dom; / * * *代码>文档</code>接口表示整个HTML或XML *文档。从概念上讲,它是文档树的根,并提供 *对文档数据的主要访问。 * <p>Since元素、文本节点、注释、处理指令等。 *不能存在于<code>Document</code>, the * <code>Document</code> interface也包含了需要的工厂方法 *创建这些对象。创建的<code>节点</code>对象有一个 * <code>ownerDocument</code> attribute which associates them with the * <code>Document</code>在其上下文中创建它们。 * <p>参见<a href='http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407'>文档对象模型(DOM) 3级核心规范</a>。 * / public interface Document extends Node { /** * The Document Type Declaration (see <code>DocumentType</code>) * associated with this document. For XML documents without a document * type declaration this returns <code>null</code>. For HTML documents, * a <code>DocumentType</code> object may be returned, independently of * the presence or absence of document type declaration in the HTML * document. * <br>This provides direct access to the <code>DocumentType</code> node, * child node of this <code>Document</code>. This node can be set at * document creation time and later changed through the use of child * nodes manipulation methods, such as <code>Node.insertBefore</code>, * or <code>Node.replaceChild</code>. Note, however, that while some * implementations may instantiate different types of * <code>Document</code> objects supporting additional features than the * "Core", such as "HTML" [<a href='http://www.w3.org/TR/2003/REC-DOM-Level-2-HTML-20030109'>DOM Level 2 HTML</a>] * , based on the <code>DocumentType</code> specified at creation time, * changing it afterwards is very unlikely to result in a change of the * features supported. * * @since DOM Level 3 */ public DocumentType getDoctype(); |
Element 及 Document 都是w3c包下面的
以上代码没有涉及到java反射技术,
总结:通过加载配置文件,然后转变成流,最后w3c技术把流转换成Document 及Element 类,最后封装成BeanDefinition 对象,并且放到Map里面
key就是applicationContext.xml里面的<bean id="XXX">中的id名称xxx
value就是BeanDefinition对象
但是大家都说spring利用反射技术生成,为啥这么说呢?
需要继续看
一般我们做测试的时候代码都是这样写的
@Test public void test1() { String conf = "/applicationContext.xml"; ApplicationContext ac = new ClassPathXmlApplicationContext(conf);// 实例化容器 CostDAO costDAO = (CostDAO) ac.getBean("jdbcCostDAO");// 获取Bean对象 costDAO.save(); } |
他们之间的关系图
|
ac.getBean("jdbcCostDAO")这段代码怎么实现的呢?
由于ApplicationContext 跟 ClassPathXmlApplicationContext 都不包含getBean(String beanName)这个方法
但是请看AbstractApplicationContext这个类
/* */ public Object getBean(String name) /* */ throws BeansException /* */ { /* 881 */ return getBeanFactory().getBean(name); /* */ } /* */ /* */ public Object getBean(String name, Class requiredType) throws BeansException { /* 885 */ return getBeanFactory().getBean(name, requiredType); /* */ } /* */ /* */ public Object getBean(String name, Object[] args) throws BeansException { /* 889 */ return getBeanFactory().getBean(name, args); /* */ } /* */ /* */ public boolean containsBean(String name) { /* 893 */ return getBeanFactory().containsBean(name); /* */ } /* */ -------------------------------------------------------------------- /* */ public abstract ConfigurableListableBeanFactory getBeanFactory() /* */ throws IllegalStateException; /* */ |
ConfigurableListableBeanFactory 查看这个类
package org.springframework.beans.factory.config;
import org.springframework.beans.BeansException; import org.springframework.beans.factory.ListableBeanFactory; import org.springframework.beans.factory.NoSuchBeanDefinitionException;
public abstract interface ConfigurableListableBeanFactory extends ListableBeanFactory, AutowireCapableBeanFactory, ConfigurableBeanFactory { public abstract void ignoreDependencyType(Class paramClass);
public abstract void ignoreDependencyInterface(Class paramClass);
public abstract void registerResolvableDependency(Class paramClass, Object paramObject);
public abstract boolean isAutowireCandidate(String paramString, DependencyDescriptor paramDependencyDescriptor) throws NoSuchBeanDefinitionException;
public abstract BeanDefinition getBeanDefinition(String paramString) throws NoSuchBeanDefinitionException;
public abstract void freezeConfiguration();
public abstract boolean isConfigurationFrozen();
public abstract void preInstantiateSingletons() throws BeansException; } |
里面没有包含 getBean方法,所以他们继承了最大父类的BeanFactory的 getBean方法
大boss BeanFactory
package org.springframework.beans.factory;
import org.springframework.beans.BeansException;
public abstract interface BeanFactory { public static final String FACTORY_BEAN_PREFIX = "&";
public abstract Object getBean(String paramString) throws BeansException;
public abstract Object getBean(String paramString, Class paramClass) throws BeansException;
public abstract Object getBean(String paramString, Object[] paramArrayOfObject) throws BeansException;
public abstract boolean containsBean(String paramString);
public abstract boolean isSingleton(String paramString) throws NoSuchBeanDefinitionException;
public abstract boolean isPrototype(String paramString) throws NoSuchBeanDefinitionException;
public abstract boolean isTypeMatch(String paramString, Class paramClass) throws NoSuchBeanDefinitionException;
public abstract Class getType(String paramString) throws NoSuchBeanDefinitionException;
public abstract String[] getAliases(String paramString); } |
那spring怎么实现getBean方法呢,只有看子类了
AbstractBeanFactory
/* */ public Object getBean(String name) /* */ throws BeansException /* */ { /* 164 */ return getBean(name, null, null); /* */ } /* */ /* */ public Object getBean(String name, Class requiredType) throws BeansException { /* 168 */ return getBean(name, requiredType, null); /* */ } /* */ /* */ public Object getBean(String name, Object[] args) throws BeansException { /* 172 */ return getBean(name, null, args); /* */ } /* */ /* */ public Object getBean(String name, Class requiredType, Object[] args) /* */ throws BeansException /* */ { /* 185 */ return doGetBean(name, requiredType, args, false); /* */ } /* */ /* */ protected Object doGetBean(String name, Class requiredType, final Object[] args, boolean typeCheckOnly) /* */ throws BeansException /* */ { /* 202 */ final String beanName = transformedBeanName(name); /* 203 */ Object bean = null; /* */ /* */ /* 206 */ Object sharedInstance = getSingleton(beanName); /* 207 */ if (sharedInstance != null) { /* 208 */ if (logger.isDebugEnabled()) { /* 209 */ if (isSingletonCurrentlyInCreation(beanName)) { /* 210 */ logger.debug("Returning eagerly cached instance of singleton bean '" + beanName + "' that is not fully initialized yet - a consequence of a circular reference"); /* */ } /* */ else /* */ { /* 214 */ logger.debug("Returning cached instance of singleton bean '" + beanName + "'"); /* */ } /* */ } /* 217 */ bean = getObjectForBeanInstance(sharedInstance, name, beanName, null); /* */ /* */ } /* */ else /* */ { /* */ /* 223 */ if (isPrototypeCurrentlyInCreation(beanName)) { /* 224 */ throw new BeanCurrentlyInCreationException(beanName); /* */ } /* */ /* */ /* 228 */ BeanFactory parentBeanFactory = getParentBeanFactory(); /* 229 */ if ((parentBeanFactory != null) && (!containsBeanDefinition(beanName))) /* */ { /* 231 */ String nameToLookup = originalBeanName(name); /* 232 */ if (args != null) /* */ { /* 234 */ return parentBeanFactory.getBean(nameToLookup, args); /* */ } /* */ /* */ /* 238 */ return parentBeanFactory.getBean(nameToLookup, requiredType); /* */ } /* */ /* */ /* 242 */ if (!typeCheckOnly) { /* 243 */ markBeanAsCreated(beanName); /* */ } /* */ /* 246 */ final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); /* 247 */ checkMergedBeanDefinition(mbd, beanName, args); /* */ /* */ /* 250 */ String[] dependsOn = mbd.getDependsOn(); /* 251 */ if (dependsOn != null) { /* 252 */ for (int i = 0; i < dependsOn.length; i++) { /* 253 */ String dependsOnBean = dependsOn[i]; /* 254 */ getBean(dependsOnBean); /* 255 */ registerDependentBean(dependsOnBean, beanName); /* */ } /* */ } /* */ /* */ /* 260 */ if (mbd.isSingleton()) { /* 261 */ sharedInstance = getSingleton(beanName, new ObjectFactory() { /* */ public Object getObject() throws BeansException { /* */ try { /* 264 */ return createBean(beanName, mbd, args); /* */ /* */ } /* */ catch (BeansException ex) /* */ { /* */ /* 270 */ destroySingleton(beanName); /* 271 */ throw ex; /* */ } /* */ } /* 274 */ }); /* 275 */ bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd); /* */ /* */ } /* 278 */ else if (mbd.isPrototype()) /* */ { /* 280 */ Object prototypeInstance = null; /* */ try { /* 282 */ beforePrototypeCreation(beanName); /* 283 */ prototypeInstance = createBean(beanName, mbd, args); /* */ } /* */ finally { /* 286 */ afterPrototypeCreation(beanName); /* */ } /* 288 */ bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd); /* */ } /* */ else /* */ { /* 292 */ String scopeName = mbd.getScope(); /* 293 */ Scope scope = (Scope)scopes.get(scopeName); /* 294 */ if (scope == null) { /* 295 */ throw new IllegalStateException("No Scope registered for scope '" + scopeName + "'"); /* */ } /* */ try { /* 298 */ Object scopedInstance = scope.get(beanName, new ObjectFactory() { /* */ public Object getObject() throws BeansException { /* 300 */ beforePrototypeCreation(beanName); /* */ try { /* 302 */ return createBean(beanName, mbd, args); /* */ } /* */ finally { /* 305 */ afterPrototypeCreation(beanName); /* */ } /* */ } /* 308 */ }); /* 309 */ bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd); /* */ } /* */ catch (IllegalStateException ex) { /* 312 */ 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); /* */ } /* */ } /* */ } /* 321 */ if ((requiredType != null) && (bean != null) && (!requiredType.isAssignableFrom(bean.getClass()))) { /* 322 */ throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass()); /* */ } /* 324 */ return bean; /* */ } /* */ /* */ /* */ protected Object getObjectForBeanInstance(Object beanInstance, String name, String beanName, RootBeanDefinition mbd) /* */ { /* 1262 */ if ((BeanFactoryUtils.isFactoryDereference(name)) && (!(beanInstance instanceof FactoryBean))) { /* 1263 */ throw new BeanIsNotAFactoryException(transformedBeanName(name), beanInstance.getClass()); /* */ } /* */ /* */ /* */ /* */ /* 1269 */ if ((!(beanInstance instanceof FactoryBean)) || (BeanFactoryUtils.isFactoryDereference(name))) { /* 1270 */ return beanInstance; /* */ } /* */ /* 1273 */ Object object = null; /* 1274 */ if (mbd == null) { /* 1275 */ object = getCachedObjectForFactoryBean(beanName); /* */ } /* 1277 */ if (object == null) /* */ { /* 1279 */ FactoryBean factory = (FactoryBean)beanInstance; /* */ /* 1281 */ if ((mbd == null) && (containsBeanDefinition(beanName))) { /* 1282 */ mbd = getMergedLocalBeanDefinition(beanName); /* */ } /* 1284 */ boolean synthetic = (mbd != null) && (mbd.isSynthetic()); /* 1285 */ object = getObjectFromFactoryBean(factory, beanName, !synthetic); /* */ } /* 1287 */ return object; /* */ } /* */ /* */ /* */ protected RootBeanDefinition getMergedLocalBeanDefinition(String beanName) /* */ throws BeansException /* */ { /* 964 */ RootBeanDefinition mbd = (RootBeanDefinition)mergedBeanDefinitions.get(beanName); /* 965 */ if (mbd != null) { /* 966 */ return mbd; /* */ } /* 968 */ return getMergedBeanDefinition(beanName, getBeanDefinition(beanName)); /* */ } /* */ /* */ protected abstract BeanDefinition getBeanDefinition(String paramString) /* */ throws BeansException; //这里也用到了BeanDefinition 类 * */ /* */ /* */ protected Object getObjectFromFactoryBean(FactoryBean factory, String beanName, boolean shouldPostProcess) /* */ { /* 87 */ if ((factory.isSingleton()) && (containsSingleton(beanName))) { /* 88 */ synchronized (getSingletonMutex()) { /* 89 */ Object object = factoryBeanObjectCache.get(beanName); /* 90 */ if (object == null) { /* 91 */ object = doGetObjectFromFactoryBean(factory, beanName, shouldPostProcess); /* 92 */ factoryBeanObjectCache.put(beanName, object != null ? object : NULL_OBJECT); /* */ } /* 94 */ return object != NULL_OBJECT ? object : null; /* */ } /* */ } /* 98 */ return doGetObjectFromFactoryBean(factory, beanName, shouldPostProcess); /* */ } /* */ //注意 factoryBeanObjectCache 就是一个Map /* */ private final Map factoryBeanObjectCache = CollectionFactory.createConcurrentMapIfPossible(16); /* */ /* */ private Object doGetObjectFromFactoryBean(final FactoryBean factory, final String beanName, final boolean shouldPostProcess) /* */ throws BeanCreationException /* */ { /* 115 */ AccessControlContext acc = AccessController.getContext(); /* 116 */ AccessController.doPrivileged(new PrivilegedAction() /* */ { /* */ public Object run() { /* */ Object object; /* */ try { /* 121 */ object = factory.getObject(); /* */ } /* */ catch (FactoryBeanNotInitializedException ex) { /* 124 */ throw new BeanCurrentlyInCreationException(beanName, ex.toString()); /* */ } /* */ catch (Throwable ex) { /* 127 */ throw new BeanCreationException(beanName, "FactoryBean threw exception on object creation", ex); /* */ } /* */ /* */ /* */ /* 132 */ if ((object == null) && (isSingletonCurrentlyInCreation(beanName))) { /* 133 */ throw new BeanCurrentlyInCreationException(beanName, "FactoryBean which is currently in creation returned null from getObject"); /* */ } /* */ /* */ /* 137 */ if ((object != null) && (shouldPostProcess)) { /* */ try { /* 139 */ object = postProcessObjectFromFactoryBean(object, beanName); /* */ } /* */ catch (Throwable ex) { /* 142 */ throw new BeanCreationException(beanName, "Post-processing of the FactoryBean's object failed", ex); /* */ } /* */ } /* */ /* 146 */ return object; } }, acc); /* */ } /* */ /* */ protected Object postProcessObjectFromFactoryBean(Object object, String beanName) /* */ throws BeansException /* */ { /* 162 */ return object; /* */ } /* */ |
AbstractFactoryBean类是FactoryBean的子类
/* */ package org.springframework.beans.factory.config; /* */ /* */ import java.lang.reflect.InvocationHandler; /* */ import java.lang.reflect.InvocationTargetException; /* */ import java.lang.reflect.Method; /* */ import java.lang.reflect.Proxy; //从上面导入的包 //一看就知道用到了java的反射了 /* 66 */ private boolean initialized = false; /* 62 */ private boolean singleton = true; /* */ public boolean isSingleton() { /* 82 */ return singleton; /* */ } /* */ public final Object getObject() /* */ throws Exception /* */ { /* 132 */ if (isSingleton()) { /* 133 */ return initialized ? singletonInstance : getEarlySingletonInstance(); /* */ } /* 136 */ return createInstance(); /* */ } /* */ /* */ private Object getEarlySingletonInstance() /* */ throws Exception /* */ { /* 145 */ Class[] ifcs = getEarlySingletonInterfaces(); /* 146 */ if (ifcs == null) { /* 147 */ throw new FactoryBeanNotInitializedException(getClass().getName() + " does not support circular references"); /* */ } /* */ /* 150 */ if (earlySingletonInstance == null) { /* 151 */ earlySingletonInstance = Proxy.newProxyInstance(getClass().getClassLoader(), ifcs, new InvocationHandler() /* */ { /* */ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { /* */ try { /* 155 */ return method.invoke(AbstractFactoryBean.this.getSingletonInstance(), args); /* */ } /* */ catch (InvocationTargetException ex) { /* 158 */ throw ex.getTargetException(); /* */ } /* */ } /* */ }); /* */ } /* 163 */ return earlySingletonInstance; /* */ } /* */ |
原来是FactoryBean这个接口的抽象子类AbstractFactoryBean
创造Bean的时候java反射了
spring底层反射源码找到了,有机会自己也试下
我反正是那种明明知道对了,但是自己不亲身试下,心里面就犯嘀咕的人
找了一下午终于搞定了,这次心算舒心了,顺便把过程分享给志同道合的朋友们
这是本人探索了,如有不对的地方,请指正
如果喜欢就点个赞吧,唯一小心愿啦
参考文档:
Spring IOC源码实现流程:https://blog.csdn.net/DS_1258/article/details/102427760