Spring(二~end)观其大略

文章目录

  • 前言
  • Spring(二)
    • Environment
      • PropertySourcesPlaceholderConfigurer & PlaceholderConfigurerSupport
      • Profile
      • ConfigurableEnvironment
    • BeanFactoryPostProcessor
  • Spring(三)
    • 前情回顾
    • ApplicationContext
      • AutowireCapableBeanFactory
  • 小插曲,讲到SpringCloud的注册中心
  • SPI
  • to be continued...


前言

Spring源码其实很有用,很多核心代码都是零几年写的,但是很经典,到今天也不落后
将来如果有机会写底层框架,Spring的接口隔离等架构思想,十分值得学习
但是最近在找工作,没时间研究太深入啦,先观其大略,后续再看书和源码了解细节了…
不能只看诗和远方,还要兼顾脚下的路呀…


Spring(二)

Environment

先来个小测试

public class EnvironmentTest {
    @Test
    public void systemPropertyTest() {
        /*
            环境变量
            常用的有user.dir,当前工程的目录
            虚拟机的VM参数 -Dxx=1 也会在这里面  (-D=:set a system property  设置系统属性。)
         */
        Properties properties = System.getProperties();
        Set<String> nameSet = properties.stringPropertyNames();
        for (String name : nameSet) {
            System.out.println(String.format("%s----------->%s", name, properties.getProperty(name)));
        }
    }
}

org.springframework.core.env.Environment

PropertySourcesPlaceholderConfigurer & PlaceholderConfigurerSupport

org.springframework.context.support.PropertySourcesPlaceholderConfigurer

使用Spring时,如果我们需要读取properties配置,
需要在xml中配置
然后使用SpEL ${xxx.ooo}

PropertySourcesPlaceholderConfigurer.processProperties() ->
PlaceholderConfigurerSupport.doProcessProperties()
接口隔离(i have a pen, i have an apple, ahhhh, applepen!)
函数式编程
策略模式
访问者模式

Profile

Spring(二~end)观其大略_第1张图片

SPI, dubbo SPI经典用例

ConfigurableEnvironment

When an {@link Environment} is being used by an {@code ApplicationContext}, it is
important that any such {@code PropertySource} manipulations be performed
before the context’s {@link
org.springframework.context.support.AbstractApplicationContext#refresh() refresh()}
method is called. This ensures that all property sources are available during the
container bootstrap process, including use by {@linkplain
org.springframework.context.support.PropertySourcesPlaceholderConfigurer property
placeholder configurers}.

重点方法:

/**                                                                                   
 * Append the given parent environment's active profiles, default profiles and        
 * property sources to this (child) environment's respective collections of each.     
 * 

For any identically-named {@code PropertySource} instance existing in both * parent and child, the child instance is to be preserved and the parent instance * discarded. This has the effect of allowing overriding of property sources by the * child as well as avoiding redundant searches through common property source types, * e.g. system environment and system properties. *

Active and default profile names are also filtered for duplicates, to avoid * confusion and redundant storage. *

The parent environment remains unmodified in any case. Note that any changes to * the parent environment occurring after the call to {@code merge} will not be * reflected in the child. Therefore, care should be taken to configure parent * property sources and profile information prior to calling {@code merge}. * @param parent the environment to merge with * @since 3.1.2 * @see org.springframework.context.support.AbstractApplicationContext#setParent */ void merge(ConfigurableEnvironment parent);

BeanFactoryPostProcessor

Spring(二~end)观其大略_第2张图片

Spring(二~end)观其大略_第3张图片


Spring(三)

前情回顾

  1. BeanPostProcessor
  2. BeanFactoryPostProcessor
  3. FactoryBean
  4. BeanFactory
  5. Environment
  6. Event事件机制(?? 我咋不记得)
  7. XXXAware接口注入spring相关的东西
  8. Feign的源码
    回头看书再细看了,现在就是观其大略

接口隔离,每个接口拆的够细,
然后通过一个接口把这些细的接口组合(extends) (LOL的装备合成)

总接口: BeanFactory bean的工厂,生产bean,提供获取bean的方法
子接口: 1. 父子关系 2. List的功能,遍历
子接口: 需要1和2的功能, xxx extends 1,2{},例如org.springframework.context.ApplicationContext, spring的总接口

ApplicationContext

/**
 * Central interface to provide configuration for an application.
 * This is read-only while the application is running, but may be
 * reloaded if the implementation supports this.
 *
 * 

An ApplicationContext provides: *

    *
  • Bean factory methods for accessing application components. * Inherited from {@link org.springframework.beans.factory.ListableBeanFactory}. *
  • The ability to load file resources in a generic fashion. * Inherited from the {@link org.springframework.core.io.ResourceLoader} interface. *
  • The ability to publish events to registered listeners. * Inherited from the {@link ApplicationEventPublisher} interface. *
  • The ability to resolve messages, supporting internationalization. * Inherited from the {@link MessageSource} interface. *
  • Inheritance from a parent context. Definitions in a descendant context * will always take priority. This means, for example, that a single parent * context can be used by an entire web application, while each servlet has * its own child context that is independent of that of any other servlet. *
* *

In addition to standard {@link org.springframework.beans.factory.BeanFactory} * lifecycle capabilities, ApplicationContext implementations detect and invoke * {@link ApplicationContextAware} beans as well as {@link ResourceLoaderAware}, * {@link ApplicationEventPublisherAware} and {@link MessageSourceAware} beans. * * @author Rod Johnson * @author Juergen Hoeller * @see ConfigurableApplicationContext * @see org.springframework.beans.factory.BeanFactory * @see org.springframework.core.io.ResourceLoader */

重点方法:

/**
	 * Expose AutowireCapableBeanFactory functionality for this context.
	 * 

This is not typically used by application code, except for the purpose of * initializing bean instances that live outside of the application context, * applying the Spring bean lifecycle (fully or partly) to them. *

Alternatively, the internal BeanFactory exposed by the * {@link ConfigurableApplicationContext} interface offers access to the * {@link AutowireCapableBeanFactory} interface too. The present method mainly * serves as a convenient, specific facility on the ApplicationContext interface. *

NOTE: As of 4.2, this method will consistently throw IllegalStateException * after the application context has been closed. In current Spring Framework * versions, only refreshable application contexts behave that way; as of 4.2, * all application context implementations will be required to comply. * @return the AutowireCapableBeanFactory for this context * @throws IllegalStateException if the context does not support the * {@link AutowireCapableBeanFactory} interface, or does not hold an * autowire-capable bean factory yet (e.g. if {@code refresh()} has * never been called), or if the context has been closed already * @see ConfigurableApplicationContext#refresh() * @see ConfigurableApplicationContext#getBeanFactory() */ AutowireCapableBeanFactory getAutowireCapableBeanFactory() throws IllegalStateException;

AutowireCapableBeanFactory

org.springframework.beans.factory.config.AutowireCapableBeanFactory

/**
 * Extension of the {@link org.springframework.beans.factory.BeanFactory}
 * interface to be implemented by bean factories that are capable of
 * autowiring, provided that they want to expose this functionality for
 * existing bean instances.
 *
 * 

This subinterface of BeanFactory is not meant to be used in normal * application code: stick to {@link org.springframework.beans.factory.BeanFactory} * or {@link org.springframework.beans.factory.ListableBeanFactory} for * typical use cases. * *

Integration code for other frameworks can leverage this interface to * wire and populate existing bean instances that Spring does not control * the lifecycle of. This is particularly useful for WebWork Actions and * Tapestry Page objects, for example. * *

Note that this interface is not implemented by * {@link org.springframework.context.ApplicationContext} facades, * as it is hardly ever used by application code. That said, it is available * from an application context too, accessible through ApplicationContext's * {@link org.springframework.context.ApplicationContext#getAutowireCapableBeanFactory()} * method. * *

You may also implement the {@link org.springframework.beans.factory.BeanFactoryAware} * interface, which exposes the internal BeanFactory even when running in an * ApplicationContext, to get access to an AutowireCapableBeanFactory: * simply cast the passed-in BeanFactory to AutowireCapableBeanFactory. * * @author Juergen Hoeller * @since 04.12.2003 * @see org.springframework.beans.factory.BeanFactoryAware * @see org.springframework.beans.factory.config.ConfigurableListableBeanFactory * @see org.springframework.context.ApplicationContext#getAutowireCapableBeanFactory() */


小插曲,讲到SpringCloud的注册中心

现在大家都喜欢用阿里开源的组件,比如nacos
但是阿里开源的东西,几乎没有注释,一个没有注释的开源软件,可能需要特别大的经历去读懂它,这样有了问题才好排查
国外的开源软件,比如Spring家族,比如Eureka,注释写的特别多,很好理解

eureka没有闭源! 他只是声明2.0版本不维护啦,出现问题不负责;但是1.0还是正常维护的,也很好用!
eureka的缺点,可能是他会一个个遍历服务提供方,如果注册的provider超过2000个的话,会影响其心跳延时(大概是这样,回头SpringCloud系列再深入研究)
但是一般的企业,哪有2000台实例的需求… 所以,eureka很好用,AP思想很奈斯!


SPI

service provider interface
Spring(二~end)观其大略_第4张图片
读取一个配置文件(META-INFO/xxx.xml),然后加载那些实现类;
我们可以用properties配置文件模拟一下
Spring(二~end)观其大略_第5张图片


to be continued…

你可能感兴趣的:(Spring原理)