[source code] Spring source code parsing IOC container_ ClassPathXmlApplicationContext start

Posted by vcodeinfotec on Thu, 03 Feb 2022 20:51:33 +0100

Spring source code collection:
Spring source code analysis (I) IOC container_ BeanDefinition and container loading

preface

Before we start to analyze the Spring source code, we need to do a few preparations.

What we want to analyze in this chapter is to use ClassPathXmlApplicationContext to read the xml configuration file and start the source code process of Spring. Before combing the process, We need to have a general understanding of the abstract structure of the Spring container (some small partners who have read the Spring source code should have such a feeling that why the Spring source code jumps around, a method often needs to be overloaded and rewritten many times, and finally it takes a long time to get to the place where it really works. Personally, I think this is the essence of the Spring source code, which is "Object-Oriented" And "design pattern". To feel the beauty of this design, the abstract structure of Spring container is a good starting point).

BeanFactory abstract structure

Here is the abstract structure diagram of BeanFactory.

The following lists the more important interfaces I think. It is suggested that readers can open the source code to have a look at these interfaces.

BeanFactory interface

The root interface of Bean factory provides the basic method to obtain a single Bean instance (according to type, name...)

Design patterns used:

  • Simple factory mode
  • Singleton mode
  • Prototype pattern (prototype), when generating multiple objects, deep copy is carried out through serialization.

Methods in BeanFactory:

interface BeanFactory {
    String FACTORY_BEAN_PREFIX = "&";

    Object getBean(String name) throws BeansException;

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

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

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

    <T> T getBean(Class<T> requiredType, Object... args) throws BeansException;

    <T> ObjectProvider<T> getBeanProvider(Class<T> requiredType);

    <T> ObjectProvider<T> getBeanProvider(ResolvableType requiredType);

    boolean containsBean(String name);

    boolean isSingleton(String name) throws NoSuchBeanDefinitionException;

    boolean isPrototype(String name) throws NoSuchBeanDefinitionException;

    boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException;

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

    @Nullable
    Class<?> getType(String name) throws NoSuchBeanDefinitionException;

    @Nullable
    Class<?> getType(String name, boolean allowFactoryBeanInit) throws NoSuchBeanDefinitionException;

    String[] getAliases(String name);
}

ListableBeanFactory interface

Inheriting the BeanFactory interface, it provides a method to obtain the bean collection (multiple beans, the previous BeanFactory only supports obtaining a single bean) according to the type, name, annotation, etc.

For example:

interface ListableBeanFactory {

    boolean containsBeanDefinition(String beanName);

    int getBeanDefinitionCount();

    String[] getBeanDefinitionNames();

    String[] getBeanNamesForType(ResolvableType type);

    String[] getBeanNamesForType(ResolvableType type, boolean includeNonSingletons, boolean allowEagerInit);

    String[] getBeanNamesForType(@Nullable Class<?> type);

    String[] getBeanNamesForType(@Nullable Class<?> type, boolean includeNonSingletons, boolean allowEagerInit);

    <T> Map<String, T> getBeansOfType(@Nullable Class<T> type) throws BeansException;

    <T> Map<String, T> getBeansOfType(@Nullable Class<T> type, boolean includeNonSingletons, boolean allowEagerInit)
        throws BeansException;

    String[] getBeanNamesForAnnotation(Class<? extends Annotation> annotationType);

    Map<String, Object> getBeansWithAnnotation(Class<? extends Annotation> annotationType) throws BeansException;

    @Nullable
    <A extends Annotation> A findAnnotationOnBean(String beanName, Class<A> annotationType)
        throws NoSuchBeanDefinitionException;
}

Hierarchalbeanfactory interface

Inherits the BeanFactory interface, allowing the factory of the parent to be set in a configurable manner

interface HierarchicalBeanFactory {
    /**
     * Returns the parent BeanFactory without returning null
     */
    @Nullable
    BeanFactory getParentBeanFactory();

    /**
     * Judge whether the current BeanFactory (not in the parent BeanFactory) contains a Bean with the name of name
     */
    boolean containsLocalBean(String name);
} 

AutowireCapableBeanFactory interface

Inherit the BeanFactory interface. We are very familiar with autowire. This interface is mainly used to automatically assemble beans.

There are some important methods (familiar, if you have seen the source code of bean creation process):

interface AutowireCapableBeanFactory {
    int AUTOWIRE_NO = 0;

    int AUTOWIRE_BY_NAME = 1;

    int AUTOWIRE_BY_TYPE = 2;

    int AUTOWIRE_CONSTRUCTOR = 3;

    @Deprecated
    int AUTOWIRE_AUTODETECT = 4;

    <T> T createBean(Class<T> beanClass) throws BeansException;

    Object createBean(Class<?> beanClass, int autowireMode, boolean dependencyCheck) throws BeansException;

    void applyBeanPropertyValues(Object existingBean, String beanName) throws BeansException;

    Object initializeBean(Object existingBean, String beanName) throws BeansException;

    Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
                throws BeansException;

    Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
                throws BeansException;

    void destroyBean(Object existingBean);

    @Nullable
        Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName) throws BeansException;

    @Nullable
        Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName,
                @Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException;
}

ConfigurableBeanFactory interface

Inherit the hierarchical beanfactory and SingletonBeanRegistry. Its method is mainly to configure the Bean factory, which is mainly used inside the framework.

SingletonBeanRegistry provides some operations on singleton objects.

ConfigurableListableBeanFactory interface

Its special feature is that it inherits three interfaces: ConfigurableBeanFactory, ListableBeanFactory and AutowireCapableBeanFactory (that is, it will have the functions of these three interfaces. You will see later that DefaultListableBeanFactory inherits this interface).

Topics: Java Spring source code