Spring源码剖析(四)ioc(一)

开始剖析了好紧张啊,Spring还是写个半懂就开始剖析了

先从ioc开始分析,因为我也不太会所以从最基础的来

分析的版本为3.2.x

因为比较稳定,而且也是主流的版本,从github上就能下到,然后使用的是sourceinsght

不用图片说话自己就会忘记

 

AliasRegistry:定义对alias的简单增删改

Single

ListableBeanFactory根据条件获取bean的配置清单。

AbstractBeanFactory 提供了Register支持和Configable的

先理解下几个问题

1.Spring存放了类的哪些信息呢?

 

①类名(姓名),该类是否抽象(种别),该类的父类(家庭信息),该类的包名(家庭地址)(基本信息)

②属性,构造函数(否则怎么构造函数注入和Setter注入啊?)

③Annotation(否则你@Controller写这样的注解的时候,它怎么知道他是Controller呢?)

这些信息就是类的名片,根据这些信息,我们容器就可以把该类“造”出来,BeanDefinition

 

其次就是BeanFactory   ioc中 最重要的接口

 

先分析BeanFactory  刚开始带着翻译讲,而且有利于提高英语阅读能力,后面的话只看比较重要的部分

package org.springframework.beans.factory;

* The root interface for accessing a Spring bean container.
* This is the basic client view of a bean container;

原话:这是一个spring容器的根接口,展现给使用者

进一步的更专用接口有ListableBeanFactory和ConfigurableBeanFactory

 * <p>This interface is implemented by objects that hold a number of bean definitions,
 * each uniquely identified by a String name. Depending on the bean definition,
 * the factory will return either an independent instance of a contained object
 * (the Prototype design pattern), or a single shared instance (a superior
 * alternative to the Singleton design pattern, in which the instance is a
 * singleton in the scope of the factory)

差不多是讲这个接口被持有具体bean定义的目标对象实例化并且通过id区分,工厂可以返回一个单例的(默认)或者原型的实例

 * <p>Note that it is generally better to rely on Dependency Injection
 * ("push" configuration) to configure application objects through setters
 * or constructors, rather than use any form of "pull" configuration like a
 * BeanFactory lookup. Spring's Dependency Injection functionality is
 * implemented using this BeanFactory interface and its subinterfaces.

依赖注入的设置注入和构造注入更优于 传统的pull ,Spring的di是通过BeanFactory和子类实现

 * <p>Normally a BeanFactory will load bean definitions stored in a configuration
 * source (such as an XML document), and use the {@code org.springframework.beans}
 * package to configure the beans. However, an implementation could simply return
 * Java objects it creates as necessary directly in Java code. There are no
 * constraints on how the definitions could be stored: LDAP, RDBMS, XML,
 * properties file, etc. Implementations are encouraged to support references
 * amongst beans (Dependency Injection).

BeanFactory通常从xml配置文件中加载bean定义

The full set of initialization methods and their standard order is:<br>
 * 1. BeanNameAware's {@code setBeanName}<br>
 * 2. BeanClassLoaderAware's {@code setBeanClassLoader}<br>
 * 3. BeanFactoryAware's {@code setBeanFactory}<br>
 * 4. EnvironmentAware's {@code setEnvironment}
 * 5. EmbeddedValueResolverAware's {@code setEmbeddedValueResolver}
 * 6. ResourceLoaderAware's {@code setResourceLoader}
 * (only applicable when running in an application context)<br>
 * 7. ApplicationEventPublisherAware's {@code setApplicationEventPublisher}
 * (only applicable when running in an application context)<br>
 * 8. MessageSourceAware's {@code setMessageSource}
 * (only applicable when running in an application context)<br>
 * 9. ApplicationContextAware's {@code setApplicationContext}
 * (only applicable when running in an application context)<br>
 * 10. ServletContextAware's {@code setServletContext}
 * (only applicable when running in a web application context)<br>
 * 11. {@code postProcessBeforeInitialization} methods of BeanPostProcessors<br>
 * 12. InitializingBean's {@code afterPropertiesSet}<br>
 * 13. a custom init-method definition<br>
 * 14. {@code postProcessAfterInitialization} methods of BeanPostProcessors

设置注入的完整流程

 * <p>On shutdown of a bean factory, the following lifecycle methods apply:<br>
 * 1. {@code postProcessBeforeDestruction} methods of DestructionAwareBeanPostProcessors
 * 2. DisposableBean's {@code destroy}<br>
 * 3. a custom destroy-method definition

 关闭后的流程

这个接口其实很简单    也没啥讲的  主要是获取实例和判断类型,给bean起别名

public interface BeanFactory {

   String FACTORY_BEAN_PREFIX = "&";

    Object getBean(String name) throws BeansException;

   <T> T getBean(String name, Class<T> requiredType) throws BeansException;

    <T> T getBean(Class<T> requiredType) throws BeansException;

    Object getBean(String name, Object... args) throws BeansException;

    boolean containsBean(String name);

    boolean isSingleton(String name) throws NoSuchBeanDefinitionException;

    boolean isPrototype(String name) throws NoSuchBeanDefinitionException;

    boolean isTypeMatch(String name, Class<?> targetType) throws NoSuchBeanDefinitionException;

    boolean isTypeMatch(String name, Class<?> targetType) throws NoSuchBeanDefinitionException;

    String[] getAliases(String name);

}

 

 

 

 

 

所以BeanFactory只是定义了“汤勺”的基本性质,我们来看看他的子类,看看具体的一些汤勺吧~

DefaultListableBeanFactory最牛比的一个类

先看源码定义

 * Default implementation of the
 * {@link org.springframework.beans.factory.ListableBeanFactory} and
 * {@link BeanDefinitionRegistry} interfaces: a full-fledged bean factory
 * based on bean definition objects.
 *
 * <p>Typical usage is registering all bean definitions first (possibly read
 * from a bean definition file), before accessing beans. Bean definition lookup
 * is therefore an inexpensive operation in a local bean definition table,
 * operating on pre-built bean definition metadata objects.
 *
 * <p>Can be used as a standalone bean factory, or as a superclass for custom
 * bean factories. Note that readers for specific bean definition formats are
 * typically implemented separately rather than as bean factory subclasses:
 * see for example {@link PropertiesBeanDefinitionReader} and
 * {@link org.springframework.beans.factory.xml.XmlBeanDefinitionReader}.
 *
 * <p>For an alternative implementation of the
 * {@link org.springframework.beans.factory.ListableBeanFactory} interface,
 * have a look at {@link StaticListableBeanFactory}, which manages existing
 * bean instances rather than creating new ones based on bean definitions.

差不多是讲这是它们的默认实现,源码讲的像屎一样,这里就不翻译了

public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory
        implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable {

挑重要的讲吧  主要对bean注册后的处理

ConfigurableListableBeanFactory  BeanFactory配置清单,指定忽略类型和接口

该类拥有的属性有

 

serializationId   序列号id

allowBeanDefinitionOverriding = true   是否可 以 重名

allowEagerClassLoading = true    是否延迟加


    /** Map from serialized id to factory instance */
 private static final Map<String, Reference<DefaultListableBeanFactory>> serializableFactories =
            new ConcurrentHashMap<String, Reference<DefaultListableBeanFactory>>(8);

 

AutowireCandidateResolver autowireCandidateResolver = new SimpleAutowireCandidateResolver()

 

 final Map<Class<?>, Object> resolvableDependencies = new HashMap<Class<?>, Object>(16);

final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<String, BeanDefinition>(64);

final Map<Class<?>, String[]> allBeanNamesByType = new ConcurrentHashMap<Class<?>, String[]>(64);

final Map<Class<?>, String[]> singletonBeanNamesByType = new ConcurrentHashMap<Class<?>, String[]>(64);

final List<String> beanDefinitionNames = new ArrayList<String>(64);

boolean configurationFrozen = false;

String[] frozenBeanDefinitionNames;

构造方法有多种,基本以父类构造为主

public DefaultListableBeanFactory() {
        super();
    }

接口实现

 

  //---------------------------------------------------------------------
    // Implementation of ListableBeanFactory interface
    //---------------------------------------------------------------------

    public <T> T getBean(Class<T> requiredType) throws BeansException {
        Assert.notNull(requiredType, "Required type must not be null");

//获取beanname数组

       String[] beanNames = getBeanNamesForType(requiredType);
        if (beanNames.length > 1) {
            ArrayList<String> autowireCandidates = new ArrayList<String>();
            for (String beanName : beanNames) {
                if (!containsBeanDefinition(beanName) || getBeanDefinition(beanName).isAutowireCandidate()) {
                    autowireCandidates.add(beanName);
                }
            }
            if (autowireCandidates.size() > 0) {
                beanNames = autowireCandidates.toArray(new String[autowireCandidates.size()]);
            }
        }
        if (beanNames.length == 1) {
            return getBean(beanNames[0], requiredType);//父类方法
        }
        else if (beanNames.length > 1) {
            T primaryBean = null;
            for (String beanName : beanNames) {
                T beanInstance = getBean(beanName, requiredType);
                if (isPrimary(beanName, beanInstance)) {
                    if (primaryBean != null) {
                        throw new NoUniqueBeanDefinitionException(requiredType, beanNames.length,
                                "more than one 'primary' bean found of required type: " + Arrays.asList(beanNames));
                    }
                    primaryBean = beanInstance;
                }
            }
            if (primaryBean != null) {
                return primaryBean;
            }
            throw new NoUniqueBeanDefinitionException(requiredType, beanNames);
        }
        else if (getParentBeanFactory() != null) {
            return getParentBeanFactory().getBean(requiredType);
        }
        else {
            throw new NoSuchBeanDefinitionException(requiredType);
        }
    }

 

 

 

 

 

我们在来看父类

public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
        implements AutowireCapableBeanFactory {

看到实例缓存
private final Map<String, BeanWrapper> factoryBeanInstanceCache =
            new ConcurrentHashMap<String, BeanWrapper>(16);


 构造函数

  

 public AbstractAutowireCapableBeanFactory() {
        super();
        ignoreDependencyInterface(BeanNameAware.class);
        ignoreDependencyInterface(BeanFactoryAware.class);
        ignoreDependencyInterface(BeanClassLoaderAware.class);
    }

 


它的子类

 

 

public class XmlBeanFactory extends DefaultListableBeanFactory {

private final XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(this);

public XmlBeanFactory(Resource resource) throws BeansException {
        this(resource, null);
    }

public XmlBeanFactory(Resource resource, BeanFactory parentBeanFactory) throws BeansException {
        super(parentBeanFactory);
        this.reader.loadBeanDefinitions(resource);
    }
}

补充:

容器的基础xmlBeanFactory

主要从xml文档中读取BeanDefinition  注册和获取Bean都是父类DefaultListableBeanFactory继承的方法去实现

不同点多了XmlBeanDefinitionReader  reader对资源文件 进行读取和注册

 

XmlBeanDefinitionReader分析

我们然后梳理资源文件读取解析注册的大致脉络

ResourceLoader 定义资源加载类返回Resource

BeanDefinationReader 定义资源文件转换为BeanDefitionReader的各个功能

EnirmentCapable 定义获取Environment方法

DoucumentLoader定义从资源文件加载转化到Doucment的功能

AbstractBeanDefinationReader对以上实现

BeanDefinationDocumentReader定义读取Dcument并注册BeanDefination功能

BeanDefiantionPaserDelegate定义解析Element方法

 

xml读取的大致流程

1.继承AbstractBeanDefinationReader 中的方法来使用ResourceLoader将资源路径转化为Resource文件

2.通过DoucumentLoader把Resource转化为Document文件

3.通过DefaultBeanDefinitionDoucmentReader类对Doucment解析,并使用BeanDefinitionParserDelegate对Element解析

 

通常通过ClassPathResource来构造Resource资源实例供后续处理,那么Resource资源如何封装的呢??

配置文件的封装

Resource接口来实现底层资源的封装  InputStreamSource  只有一个getInputStream() 方法

public interface Resource extends InputStreamSource {

先分析ClassPathResource  

 public class XmlBeanDefinitionReader extends AbstractBeanDefinitionReader {
boolean exists();

boolean isReadable();

boolean isOpen();

URL getURL() throws IOException;

URI getURI() throws IOException;

File getFile() throws IOException;

long contentLength() throws IOException;

long lastModified() throws IOException;

Resource createRelative(String relativePath) throws IOException;

String getFilename();

String getDescription();//错误处理中打印信息

}

 

 

感觉相当于对url补充,提供了检查当前资源状态(可读,存在,打开)的接口

 

 

Resource接口抽象了Spring内部使用到的底层资源File,URL,URI,Classpath,以及获取权限或者文件名的方法

createRealative()提供创建一个相对资源的方法

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值