SpringIOC底层源码分析(xml文件加载,底层反射创建对象)

首先分析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> &lt;elementExample id="demo"&gt; ...

          * &lt;/elementExample&gt; , </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

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值