spring boot 源码

扫码关注公众号:Java 技术驿站

发送:vip
将链接复制到本浏览器,永久解锁本站全部文章

【公众号:Java 技术驿站】 【加作者微信交流技术,拉技术群】
        PropertySource和Enviroment   http://blog.csdn.net/u011179993/article/details/51511364
        统一抽象资源---Resource  http://blog.csdn.net/u011179993/article/details/51531140
        SpringApplicationRunListener及其周期  http://blog.csdn.net/u011179993/article/details/51555690
        BeanDefinition及读取、注册  http://blog.csdn.net/u011179993/article/details/51598567
        http://blog.csdn.net/u011179993/article/category/5623745

    BeanDefinitionRegistry   该类的作用主要是向注册表中注册 BeanDefinition 实例,完成 注册的过程。
            public interface BeanDefinitionRegistry extends AliasRegistry {

            // 关键 -> 往注册表中注册一个新的 BeanDefinition 实例 
            void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)throws BeanDefinitionStoreException;

            // 移除注册表中已注册的 BeanDefinition 实例
            void removeBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;

            // 从注册中取得指定的 BeanDefinition 实例
            BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;

            // 判断 BeanDefinition 实例是否在注册表中(是否注册)
            boolean containsBeanDefinition(String beanName);

            // 取得注册表中所有 BeanDefinition 实例的 beanName(标识)
            String[] getBeanDefinitionNames();

            // 返回注册表中 BeanDefinition 实例的数量
            int getBeanDefinitionCount();

            // beanName(标识)是否被占用
            boolean isBeanNameInUse(String beanName);
            }

    http://blog.csdn.net/u011179993/article/details/51655057    
    BeanFactoryPostProcessor  当spring初始化好BenaDefinnitionMap之后,提供了一个接口BeanFactoryPostProcessor,允许我们开发者自定义的去修改BeanFactory中的内容,这也是符合“spring”的开闭原则
            public interface BeanFactoryPostProcessor {

        /**
         * 这里提供了修改beanFacotry的机会
             */
        void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;

            }

    http://jinnianshilongnian.iteye.com/blog/2000183
    PropertySource:属性源,key-value属性对抽象,比如用于配置数据

    PropertyResolver 属性解析器,用来根据名字解析其值等
        public interface PropertyResolver {  

            //是否包含某个属性  
            boolean containsProperty(String key);  

                //获取属性值 如果找不到返回null   
            String getProperty(String key);  

                //获取属性值,如果找不到返回默认值        
            String getProperty(String key, String defaultValue);  

                //获取指定类型的属性值,找不到返回null  
            <T> T getProperty(String key, Class<T> targetType);  

                //获取指定类型的属性值,找不到返回默认值  
            <T> T getProperty(String key, Class<T> targetType, T defaultValue);  

                 //获取属性值为某个Class类型,找不到返回null,如果类型不兼容将抛出ConversionException  
            <T> Class<T> getPropertyAsClass(String key, Class<T> targetType);  

                //获取属性值,找不到抛出异常IllegalStateException  
            String getRequiredProperty(String key) throws IllegalStateException;  

                //获取指定类型的属性值,找不到抛出异常IllegalStateException         
            <T> T getRequiredProperty(String key, Class<T> targetType) throws IllegalStateException;  

                //替换文本中的占位符(${key})到属性值,找不到不解析  
            String resolvePlaceholders(String text);  

                //替换文本中的占位符(${key})到属性值,找不到抛出异常IllegalArgumentException  
            String resolveRequiredPlaceholders(String text) throws IllegalArgumentException;  

        }   

    http://blog.csdn.net/u011179993/article/details/51598567
    BeanDefinition  这个接口描述bean的结构,对应XML中的< bean >或者配置类中的@Bean 它集成了BeanMetadataElement和AttributeAccessor

    PropertyValues  包含了一个或者多个PropertyValue对象,通常用作特定的一个目的bean的属性更新   

    AttributeAccessor接口定义了最基本的对任意对象的元数据的修改或者获取  

        private void initialize(Object[] sources) {
            if (sources != null && sources.length > 0) {
                this.sources.addAll(Arrays.asList(sources));
            }

            //判断是否web环境 
            //javax.servlet.Servlet"和"org.springframework.web.context.ConfigurableWebApplicationContext"类能被加载到代表为web环境
            this.webEnvironment = deduceWebEnvironment();

            /*
            *通过Thread.currentThread().getContextClassLoader(); 获取到 类加载器
            *获取 spring-boot-{v}.jar/META-INF/spring.factories 文件中 org.springframework.context.ApplicationContextInitializer 的值
            *   org.springframework.boot.context.ConfigurationWarningsApplicationContextInitializer   配置警告应用程序上下文初始化程序
            *   org.springframework.boot.context.ContextIdApplicationContextInitializer  上下文Id 应用上下文初始化器
            *   org.springframework.boot.context.config.DelegatingApplicationContextInitializer 委托应用程序上下文初始化程序
        *   org.springframework.boot.context.embedded.ServerPortInfoApplicationContextInitializer  设置端口
            *并通过各自的构造方法实例化
            *
            */
            setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));

          /*
          *获取 spring-boot-{v}.jar/META-INF/spring.factories 文件中 org.springframework.context.ApplicationListener 的值,并实例化
          *  org.springframework.boot.ClearCachesApplicationListener
          *  org.springframework.boot.builder.ParentContextCloserApplicationListener
          *  org.springframework.boot.context.FileEncodingApplicationListener
          *  org.springframework.boot.context.config.AnsiOutputApplicationListener
          *  org.springframework.boot.context.config.ConfigFileApplicationListener
          *  org.springframework.boot.context.config.DelegatingApplicationListener
          *  org.springframework.boot.liquibase.LiquibaseServiceLocatorApplicationListener
          *  org.springframework.boot.logging.ClasspathLoggingApplicationListener
          *  org.springframework.boot.logging.LoggingApplicationListener
          *
            setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));

            /*
            *获取main方法所在的类
            *StackTraceElement[] stackTrace = new RuntimeException().getStackTrace(); 获取 虚拟机栈中 栈桢数组
            */
            this.mainApplicationClass = deduceMainApplicationClass();
        }

    public ConfigurableApplicationContext run(String... args) {
            //计时器
            StopWatch stopWatch = new StopWatch();
            //开始计时
            stopWatch.start();
            ConfigurableApplicationContext context = null;
            FailureAnalyzers analyzers = null;

            //用来设置java.awt.headless 属性是true 还是false,是J2SE的一种模式用于在缺少显示屏、键盘    
        //或者鼠标时的系统配置
            configureHeadlessProperty();

            /*
            *获得运行侦听器  获取 spring-boot-{v}.jar/META-INF/spring.factories 文件中 org.springframework.boot.SpringApplicationRunListener 的值
            *  org.springframework.boot.context.event.EventPublishingRunListener 事件发布运行侦听器
            *在EventPublishingRunListener实例化时将 ApplicationListener的所有实现类添加 到SimpleApplicationEventMulticaster 事件中
            */
            SpringApplicationRunListeners listeners = getRunListeners(args);

            /*
            *启动SpringApplicationRunListeners侦听器
            *启动EventPublishingRunListener侦听器
            *org.springframework.boot.context.config.ConfigFileApplicationListener   onApplicationEvent没有做任何事
            *org.springframework.boot.logging.LoggingApplicationListener        onApplicationEvent加载 LoggingSystem对象
            *org.springframework.boot.context.config.DelegatingApplicationListener   onApplicationEvent没有做任何事
            *org.springframework.boot.liquibase.LiquibaseServiceLocatorApplicationListener  onApplicationEvent没有做任何事
            *调用以上监听器的onApplicationEvent 方法 
            */
            listeners.starting();

            try {

                //设置应用参数
                ApplicationArguments applicationArguments = new DefaultApplicationArguments(
                        args);

                //加载配置
                ConfigurableEnvironment environment = prepareEnvironment(listeners,
                        applicationArguments);

              //打印Banner  默认 SpringBootBanner.BANNER
                Banner printedBanner = printBanner(environment);

                //获取 上下文ApplicationContext
                context = createApplicationContext();
                //错误处理
                analyzers = new FailureAnalyzers(context);
                //准备上下文
                prepareContext(context, environment, listeners, applicationArguments,
                        printedBanner);
                //刷新上下文
                refreshContext(context);
                //完成加载
                afterRefresh(context, applicationArguments);
                //完成侦听器
                listeners.finished(context, null);
                //停止记时
                stopWatch.stop();
                //记录启动信息
                if (this.logStartupInfo) {
                    new StartupInfoLogger(this.mainApplicationClass)
                            .logStarted(getApplicationLog(), stopWatch);
                }
                return context;
            }
            catch (Throwable ex) {
                handleRunFailure(context, listeners, analyzers, ex);
                throw new IllegalStateException(ex);
            }
        }

        private ConfigurableEnvironment prepareEnvironment(
                SpringApplicationRunListeners listeners,
                ApplicationArguments applicationArguments) {

            // 创建和配置环境    StandardServletEnvironment.customizePropertySources获取配置加载顺序
            ConfigurableEnvironment environment = getOrCreateEnvironment();

            //获取启动配置
            configureEnvironment(environment, applicationArguments.getSourceArgs());

            /**
            *通过 EventPublishingRunListener监听 发送ApplicationEnvironmentPreparedEvent 事件到下面监听器
            *加载配置以下配置的值并加载配置,并调用以下监听的 onApplicationEvent 方法
            *org.springframework.boot.context.config.ConfigFileApplicationListener   加载配置  
            *   获取org.springframework.boot.env.EnvironmentPostProcessor配置的值 
            *      org.springframework.boot.cloud.CloudFoundryVcapEnvironmentPostProcessor
            *          获取 spring cloud config VCAP_APPLICATION  和  VCAP_SERVICES  的配置 
            *
        *      org.springframework.boot.env.SpringApplicationJsonEnvironmentPostProcessor
        *          获取${spring.application.json:${SPRING_APPLICATION_JSON:}}  的配置
        *
            *      org.springframework.boot.context.config.ConfigFileApplicationListener
            *               添加属性源  [servletConfigInitParams,servletContextInitParams,systemProperties,systemEnvironment,random]
            *               获取 org.springframework.boot.env.PropertySourceLoader的值
            *                   org.springframework.boot.env.PropertiesPropertySourceLoader
            *               org.springframework.boot.env.YamlPropertySourceLoader
            *               配置文件路径加载顺序  1.获取用户自定义路径地址(spring.config.location的值) 2.[file:./config/, file:./, classpath:/config/, classpath:/]
            *               文件加载顺序  1.获取用户自定义文件名(spring.config.name的值) 2.默认文件名(application)
            *               文件后缀加载顺序: [properties, xml, yml, yaml]
            *                1.file:./config/application.properties
            *                2.file:./config/application.xml
            *                3.file:./config/application.yml
            *                4.file:./config/application.yaml
            *                file:./application.properties
            *                file:./application.xml
            *                file:./application.yml
            *                file:./application.yaml
            *                file:./application.yaml
            *                classpath:/config/application.properties
            *                classpath:/config/application.xml
            *                classpath:/config/application.yml
            *                classpath:/config/application.yaml
            *                //我配置的是放在  classpath下的
            *                classpath:/application.properties
            *                classpath:/application-dev.properties 
            *           读取完配置,过滤spring bean
            *           将配置绑定到  SpringApplication    
          *org.springframework.boot.context.config.AnsiOutputApplicationListener
          *org.springframework.boot.logging.LoggingApplicationListener
          *org.springframework.boot.logging.ClasspathLoggingApplicationListener
          *org.springframework.boot.autoconfigure.BackgroundPreinitializer
          *org.springframework.boot.context.config.DelegatingApplicationListener
          *org.springframework.boot.context.FileEncodingApplicationListener
          *
          *
          *
            */
            listeners.environmentPrepared(environment);
            if (!this.webEnvironment) {
                environment = new EnvironmentConverter(getClassLoader())
                        .convertToStandardEnvironmentIfNecessary(environment);
            }
            return environment;
        }

        /**
        * 配置优先级
        * StandardServletEnvironment.customizePropertySources
        * SERVLET_CONFIG_PROPERTY_SOURCE_NAME > SERVLET_CONTEXT_PROPERTY_SOURCE_NAME > JNDI_PROPERTY_SOURCE_NAME  > 系统属性 > 环境变量
        * servlet配置属性源名称 > servlet上下文属性源名称 > jndi属性源名称 > 系统属性 > 环境变量
        **/
        @Override
        protected void customizePropertySources(MutablePropertySources propertySources) {
            propertySources.addLast(new StubPropertySource(SERVLET_CONFIG_PROPERTY_SOURCE_NAME));
            propertySources.addLast(new StubPropertySource(SERVLET_CONTEXT_PROPERTY_SOURCE_NAME));
            if (JndiLocatorDelegate.isDefaultJndiEnvironmentAvailable()) {
                propertySources.addLast(new JndiPropertySource(JNDI_PROPERTY_SOURCE_NAME));
            }
            //获取系统属性、环境变量
            super.customizePropertySources(propertySources);
        }

        protected void configureEnvironment(ConfigurableEnvironment environment,
                String[] args) {
            //加载命令行属性
            configurePropertySources(environment, args);
            //获取 spring.profiles.active  的配置
            configureProfiles(environment, args);
        }

        @Override
        public void postProcessEnvironment(ConfigurableEnvironment environment,
                SpringApplication application) {
            addPropertySources(environment, application.getResourceLoader());
            //加载配置
            configureIgnoreBeanInfo(environment);
            绑定资源
            bindToSpringApplication(environment, application);
        }

        protected ConfigurableApplicationContext createApplicationContext() {
            Class<?> contextClass = this.applicationContextClass;
            if (contextClass == null) {
                try {
                  /**
                  * web项目 初始化  org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext
                  * java项目  初始化 org.springframework.context.annotation.AnnotationConfigApplicationContext
                  **/
                    contextClass = Class.forName(this.webEnvironment
                            ? DEFAULT_WEB_CONTEXT_CLASS : DEFAULT_CONTEXT_CLASS);
                }
                catch (ClassNotFoundException ex) {
                    throw new IllegalStateException(
                            "Unable create a default ApplicationContext, "
                                    + "please specify an ApplicationContextClass",
                            ex);
                }
            }
            //初始化AnnotationConfigEmbeddedWebApplicationContext  注释Bean定义阅读器 类路径Bean定义扫描器
            return (ConfigurableApplicationContext) BeanUtils.instantiate(contextClass);
        }

        private void prepareContext(ConfigurableApplicationContext context,
                ConfigurableEnvironment environment, SpringApplicationRunListeners listeners,
                ApplicationArguments applicationArguments, Banner printedBanner) {

            /**
            * 注释Bean定义阅读器
            * 类路径Bean定义扫描器 
            **/ 
            context.setEnvironment(environment);

            //上下文后处理
            postProcessApplicationContext(context);

            //初始化上下文
            applyInitializers(context);
            //上下文准备完成
            listeners.contextPrepared(context);
            if (this.logStartupInfo) {
                logStartupInfo(context.getParent() == null);
                logStartupProfileInfo(context);
            }

            //添加特殊的bean
            context.getBeanFactory().registerSingleton("springApplicationArguments",
                    applicationArguments);
            if (printedBanner != null) {
                context.getBeanFactory().registerSingleton("springBootBanner", printedBanner);
            }

            // Load the sources
            Set<Object> sources = getSources();
            Assert.notEmpty(sources, "Sources must not be empty");

            //将bean加载到应用程序上下文中。
            load(context, sources.toArray(new Object[sources.size()]));
            //将context添加到监听中
            listeners.contextLoaded(context);
        }

        @Override
        public void refresh() throws BeansException, IllegalStateException {
            synchronized (this.startupShutdownMonitor) {

                //准备刷新上下文
                prepareRefresh();

                //告诉子类刷新内部bean工厂
                ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

                // 准备在这个上下文中使用的bean工厂
                prepareBeanFactory(beanFactory);

                try {
                    // 允许在上下文子类中对bean工厂进行后处理。
                    postProcessBeanFactory(beanFactory);

                    // 在上下文中调用在Bean中注册的工厂处理器
                    invokeBeanFactoryPostProcessors(beanFactory);

                    // Register bean processors that intercept bean creation.
                    registerBeanPostProcessors(beanFactory);

                    // Initialize message source for this context.
                    initMessageSource();

                    // Initialize event multicaster for this context.
                    initApplicationEventMulticaster();

                    // Initialize other special beans in specific context subclasses.
                    onRefresh();

                    // Check for listener beans and register them.
                    registerListeners();

                    // Instantiate all remaining (non-lazy-init) singletons.
                    finishBeanFactoryInitialization(beanFactory);

                    // Last step: publish corresponding event.
                    finishRefresh();
                }

                catch (BeansException ex) {
                    if (logger.isWarnEnabled()) {
                        logger.warn("Exception encountered during context initialization - " +
                                "cancelling refresh attempt: " + ex);
                    }

                    // Destroy already created singletons to avoid dangling resources.
                    destroyBeans();

                    // Reset 'active' flag.
                    cancelRefresh(ex);

                    // Propagate exception to caller.
                    throw ex;
                }

                finally {
                    // Reset common introspection caches in Spring's core, since we
                    // might not ever need metadata for singleton beans anymore...
                    resetCommonCaches();
                }
            }
        }

        protected void prepareRefresh() {
            this.startupDate = System.currentTimeMillis();
            this.closed.set(false);
            this.active.set(true);

            if (logger.isInfoEnabled()) {
                logger.info("Refreshing " + this);
            }

            // 在上下文环境中初始化任何占位符属性源
            initPropertySources();

            // 验证所有标记为必需的属性是可解析的
            getEnvironment().validateRequiredProperties();

            this.earlyApplicationEvents = new LinkedHashSet<ApplicationEvent>();
        }

来源:[]()

赞(0) 打赏
版权归原创作者所有,任何形式的转载请联系博主:daming_90:Java 技术驿站 » spring boot 源码

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏