• spring全家桶


    一、spring

    1、概念解释

    spring:java应用程序类与类之间互相协作是比较费劲的,需要在类中自行创建对象并且管理对象的整个生命周期,会造成代码高度耦合和不可想象的复杂度,而spring就是一个帮助java应用程序管理对象创建、依赖关系和生命周期的第三方组件

    DI:依赖注入,创建被调用实例的工作由spring容器完成,然后注入调用者

    IOC:控制反转,创建被调用者实例的工作不再由调用者来完成

    IOC容器:负责创建对象和管理对象之间依赖关系的容器

    BeanFactory:最简单的容器接口,只定义了基本的DI功能

    ApplicationContext应用上下文:实现了BeanFactory接口和其他各种功能,提供更多企业级的服务

    2、模块说明

    spring-core:发现、建立和维护每个 Bean 之间的关系所需要的一些列的工具

    spring-bean:Bean 的定义(BeanDefinition)、Bean 的创建(BeanFactory)以及对 Bean 的解析

    spring-context:Bean的IOC容器(ApplicationContext)

    3、ioc容器详细说明(许令波)

    ioc作为一个容器,它里面放得都是bean,bean与bean之间的对应关系,而bean之间的对应关系我们开始都是通过xml配置文件来体现的,所以ioc容器需要面对这些问题:

    • 对应与对象之间的关系是通过xml配置文件来描述的(当然也可以是properties等文件)
    • 描述的文件存放位置在那里,一般来说我们都是放在classpath目录下的,但是也可以是URL、fileSystem
    • 文件的解析
    • Bean在容器中的表现形式,也就是它的数据结构

    对于Spring而言,它用Resource、BeanDefinition、BeanDefinitionReader、BeanFactory、ApplicationContext五个组件来实现以上问题,而同时这5个接口定义了 spring ioc 容器的基本代码组件结构:

    Resource:对资源的抽象,它的每一个实现类都代表了一种资源的访问策略,如ClasspathResource 、 URLResource ,FileSystemResource 等

    BeanDefinition:用来描述和抽象一个具体的Bean对象,它是描述Bean对象的基本数据结构。配置文件中的每一个bean对应一个BeanDefinition实例

    BeanDefinitionReader:外部资源所表达的语义需要转化为内部数据结构BeanDefinition,BeanDefinitionReader起到解析的作用。对应不同的描述需要有不同的Reader 。如 XmlBeanDefinitionReader 用来读取xml 描述配置的 bean 对象

    BeanFactory:是一个纯粹的bean容器,它是IOC必备的数据结构,其中BeanDefinition是它的基本结构,它内部维护着一个BeanDefinition map,并可根据BeanDefinition 的描述进行 bean 的创建和管理

    ApplicationContext:这个就是大名鼎鼎的Spring容器,它叫做应用上下文,与我们应用息息相关,它继承BeanFactory,是BeanFactory的扩展升级版。由于ApplicationContext的结构就决定了它与BeanFactory的不同,其主要区别有:

    • 继承MessageSource,提供国际化的标准访问策略
    • 继承ApplicationEventPublisher,提供强大的事件机制
    • 扩展ResourceLoader,可以用来加载多个Resource,可以灵活访问不同的资源
    • 对Web应用的支持

    4、ioc启动流程

    ApplicationContext context = new ClassPathXmlApplicationContext("spring-ioc.xml");
    

    在main方法中通过读取xml配置的方式创建应用上下文

    public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, @Nullable ApplicationContext parent) throws BeansException {
        super(parent);
        //设置配置文件路径
        setConfigLocations(configLocations);
        if (refresh) {
            //执行最核心的刷新方法
            this.refresh();
        }
    }
    

    执行AbstractApplicationContext的refresh()方法

    public void refresh() throws BeansException, IllegalStateException {
        synchronized(this.startupShutdownMonitor) {
            //准备刷新的上下文环境,例如对系统属性或者环境变量进行准备及验证
            prepareRefresh();
            //初始化BeanFactory,并进行XML文件读取,
            //这一步之后,ClassPathXmlApplicationContext实际上就已经包含了BeanFactory所提供的功能,也就是可以进行Bean的提取等基础操作了
            ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
            //对BeanFactory进行各种功能填充,@Qualifier与@Autowired这两个注解正是在这一步骤中增加的支持。
            //设置@Autowired和 @Qualifier注解解析器QualifierAnnotationAutowireCandidateResolver
            prepareBeanFactory(beanFactory);
            try {
                //子类覆盖方法做额外的处理,提供了一个空的函数实现postProcessBeanFactory来方便程序员在业务上做进一步扩展
                postProcessBeanFactory(beanFactory);
                //激活各种BeanFactory处理器(spring boot下会执行关键的配置类加载,完成@Configuration注解的配置类装配)
                invokeBeanFactoryPostProcessors(beanFactory);
                //注册拦截Bean创建的Bean处理器,这里只是注册,真正的调用是在getBean时候
                registerBeanPostProcessors(beanFactory);
                //为上下文初始化Message源,即不同语言的消息体进行国际化处理
                initMessageSource();
                //初始化应用消息广播器(如果用户定义了就用用户的,如果没有默认用户ApplicationEventMulticaster)
                initApplicationEventMulticaster();
                //留给子类来初始化其它的Bean
                onRefresh();
                //在所有注册的bean中查找Listener bean,注册到消息广播器中
                registerListeners();
                //初始化剩下的单实例(非惰性的)
                finishBeanFactoryInitialization(beanFactory);
                //完成刷新过程,通知生命周期处理器lifecycleProcessor刷新过程,同时发出ContextRefreshEvent通知别人
                finishRefresh();
            } catch (BeansException ex) {
                if (this.logger.isWarnEnabled()) {
                    this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + ex);
                }
                destroyBeans();
                cancelRefresh(ex);
                throw ex;
            } finally {
                resetCommonCaches();
            }
        }
    }
    
    1)初始化工作,创建ioc容器并加载Bean的定义

    在this.obtainFreshBeanFactory()这个方法中会创建一个DefaultListableBeanFactory容器,这个容器是第一个可以独立使用的ioc容器,所有spring ioc容器的始祖

    看一下DefaultListableBeanFactory容器的依赖图

    protected final void refreshBeanFactory() throws BeansException {
        //如果已经有容器,销毁容器中的bean,关闭容器
        if (hasBeanFactory()) {
            destroyBeans();
            closeBeanFactory();
        }
        try {
            //创建最基础的ioc容器
            DefaultListableBeanFactory beanFactory = createBeanFactory();
            //为了序列化指定id
            beanFactory.setSerializationId(getId());
            //简单定制化
            customizeBeanFactory(beanFactory);
            //关键方法,加载bean到容器
            loadBeanDefinitions(beanFactory);
            this.beanFactory = beanFactory;
        } catch (IOException ex) {
            throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
        }
    }
    

    继续看loadBeanDefinitions(beanFactory)方法,实现方法在父类AbstractXmlApplicationContext中

    protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
        //为指定beanFactory创建XmlBeanDefinitionReader
        XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
        //对beanDefinitionReader进行环境变量的设置
        beanDefinitionReader.setEnvironment(this.getEnvironment());
        beanDefinitionReader.setResourceLoader(this);
        beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
        //对BeanDefinitionReader进行设置,可以覆盖
        initBeanDefinitionReader(beanDefinitionReader);
        //(关键)使用XmlBeanDefinitionReader的loadBeanDefinitions方法进行配置文件的加载及注册
        loadBeanDefinitions(beanDefinitionReader);
    }
    

    创建了XmlBeanDefinitionReader读取器,作为参数调用loadBeanDefinitions()方法,最终读取器的loadBeanDefinitions()被调用

    public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException {
        ……
        //将资源文件转换为io流
        try (InputStream inputStream = encodedResource.getResource().getInputStream()) {
            InputSource inputSource = new InputSource(inputStream);
            if (encodedResource.getEncoding() != null) {
                inputSource.setEncoding(encodedResource.getEncoding());
            }
            //真正开始读取bean
            return doLoadBeanDefinitions(inputSource, encodedResource.getResource());
        }
        ……
    }
    

    这一步完成了定位阶段,开始加载bean,继续一直调用直到registerBeanDefinitions()方法

    public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
        //创建读取文件并加载Bean的类
        BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();
        int countBefore = getRegistry().getBeanDefinitionCount();
        //加载Bean
        documentReader.registerBeanDefinitions(doc, createReaderContext(resource));
        return getRegistry().getBeanDefinitionCount() - countBefore;
    }
    

    执行了BeanDefinitionDocumentReader接口的registerBeanDefinitions()方法,进行Bean的解析和注册操作

    进入实现类DefaultBeanDefinitionDocumentReader的doRegisterBeanDefinitions()方法

    protected void doRegisterBeanDefinitions(Element root) {
        ……
        preProcessXml(root);
        //使用spring的Bean规则解析元素节点
        parseBeanDefinitions(root, this.delegate);
        postProcessXml(root);
        ……
    }
    

    进入parseBeanDefinitions方法,如果发现是Bean节点的话会再进入processBeanDefinition()方法,很关键,这里面就会完成Bean的解析和注册

    protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
        //(核心)最终会调用BeanDefinitionParserDelegate这个辅助操作实现类的parseBeanDefinitionElement()方法进行Bean解析
        BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
        if (bdHolder != null) {
            bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
            try {
                //(核心)向spring ioc容器中注册解析得到的Bean定义,这是Bean定义向ioc容器注册的入口
                BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
            }
            catch (BeanDefinitionStoreException ex) {
                getReaderContext().error("Failed to register bean definition with name '" + bdHolder.getBeanName() + "'", ele, ex);
            }
            getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
        }
    }
    

    parseBeanDefinitionElement()解析方法是从document中解析xml并得到Bean的定义

    然后执行BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry())方法注册Bean到容器,这里的getRegistry()拿到的其实就是最开始创建Reader读取器的时候设置过的ioc容器(new XmlBeanDefinitionReader(beanFactory)),作为第二个入参传入了registerBeanDefinition()方法

    public static void registerBeanDefinition(BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry) throws BeanDefinitionStoreException {
    
        //获取Bean的名字
        String beanName = definitionHolder.getBeanName();
        //registry的实现其实是DefaultListableBeanFactory,注册Bean
        registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
    
        //注册Bean的别名
        String[] aliases = definitionHolder.getAliases();
        if (aliases != null) {
            for (String alias : aliases) {
                registry.registerAlias(beanName, alias);
            }
        }
    }
    

    最后来看一下DefaultListableBeanFactory容器的registerBeanDefinition()是如何进行Bean的注册的

    不贴代码了,最终执行了this.beanDefinitionMap.put(beanName, beanDefinition);将Bean添加到了一个ConcurrentHashMap中

    2)准备工作,配置ioc容器的特性

    查看prepareBeanFactory()方法

    protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
        //设置容器的类加载器为当前上下文
        beanFactory.setBeanClassLoader(getClassLoader());
        beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
        beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
    
        //增加一个用来给继承了Aware的类设置上下文的前置处理器
        beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
        //忽略Aware类
        beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
        beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
        beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
        beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
        beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
        beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
    
        //自动装配的特殊规则,这样可以通过autowired的方式拿到ApplicationContext的实例
        beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
        beanFactory.registerResolvableDependency(ResourceLoader.class, this);
        beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
        beanFactory.registerResolvableDependency(ApplicationContext.class, this);
    
        //增加一个用来在Bean(ApplicationListener)销毁之前从ApplicationEventMulticaster(事件广播器)中提前删除的后置处理器
        beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
    
        //增加对AspectJ的支持
        if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
            beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
            // Set a temporary ClassLoader for type matching.
            beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
        }
    
        //将相关环境变量及属性注册以单例模式注册,environment,systemProperties,systemEnvironment
        if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
            beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
        }
        if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
            beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
        }
        if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
            beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
        }
    }
    

    prepareBeanFactory()方法完成了一些ioc容器特性的设置,增加了两个Bean处理器

    postProcessBeanFactory()空实现做扩展

    invokeBeanFactoryPostProcessors()激活各种BeanFactory处理器

    registerBeanPostProcessors()注册Bean处理器

    initMessageSource()初始化Message源,国际化

    initApplicationEventMulticaster()初始化应用消息广播器

    onRefresh()空实现,让子类初始化其他Bean

    registerListeners()查找所有监听器,注册到消息广播器中

    3)收尾工作,完成ioc容器初始化

    进入finishBeanFactoryInitialization()方法,然后进入beanFactory.preInstantiateSingletons()方法(在DefaultListableBeanFactory中)

    public void preInstantiateSingletons() throws BeansException {
        if (logger.isTraceEnabled()) {
            logger.trace("Pre-instantiating singletons in " + this);
        }
    
        //获取容器内所有bean名称
        List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
    
        //遍历所有bean
        for (String beanName : beanNames) {
            //很经典的一句,通过递归将BeanDefinition所有父类的属性和方法合并到一起,得到RootBeanDefinition返回
            RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
            //如果不是抽象类,如果是单例,如果不是懒加载
            if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
                //如果是FactoryBean的类
                if (isFactoryBean(beanName)) {
                    //先getBean创建这个FactoryBean(BeanName前面加了&)
                    Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
                    if (bean instanceof FactoryBean) {
                        FactoryBean<?> factory = (FactoryBean<?>) bean;
                        boolean isEagerInit;
                        if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
                            isEagerInit = AccessController.doPrivileged(
                                    (PrivilegedAction<Boolean>) ((SmartFactoryBean<?>) factory)::isEagerInit,
                                    getAccessControlContext());
                        }
                        else {
                            isEagerInit = (factory instanceof SmartFactoryBean && ((SmartFactoryBean<?>) factory).isEagerInit());
                        }
                        //如果是SmartFactoryBean且不是懒加载的话需要立刻创建这个FactoryBean
                        if (isEagerInit) {
                            getBean(beanName);
                        }
                    }
                }
                else {
                    //创建Bean
                    getBean(beanName);
                }
            }
        }
    
        //如果Bean实例实现了SmartInitializingSingleton接口就执行它的afterSingletonsInstantiated()方法,在Bean实例化完成后执行某些操作
        for (String beanName : beanNames) {
            Object singletonInstance = getSingleton(beanName);
            if (singletonInstance instanceof SmartInitializingSingleton) {
                SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
                if (System.getSecurityManager() != null) {
                    AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
                        smartSingleton.afterSingletonsInstantiated();
                        return null;
                    }, getAccessControlContext());
                }
                else {
                    smartSingleton.afterSingletonsInstantiated();
                }
            }
        }
    }
    

    然后进入最最最核心的getBean()和doGetBean()方法

    protected <T> T doGetBean(String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly) throws BeansException {
    
        //通过别名得到最终的名字
        String beanName = transformedBeanName(name);
        Object bean;
    
        //先尝试获取Bean
        Object sharedInstance = getSingleton(beanName);
        if (sharedInstance != null && args == null) {
            if (logger.isTraceEnabled()) {
                //若条件为true,表示这个Bean虽然在缓存里,但是还并没有完全被初始化(循环引用)
                if (isSingletonCurrentlyInCreation(beanName)) {
                    logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +
                            "' that is not fully initialized yet - a consequence of a circular reference");
                }
                else {
                    logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
                }
            }
            //简单理解就是处理FactoryBean的getObject()方法
            bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
        }
    
        else {
            //原型对象不允许循环创建,如果是原型对象正在创建,那就抛异常
            if (isPrototypeCurrentlyInCreation(beanName)) {
                throw new BeanCurrentlyInCreationException(beanName);
            }
    
            //这一步也是必须要做的,若存在父容器,得看看父容器是否实例化过它了。避免被重复实例化(若父容器被实例化,就以父容器的为准)
            BeanFactory parentBeanFactory = getParentBeanFactory();
            if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
                // Not found -> check parent.
                String nameToLookup = originalBeanName(name);
                if (parentBeanFactory instanceof AbstractBeanFactory) {
                    return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
                            nameToLookup, requiredType, args, typeCheckOnly);
                }
                else if (args != null) {
                    return (T) parentBeanFactory.getBean(nameToLookup, args);
                }
                else if (requiredType != null) {
                    return parentBeanFactory.getBean(nameToLookup, requiredType);
                }
                else {
                    return (T) parentBeanFactory.getBean(nameToLookup);
                }
            }
    
            //确认是否已经创建,创建了就加入alreadyCreated重
            if (!typeCheckOnly) {
                markBeanAsCreated(beanName);
            }
    
            try {
                RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
                //确认是否是抽象类
                checkMergedBeanDefinition(mbd, beanName, args);
    
                //@dependsOn属性可以控制Bean的初始化顺序
                String[] dependsOn = mbd.getDependsOn();
                if (dependsOn != null) {
                    for (String dep : dependsOn) {
                        if (isDependent(beanName, dep)) {
                            throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                                    "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
                        }
                        //添加Bean和它依赖Bean的相互依赖关系到2个map
                        registerDependentBean(dep, beanName);
                        try {
                            //先创建依赖Bean的实例
                            getBean(dep);
                        }
                        catch (NoSuchBeanDefinitionException ex) {
                            throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                                    "'" + beanName + "' depends on missing bean '" + dep + "'", ex);
                        }
                    }
                }
    
                //从这里开始就真的要创建这个Bean的实例了
                if (mbd.isSingleton()) {
                    //也是一样先尝试从缓存去获取,如果没有就用createBean()方法去创建
                    sharedInstance = getSingleton(beanName, () -> {
                        try {
                            //这是创建Bean的核心方法,非常重要
                            return createBean(beanName, mbd, args);
                        }
                        catch (BeansException ex) {
                            //执行失败就销毁Bean,销毁一条龙
                            destroySingleton(beanName);
                            throw ex;
                        }
                    });
                    //处理FactoryBean的情况
                    bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
                }
                //创建原型Bean(每次用到都会创建)
                else if (mbd.isPrototype()) {
                    // It's a prototype -> create a new instance.
                    Object prototypeInstance = null;
                    try {
                        //加入正在创建Prototype列表
                        beforePrototypeCreation(beanName);
                        //创建Bean
                        prototypeInstance = createBean(beanName, mbd, args);
                    }
                    finally {
                        //移除正在创建Prototype列表
                        afterPrototypeCreation(beanName);
                    }
                    bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
                }
                //其他情况,类似
                else {
                    String scopeName = mbd.getScope();
                    if (!StringUtils.hasLength(scopeName)) {
                        throw new IllegalStateException("No scope name defined for bean ´" + beanName + "'");
                    }
                    Scope scope = this.scopes.get(scopeName);
                    if (scope == null) {
                        throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
                    }
                    try {
                        Object scopedInstance = scope.get(beanName, () -> {
                            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);
                    }
                }
            }
            catch (BeansException ex) {
                cleanupAfterBeanCreationFailure(beanName);
                throw ex;
            }
        }
    
        //如果需要类型转换的话就转换,一般用不到
        if (requiredType != null && !requiredType.isInstance(bean)) {
            try {
                T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
                if (convertedBean == null) {
                    throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
                }
                return convertedBean;
            }
            catch (TypeMismatchException ex) {
                if (logger.isTraceEnabled()) {
                    logger.trace("Failed to convert bean '" + name + "' to required type '" +
                            ClassUtils.getQualifiedName(requiredType) + "'", ex);
                }
                throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
            }
        }
        return (T) bean;
    }
    

    然后看一下2个getSingleton()和createBean()方法

    protected Object getSingleton(String beanName, boolean allowEarlyReference) {
        //从一级缓存中找
        Object singletonObject = this.singletonObjects.get(beanName);
        //如果没找到并且Bean正在创建,才会进入二级和三级缓存中寻找
        if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
            synchronized (this.singletonObjects) {
                singletonObject = this.earlySingletonObjects.get(beanName);
                //如果二级缓存中没有并且spring允许循环依赖(默认为true),就进入三级缓存中寻找
                if (singletonObject == null && allowEarlyReference) {
                    ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
                    if (singletonFactory != null) {
                        singletonObject = singletonFactory.getObject();
                        //将找到的Bean从三级缓存中放入二级缓存
                        this.earlySingletonObjects.put(beanName, singletonObject);
                        this.singletonFactories.remove(beanName);
                    }
                }
            }
        }
        return singletonObject;
    }
    

    三个缓存的相爱相杀

    public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
        Assert.notNull(beanName, "Bean name must not be null");
        synchronized (this.singletonObjects) {
            //先从一级缓存中获取
            Object singletonObject = this.singletonObjects.get(beanName);
            if (singletonObject == null) {
                //如果Bean正在被销毁就抛异常
                if (this.singletonsCurrentlyInDestruction) {
                    throw new BeanCreationNotAllowedException(beanName,
                            "Singleton bean creation not allowed while 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 + "'");
                }
                //如果不排除创建检查,就将Bean加入到正在创建singletonsCurrentlyInCreation的map中
                beforeSingletonCreation(beanName);
                boolean newSingleton = false;
                boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
                if (recordSuppressedExceptions) {
                    this.suppressedExceptions = new LinkedHashSet<>();
                }
                try {
                    //从外层的createBean()拿到返回值
                    singletonObject = singletonFactory.getObject();
                    newSingleton = true;
                }
                catch (IllegalStateException ex) {
                    singletonObject = this.singletonObjects.get(beanName);
                    if (singletonObject == null) {
                        throw ex;
                    }
                }
                catch (BeanCreationException ex) {
                    if (recordSuppressedExceptions) {
                        for (Exception suppressedException : this.suppressedExceptions) {
                            ex.addRelatedCause(suppressedException);
                        }
                    }
                    throw ex;
                }
                finally {
                    if (recordSuppressedExceptions) {
                        this.suppressedExceptions = null;
                    }
                    //从正在创建singletonsCurrentlyInCreation的map中移除
                    afterSingletonCreation(beanName);
                }
                if (newSingleton) {
                    //如果创建完成就从二、三级缓存中移除,加入一级缓存,加入已注册Bean的列表
                    addSingleton(beanName, singletonObject);
                }
            }
            return singletonObject;
        }
    }
    

    这个getSingleton()相当于对createBean()方法执行前后做了一些处理,如果一级缓存中没有Bean就进行createBean()

    再看一下createBean(),是由子类AbstractAutowireCapableBeanFactory去实现的

    protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException {
    
        if (logger.isTraceEnabled()) {
            logger.trace("Creating instance of bean '" + beanName + "'");
        }
        RootBeanDefinition mbdToUse = mbd;
    
        //确保对应BeanClass完成解析
        Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
        if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
            mbdToUse = new RootBeanDefinition(mbd);
            mbdToUse.setBeanClass(resolvedClass);
        }
    
        //解析<lookup-method name="getFruit" bean="bananer"/>类似这种方式的依赖注入,不常用
        try {
            mbdToUse.prepareMethodOverrides();
        }
        catch (BeanDefinitionValidationException ex) {
            throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
                    beanName, "Validation of method overrides failed", ex);
        }
    
        try {
            //关键方法,给BeanPostProcessors一个机会来返回一个代理对象代替目标对象,动态代理就是在这里实现的
            //容器里所有的InstantiationAwareBeanPostProcessors实例都会在此处生效,进行前置处理
            Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
            if (bean != null) {
                return bean;
            }
        }
        catch (Throwable ex) {
            throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
                    "BeanPostProcessor before instantiation of bean failed", ex);
        }
    
        try {
            //好了,又是一个核心逻辑,创建Bean
            Object beanInstance = doCreateBean(beanName, mbdToUse, args);
            if (logger.isTraceEnabled()) {
                logger.trace("Finished creating instance of bean '" + beanName + "'");
            }
            return beanInstance;
        }
        catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
            throw ex;
        }
        catch (Throwable ex) {
            throw new BeanCreationException(
                    mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
        }
    }
    

    有resolveBeforeInstantiation()前置处理方法和doCreateBean()方法要讲,先看resolveBeforeInstantiation()

    protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
        Object bean = null;
        //判断这个Bean定义是否需要前置处理
        if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
            //不是构造出的内部类并且有前置处理器
            if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
                Class<?> targetType = determineTargetType(beanName, mbd);
                if (targetType != null) {
                    //执行前置实例化方法,给用户一个生成代理对象的机会
                    //处理器是遍历执行的,只要有一个result为null,后面就不遍历了,所以顺序很重要,可以用@OrderId设置
                    bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
                    if (bean != null) {
                        //如果得到了对象,就执行后置初始化方法
                        bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
                    }
                }
            }
            //如果Bean实例化了就设置
            mbd.beforeInstantiationResolved = (bean != null);
        }
        return bean;
    }
    

    在Bean要开始实例化、属性赋值、初始化之前,执行InstantiationAwareBeanPostProcessor处理器的前置实例化方法和后置初始化方法(可能,如果有的话就跳过了后置实例化方法和前置初始化方法)

    protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException {
    
        //用BeanWrapper来持有创建出来的Bean对象
        BeanWrapper instanceWrapper = null;
        //如果是单例的话,则先把缓存中的同名bean清除(同名的)
        if (mbd.isSingleton()) {
            instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
        }
        if (instanceWrapper == null) {
            //关键了,这里就是Bean的实例化,Bean创建的第一步
            //实际创建的交给createBeanInstance来完成,包装成BeanWrapperImpl类
            instanceWrapper = createBeanInstance(beanName, mbd, args);
        }
        Object bean = instanceWrapper.getWrappedInstance();
        Class<?> beanType = instanceWrapper.getWrappedClass();
        if (beanType != NullBean.class) {
            mbd.resolvedTargetType = beanType;
        }
    
        synchronized (mbd.postProcessingLock) {
            if (!mbd.postProcessed) {
                try {
                    //主要是处理@PostConstruct,@Autowire,@Value,@Resource,@PreDestory等这些注解
                    //注解都会实现MergedBeanDefinitionPostProcessor接口
                    applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
                }
                catch (Throwable ex) {
                    throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                            "Post-processing of merged bean definition failed", ex);
                }
                mbd.postProcessed = true;
            }
        }
    
        //如果是单例模式、允许循环依赖、正在进行Bean创建
        boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences && isSingletonCurrentlyInCreation(beanName));
        if (earlySingletonExposure) {
            if (logger.isTraceEnabled()) {
                logger.trace("Eagerly caching bean '" + beanName + "' to allow for resolving potential circular references");
            }
            //addSingletonFactory就是为了处理循环依赖,将Bean放入三级缓存
            //getEarlyBeanReference很关键,用到了SmartInstantiationAwareBeanPostProcessor,允许这层进行扩展处理
            //这个方法也是写入singletonFactories三级缓存的地方
            addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
        }
    
        //这个Bean是最终要返回的对象
        Object exposedObject = bean;
        try {
            //又是很关键的一步,进行Bean的属性赋值,在这里完成依赖注入,Bean创建的第二步
            populateBean(beanName, mbd, instanceWrapper);
            
            //叒是很关键的一步,进行Bean的初始化,Bean创建的最后一步
            exposedObject = initializeBean(beanName, exposedObject, mbd);
        }
        catch (Throwable ex) {
            if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
                throw (BeanCreationException) ex;
            }
            else {
                throw new BeanCreationException(
                        mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
            }
        }
    
        //继续解决循环依赖问题,用到前面的earlySingletonExposure1结果
        if (earlySingletonExposure) {
            Object earlySingletonReference = getSingleton(beanName, false);
            if (earlySingletonReference != null) {
                if (exposedObject == bean) {
                    exposedObject = earlySingletonReference;
                }
                else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
                    String[] dependentBeans = getDependentBeans(beanName);
                    Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
                    for (String dependentBean : dependentBeans) {
                        if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
                            actualDependentBeans.add(dependentBean);
                        }
                    }
                    if (!actualDependentBeans.isEmpty()) {
                        throw new BeanCurrentlyInCreationException(beanName,
                                "Bean with name '" + beanName + "' has been injected into other beans [" +
                                StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
                                "] in its raw version as part of a circular reference, but has eventually been " +
                                "wrapped. This means that said other beans do not use the final version of the " +
                                "bean. This is often the result of over-eager type matching - consider using " +
                                "'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.");
                    }
                }
            }
        }
    
        //如果有需要,就注册DisposableBean,这样Bean销毁的时候此种后置处理器也会生效了
        try {
            registerDisposableBeanIfNecessary(beanName, bean, mbd);
        }
        catch (BeanDefinitionValidationException ex) {
            throw new BeanCreationException(
                    mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
        }
    
        return exposedObject;
    }
    

    createBeanInstance()方法生成了Bean的BeanWrapperImpl实例对象,Bean的实例化,Bean创建的第一步

    populateBean()方法进行了Bean的属性赋值(包括@Autowired等依赖属性注入),Bean创建的第二步

    initializeBean()方法进行Bean的初始化,Bean创建的最后一步

    后续不跟代码了,可以看这里

    5、如何解决循环依赖

    1)spring循环依赖总结

    spring能解决单例的属性注入(setter方法注入)循环依赖

    spring不能解决构造器注入循环依赖和多例的属性注入循环依赖

    2)spring怎么解决循环依赖?

     spring解决循环依赖的方式是通过缓存队列提前暴露的还未完成的bean对象,如果对象A在属性赋值阶段需要注入一个依赖自己的对象B,那在对象B创建时就可以在缓存队列中找到对象A的引用,完成对象的创建,不然就会一直循环创建下去造成内存溢出

    3)为什么spring不能解决构造器注入循环依赖?

    spring创建Bean的步骤是实例化、属性赋值、初始化,是在属性赋值阶段解决循环依赖的,构造器注入相当于将前两步同时进行,还没有完成实例化就需要进行属性赋值,这样spring没法通过提前暴露未完成bean的方式来解决循环依赖

    4)为什么spring不能解决多例属性注入循环依赖?

    单例的情况每个对象是固定的,处理循环引用时getBean可以拿到同一个提前暴露对象的引用,而多例的情况下每次getBean都会创建一个新的对象,无法确定引用哪一个

    5)我们怎么解决spring解决不了的循环依赖?

    我们可以解决的是构造器注入循环依赖的情况:重新设计、合理分层、尽量不要使用构造器注入,使用属性注入或setter方法注入

    6)为什么需要三级缓存?

    如果没有aop的话二级缓存就可以解决循环依赖的问题,有aop的话为了避免每次singleFactory.getObject()方法每次都产生一个新的代理对象,所以需要另一个缓存来保存产生的代理对象

    所以最后的三级缓存作用分别是:一级缓存存放完全初始化、成品的bean,二级缓存存放半成品的bean或bean的代理对象,三级缓存存放ObjectFactory,如果是bean被代理getObject返回代理对象,不然就返回原bean对象

    6、ioc容器扩展点

    BeanFactoryPostProcessor、BeanPostProcessor,分别在构建 BeanFactory 和构建 Bean 对象时调用

    BeanDefinitionRegistryPostProcessor 、InstantiationAwareBeanPostProcessor?

    InitializingBean、DisposableBean,分别是在 Bean 实例创建和销毁时被调用

    FactoryBean,构建 Bean 对象时调用,通常是用来创建比较复杂的bean,一般的bean 直接用xml配置即可,但如果一个bean的创建过程中涉及到很多其他的bean 和复杂的逻辑,用xml配置比较困难,这时可以考虑用FactoryBean

    7、aop

    8、事务

    二、spring mvc

    1、spring mvc的启动流程

    2、一次请求调用的流程

    3、如何自定义注解? 

    三、spring boot

    1、spring模块驱动的实现方式?

    引入模块化驱动可以简化装配步骤,屏蔽模块中组件集合装配的细节

    spring实现@Enable模块有两种方式

    基于@Import注解,通过@Import注解导入标注了@Configuration的配置类

    基于接口编程,实现ImportSelector接口的selectImports方法,或者ImportBeanDefinitionRegistrar接口重写registerBeanDefinitions方法,通过 BeanDefinitionRegistry注册和该模块相关的组件

    2、spring boot的自动装配

    spring boot的启动类@SpringBootApplication注解包含了一个@EnableAutoConfiguration注解,通过这个注解引入了自动装配模块

    -- 在这个注解中@AutoConfigurationPackage注解负责扫描当前主类所在包和依赖包下的bean,

    在这个注解中Import了AutoConfigurationImportSelector类,这个类实现了selectImports接口,

    -- (貌似其实不会)首先会从当前的spring-boot-autoconfigure包的META-INF下的元数据json中加载properties配置项,然后在

    它会在classpath下每个Jar包中搜寻所有META-INF/spring.factories配置文件,spring.factories文件中的AutoConfiguration配置类类名集合,将类名去重、排除、过滤,最终返回自动装配的类名集合,

    这个方法会在ioc启动时,容器的refresh方法的invokeBeanFactoryPostProcessors这一步,被ConfigurationClassPostProcessor创建的ConfigurationClassParser类用到,完成配置类的装配

    spring.factories配置的方式是一种类似SPI的扩展机制(为某些接口寻找服务实现的机制,往往去约定的位置读取配置发现需要加载的实现类)

    3、spring boot的启动流程

    准备阶段会做SpringApplication类的初始化,判断web应用类型、加载应用上下文初始化类,从所有的META-INF/spring.factories资源中获取ApplicationContextInitializer的实现类(这些类是在在ConfigurableApplicationContext的refresh() 方法调用之前做一些初始化工作)、加载应用事件监听器。获取ApplicationListener的实现类(主要功能是另起一个后台线程触发那些耗时的初始化,包括验证器、消息转换器等,spring boot支持的事件主要有环境构建完成时、上下文构建完成时、上下文加载完成时、上下文刷新完成并启动时、启动完成时、启动失败时,在下一步运行阶段的相应时刻就会推送事件)

    运行阶段会先从所有的META-INF/spring.factories资源中获取SpringApplicationRunListeners事件监听器,然后设置环境信息、根据web类型创建上下文(判断创建普通容器还是web容器)、准备上下文、刷新容器(完成bean的加载)、最后执行Runner的实现类完成一些自定义初始化,期间穿插事件方法的回调

    4、嵌入式容器自动装配流程

    在SpringApplication类启动的run()方法里会根据web类型创建应用上下文,然后在容器的refresh()方法中,在invokeBeanFactoryPostProcessors()这步执行ConfigurationClassPostProcessor类的扩展,读取spring.factories并加载ServletWebServerFactoryAutoConfiguration类,这个类通过@Import导入了3个用来创建web容器工厂类内部类(有tomcat、jetty和undertow),如果存在maven依赖就会创建相应的web容器工厂类

    之后执行容器的onRefresh()方法,web应用上下文作为子类重写了这个方法,找到servlet web容器工厂Bean,创建内嵌的tomcat服务

    最后在容器的finishRefresh()时执行web服务的启动webServer.start()

    5、starter机制

    四、spring cloud

  • 相关阅读:
    WordPress Pretty Photo插件‘hashrel’参数跨站脚本漏洞
    WordPress Suco Themes ‘themify-ajax.php’任意文件上传漏洞
    nginx 安全漏洞 (CVE-2013-4547)
    Linux kernel ‘uio_mmap_physical’函数缓冲区溢出漏洞
    OpenSSH ‘mm_newkeys_from_blob’函数权限许可和访问控制漏洞
    WordPress Kernel Theme ‘upload-handler.php’任意文件上传漏洞
    Wordpress Jigoshop插件路径泄露漏洞
    WordPress Think Responsive Themes ‘upload_settings_image.php’任意文件上传漏洞
    Linux Kernel ‘write_tag_3_packet()’函数本地基于堆的缓冲区溢出漏洞
    SpringMVC配置数据验证(JSR-303)
  • 原文地址:https://www.cnblogs.com/ctxsdhy/p/13606004.html
Copyright © 2020-2023  润新知