SpringIoc源码(五)- ApplicationContext(一)- 结构梳理

目录

一、ApplicationContext

1、接口方法

2、实现接口

1)、EnvironmentCapable

2)、ListableBeanFactory

3)、HierarchicalBeanFactory

4)、MessageSource

5)、ApplicationEventPublisher

6)、ResourcePatternResolver

二、ApplicationContext主要实现类

1、ConfigurableApplicationContext

2、AbstractApplicationContext

3、AbstractRefreshableApplicationContext

4、GenericApplicationContext


    之前已经分析过Spring中不会直接使用BeanFactory(或者DefaultListableBeanFactory),而是使用ApplicationContext作为扩展容器。主要的实现是AbstractApplicationContext中的模板方法refresh方法,而不同的ApplicationContext子类实现不同的模板方法的步骤。

一、ApplicationContext

    先看看接口定义:

public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, 
    HierarchicalBeanFactory, MessageSource, ApplicationEventPublisher, 
    ResourcePatternResolver {

    @Nullable
    String getId();

    String getApplicationName();

    String getDisplayName();

    long getStartupDate();

    @Nullable
    ApplicationContext getParent();

    AutowireCapableBeanFactory getAutowireCapableBeanFactory() 
        throws IllegalStateException;
}

1、接口方法

    定义了每一个ApplicationContext都有一个id,一个名称,显示名称,启动时间,父容器,已经BeanFactory(也就是ApplicationContext与BeanFactory的关系)。

2、实现接口

1)、EnvironmentCapable

Environment getEnvironment();

    只有一个接口,定义了ApplicationContext启动时的环境。

2)、ListableBeanFactory

    之前分析过,定义了BeanDefinition的相关接口。BeanFactory的实现类是DefaultListableBeanFactory,这里真正调用的也是里面的实现方法。

3)、HierarchicalBeanFactory

    之前分析过,定义的是父子类的接口。BeanFactory的实现类是AbstractBeanFactory,同样是调用该方法实现。

4)、MessageSource

    定义国际化相关的东西,根据不同的Locale获取不同的信息,回头可以专门分析该部分。

5)、ApplicationEventPublisher

    观察者模式的事件发生机制,详细可以参见:Spring源码-事件监听机制(实现EventListener接口)

6)、ResourcePatternResolver

public interface ResourcePatternResolver extends ResourceLoader {

	String CLASSPATH_ALL_URL_PREFIX = "classpath*:";

	Resource[] getResources(String locationPattern) throws IOException;
}

    再看看ResourceLoader

public interface ResourceLoader {

    /** Pseudo URL prefix for loading from the class path: "classpath:". */
    String CLASSPATH_URL_PREFIX = ResourceUtils.CLASSPATH_URL_PREFIX;

    Resource getResource(String location);

    @Nullable
    ClassLoader getClassLoader();
}

    比较清楚了,加载Spring Resource。只是先说明一下,CLASSPATH_URL_PREFIX 为classpath:.,加载的是classpath下所有的资源,而CLASSPATH_ALL_URL_PREFIX 为classpath*:加载包含所有jar包下的resources下(classpath)的资源

 

二、ApplicationContext主要实现类

    之前用的比价多的是ClassPathXmlApplicationContextAnnotationConfigWebApplicationContext;SpringBoot之后根据初始化时不同的webApplicationType类型,初始化为AnnotationConfigApplicationContextAnnotationConfigServletWebServerApplicationContextAnnotationConfigReactiveWebServerApplicationContext类型。

   实现类非常的多,但是都会发现主要是AbstractApplicationContext的子类,并且模板方法refresh在该类中定义,所以需要分析ConfigurableApplicationContext接口和AbstractApplicationContext抽象类,之前的版本还需要看看AbstractRefreshableApplicationContext,spring Boot相关版本还需要看看GenericApplicationContext

1、ConfigurableApplicationContext

public interface ConfigurableApplicationContext extends ApplicationContext, Lifecycle, Closeable {

    String CONFIG_LOCATION_DELIMITERS = ",; \t\n";

    String CONVERSION_SERVICE_BEAN_NAME = "conversionService";

    String LOAD_TIME_WEAVER_BEAN_NAME = "loadTimeWeaver";

    String ENVIRONMENT_BEAN_NAME = "environment";

    String SYSTEM_PROPERTIES_BEAN_NAME = "systemProperties";

    String SYSTEM_ENVIRONMENT_BEAN_NAME = "systemEnvironment";

    String SHUTDOWN_HOOK_THREAD_NAME = "SpringContextShutdownHook";

    void setId(String id);

    void setParent(@Nullable ApplicationContext parent);

    void setEnvironment(ConfigurableEnvironment environment);

    @Override
    ConfigurableEnvironment getEnvironment();

    void addBeanFactoryPostProcessor(BeanFactoryPostProcessor postProcessor);

    void addApplicationListener(ApplicationListener<?> listener);

    void addProtocolResolver(ProtocolResolver resolver);

    void refresh() throws BeansException, IllegalStateException;

    void registerShutdownHook();

    @Override
    void close();

    boolean isActive();

    /**
     * @see #isActive()
     * @see #refresh()
     * @see #close()
     * @see #addBeanFactoryPostProcessor
     */
    ConfigurableListableBeanFactory getBeanFactory() throws IllegalStateException;
}

1)、Lifecycle

    实现了Lifecycle接口,也就是Spring容器的生命周期,比较简单的生命周期(启动,停止、是否在运行中)看一下接口

public interface Lifecycle {
    void start();

    void stop();

    boolean isRunning();
}

    只要是看看其实现接口(又增加了两个接口,正在调用refresh方法相关)和类:

public interface LifecycleProcessor extends Lifecycle {
    void onRefresh();
    
    void onClose();
}
public class DefaultLifecycleProcessor implements LifecycleProcessor, BeanFactoryAware {

    private final Log logger = LogFactory.getLog(getClass());

    private volatile long timeoutPerShutdownPhase = 30000;

    private volatile boolean running;

    @Nullable
    private volatile ConfigurableListableBeanFactory;
   
    // 省略其他的实现,在其他专门进行分析
}

 

2、AbstractApplicationContext

public abstract class AbstractApplicationContext extends DefaultResourceLoader
        implements ConfigurableApplicationContext {

    /**
     * Name of the MessageSource bean in the factory.
     * If none is supplied, message resolution is delegated to the parent.
     * @see MessageSource
     */
    public static final String MESSAGE_SOURCE_BEAN_NAME = "messageSource";

    /**
     * Name of the LifecycleProcessor bean in the factory.
     * If none is supplied, a DefaultLifecycleProcessor is used.
     * @see org.springframework.context.LifecycleProcessor
     * @see org.springframework.context.support.DefaultLifecycleProcessor
     */
    public static final String LIFECYCLE_PROCESSOR_BEAN_NAME = "lifecycleProcessor";

    /**
     * Name of the ApplicationEventMulticaster bean in the factory.
     * If none is supplied, a default SimpleApplicationEventMulticaster is used.
     * @see org.springframework.context.event.ApplicationEventMulticaster
     * @see org.springframework.context.event.SimpleApplicationEventMulticaster
     */
    public static final String APPLICATION_EVENT_MULTICASTER_BEAN_NAME = "applicationEventMulticaster";


    static {
        // Eagerly load the ContextClosedEvent class to avoid weird classloader issues
        // on application shutdown in WebLogic 8.1. (Reported by Dustin Woods.)
        ContextClosedEvent.class.getName();
    }


    /** Logger used by this class. Available to subclasses. */
    protected final Log logger = LogFactory.getLog(getClass());

    /** Unique id for this context, if any. */
    private String id = ObjectUtils.identityToString(this);

    /** Display name. */
    private String displayName = ObjectUtils.identityToString(this);

    /** Parent context. */
    @Nullable
    private ApplicationContext parent;

    /** Environment used by this context. */
    @Nullable
    private ConfigurableEnvironment environment;

    /** BeanFactoryPostProcessors to apply on refresh. */
    private final List<BeanFactoryPostProcessor> beanFactoryPostProcessors = new ArrayList<>();

    /** System time in milliseconds when this context started. */
    private long startupDate;

    /** Flag that indicates whether this context is currently active. */
    private final AtomicBoolean active = new AtomicBoolean();

    /** Flag that indicates whether this context has been closed already. */
    private final AtomicBoolean closed = new AtomicBoolean();

    /** Synchronization monitor for the "refresh" and "destroy". */
    private final Object startupShutdownMonitor = new Object();

    /** Reference to the JVM shutdown hook, if registered. */
    @Nullable
    private Thread shutdownHook;

    /** ResourcePatternResolver used by this context. */
    private ResourcePatternResolver resourcePatternResolver;

    /** LifecycleProcessor 管理bean的生命周期的容器 */
    @Nullable
    private LifecycleProcessor lifecycleProcessor;

    /** 委派我们自定义实现的 国际化MessageSource */
    @Nullable
    private MessageSource messageSource;

    /** 事件发送器,默认初始化为 SimpleApplicationEventMulticaster 类型 */
    @Nullable
    private ApplicationEventMulticaster applicationEventMulticaster;

    /** 静态指定的监听器 */
    private final Set<ApplicationListener<?>> applicationListeners = new LinkedHashSet<>();

    /** Local listeners registered before refresh.(refresh之前就已经注册的) */
    @Nullable
    private Set<ApplicationListener<?>> earlyApplicationListeners;

    // 早期的事件发生,与生命周期相关的;不是我们自定义的事件
    @Nullable
    private Set<ApplicationEvent> earlyApplicationEvents;
}

   AbstractApplicationContext实现了接口ConfigurableApplicationContext的所有定义的接口方法,并且集成自DefaultResourceLoader上面分析过其父类ResourceLoader,当前是对上面的实现。

public class DefaultResourceLoader implements ResourceLoader {
    @Nullable
    private ClassLoader classLoader;
    // 定义的长度为4,所以基本上后面会往里加入的数量基本定了
    private final Set<ProtocolResolver> protocolResolvers = new LinkedHashSet<>(4);

    private final Map<Class<?>, Map<Resource, ?>> resourceCaches = new ConcurrentHashMap<>(4);

    // 无参数构造,直接调用  Thread.currentThread().getContextClassLoader()
    public DefaultResourceLoader() {
        this.classLoader = ClassUtils.getDefaultClassLoader();
    }
}

 

3、AbstractRefreshableApplicationContext

public abstract class AbstractRefreshableApplicationContext extends AbstractApplicationContext {
    @Nullable
    private Boolean allowBeanDefinitionOverriding;

    @Nullable
    private Boolean allowCircularReferences;

    /**
     * Bean factory for this context.
     */
    @Nullable
    private DefaultListableBeanFactory beanFactory;

    /**
     * Synchronization monitor for the internal BeanFactory.
     */
    private final Object beanFactoryMonitor = new Object();
}

定义了是否覆盖BeanDefinition,以及是否支持循环依赖。

 

4、GenericApplicationContext

public class GenericApplicationContext extends AbstractApplicationContext implements BeanDefinitionRegistry {

    private final DefaultListableBeanFactory beanFactory;

    @Nullable
    private ResourceLoader resourceLoader;

    private boolean customClassLoader = false;

    private final AtomicBoolean refreshed = new AtomicBoolean();

    public GenericApplicationContext() {
        this.beanFactory = new DefaultListableBeanFactory();
    }
}

    实现了BeanDefinitionRegistry接口,则子类又拥有了BeanDefinition相关的功能。

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值