principio de la primavera para resolver -BeanFactory --- proceso de carga de contenedores para resolver

cargas de contenedores

presentación de clase DefaultListableBeanFactory

  clase de implementación por defecto es DefaultListableBeanFactory BeanFactory clase, lo que indirectamente interfaz BeanFactory, la interfaz BeanDefinitionRegistry, mientras que la interfaz depende de BeanDefinition. clase figura que sigue:

DefaultListableBeanFactory 类 图
Como se muestra anteriormente, la clase DefaultListableBeanFactory indirectamente interfaz BeanDefinitionRegistry BeanFactory y una interfaz, donde la interfaz de BeanDefinitionRegistry BeanDefinition también dependientes de la interfaz. Siguiente Foto torno a explicar el contenedor BeanFactory proceso de inicio.

Presentación de la interfaz BeanFactory

  interfaz BeanFactory se utiliza principalmente para crear la interfaz de fábrica de beans, que define el método de interfaz en las siguientes secciones: la adquisición de instancia del bean, se determina si el recipiente contiene un grano, determina si la instancia es de modo único o un modelo prototipo, el tipo de juego , tipo de instancia, obtener alias. interfaces específicas como sigue:

public interface BeanFactory {
    String FACTORY_BEAN_PREFIX = "&";
	//获取bean实例
    Object getBean(String var1) throws BeansException;

    <T> T getBean(String var1, Class<T> var2) throws BeansException;

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

    Object getBean(String var1, Object... var2) throws BeansException;

    <T> T getBean(Class<T> var1, Object... var2) throws BeansException;
	//是否包含指定实例
    boolean containsBean(String var1);
	//是否为单例模式
    boolean isSingleton(String var1) throws NoSuchBeanDefinitionException;
	//是否为原型模式
    boolean isPrototype(String var1) throws NoSuchBeanDefinitionException;
	//类型匹配
    boolean isTypeMatch(String var1, ResolvableType var2) throws NoSuchBeanDefinitionException;

    boolean isTypeMatch(String var1, Class<?> var2) throws NoSuchBeanDefinitionException;
	//返回实例类型
    Class<?> getType(String var1) throws NoSuchBeanDefinitionException;
	//返回别名
    String[] getAliases(String var1);
}

Descripción de la interfaz BeanDefinition

  El nombre de la interfaz se puede adivinar, la interfaz está asociado con la definición de frijol. En efecto, la interfaz se utiliza para definir la información de gestión para cada bean. Cuando se inicia el contenedor, se darán resorte para el archivo de configuración utilizando la información o anotaciones (por ejemplo @Componet @Service @Controller etc.) definida paquete bean BeanDefinition en objetos individuales, cada uno correspondiente a un objeto BeanDefinition bean en el objeto durante la instanciación, utilizando el correspondiente bean BeanDenifition reflejada por el objeto de generar una instancia de objeto. BeanDefinition método de interfaz para la gestión de información de atributos del grano
, como el nombre de los padres de clase, nombre de la clase, el alcance y la carga tan perezoso. El código siguiente es BeanDefinition Interfaz de origen:

public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement {
    String SCOPE_SINGLETON = "singleton";
    String SCOPE_PROTOTYPE = "prototype";
    int ROLE_APPLICATION = 0;
    int ROLE_SUPPORT = 1;
    int ROLE_INFRASTRUCTURE = 2;
	//父类名
    void setParentName(String var1);

    String getParentName();
	//类名
    void setBeanClassName(String var1);

    String getBeanClassName();
	//作用域
    void setScope(String var1);

    String getScope();
	//懒加载
    void setLazyInit(boolean var1);

    boolean isLazyInit();
	//依赖
    void setDependsOn(String... var1);

    String[] getDependsOn();

    void setAutowireCandidate(boolean var1);

    boolean isAutowireCandidate();

    void setPrimary(boolean var1);

    boolean isPrimary();
	//工厂类名
    void setFactoryBeanName(String var1);

    String getFactoryBeanName();
	//工厂方法名
    void setFactoryMethodName(String var1);

    String getFactoryMethodName();

    ConstructorArgumentValues getConstructorArgumentValues();

    MutablePropertyValues getPropertyValues();

    boolean isSingleton();

    boolean isPrototype();

    boolean isAbstract();

    int getRole();

    String getDescription();

    String getResourceDescription();

    BeanDefinition getOriginatingBeanDefinition();
}

  Se puede encontrar, las propiedades corresponden BeanDefinition información de atributos de interfaz con la etiqueta archivo de configuración XML, es decir un BeanDefinition corresponde a una información de la etiqueta. Cuando el recipiente se inicia, la información de etiqueta resolverá el objeto de clase de interfaz BeanDefinition primero encapsulado.
  BeanDefinition indirectamente tres categorías, a saber RootBeanFactory, ChildBeanFactory y GenericBeanDefinition. En donde RootBeanFactory se utiliza para empaquetar la información de definición de clase padre (no se muestra heredados clases otras clases), ChildBeanDefinition subclase definición se utiliza para la información del paquete.

Descripción de la interfaz BeanDefinitionRegistry

  También, de acuerdo con el nombre de la interfaz puede verse, con el registro de este objeto BeanDefinition interfaz en una porción de, el grano se iniciará definición información de la etiqueta recipiente fase BeanDefinition analiza en objetos envasados, para casos posteriores de uso, estos De quién es el BeanDefinition mantenimiento guardarlo. Sí, BeanDefinitionRegistry se utiliza para guardar objetos de mantenimiento BeanDefinition.

public interface BeanDefinitionRegistry extends AliasRegistry {
	//注册BeanDefinition
    void registerBeanDefinition(String var1, BeanDefinition var2) throws BeanDefinitionStoreException;
	//移除BeanDefinition
    void removeBeanDefinition(String var1) throws NoSuchBeanDefinitionException;
	//获取BeanDefinition
    BeanDefinition getBeanDefinition(String var1) throws NoSuchBeanDefinitionException;
	//是否包含指定BeanDefinition对象
    boolean containsBeanDefinition(String var1);
	//获取所有BeanDefinition对象名称
    String[] getBeanDefinitionNames();
	//获取BeanDefinition对象数量
    int getBeanDefinitionCount();
	//BeanDefinition是否在使用
    boolean isBeanNameInUse(String var1);
}

Cómo analizar el archivo XML

  Aquí, yo creo que hay que BeanDefinition BeanFactory dirección de la fábrica y una cierta comprensión de la misma, pero nos preguntamos si, la primavera es la forma de x 在这里插入代码片caracteres de conversión define ml de BeanDefinition objetos en él, entonces el siguiente voy a seguir para llevar a todos discusión (de hecho, se ve aquí, puede volver ahora, claramente no ha visto un análisis en profundidad del código fuente, pero desde un nivel de principio del análisis, cuando nos puede dominar los principios básicos y luego mirar el código fuente debe ser simple)
  que se resolverán antes de la primera una pieza de código, como sigue:

public class ClassA {
    
    public void say(){
        System.out.println("我是ClassA对象,我在说话");
    }
}

  Este es un tipo común de clase

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="
       http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context-3.0.xsd">
    
    <bean id="classA" class="springBeanTest.ClassA"/>
</beans>

  Este es el archivo de configuración de la primavera spring.xml

public class LifeCycleTest {
    @Test
    public void test1(){
        //创建bean的工厂类
        DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
        //创建一个xml文件的reader类,将bean工厂传入reader中
        XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader((BeanDefinitionRegistry) beanFactory);
        //加载xml未配置文件,并将配置文件解析成BeanDefinition对象保存在工厂类中
        reader.loadBeanDefinitions("classpath:/spring.xml");
        //从工厂类中获取classA类的beanDefinition对象
        BeanDefinition beanDefinition = beanFactory.getBeanDefinition("classA");
        //打印
        System.out.println(beanDefinition.getBeanClassName());
        System.out.println(beanDefinition.isSingleton());
    }
}

  resultados FIG son los siguientes, se puede ver, el resorte será de hecho analizado archivo de configuración XML en un beanDefinition objeto
Los resultados operativos

  1. BaenFactory para crear parámetro de objeto constructor BeanDefinitionReader:

  AbstractBeanDefinitionReader partes abstractas constructor de la clase:

public XmlBeanDefinitionReader(BeanDefinitionRegistry registry) {
		//将beanFactory传给父类构造器
        super(registry);
       
    }

  Pieza padre código de constructor de la clase es la siguiente:

protected AbstractBeanDefinitionReader(BeanDefinitionRegistry registry) {
        Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
        //父类构造器将beanFactory复制给自己的依赖对象,这样便为BeanDefinitionReader对象设置好了BeanFactory实例,用于注册beanDefinition。
        this.registry = registry;
        //初始化ResourceLoader
        if (this.registry instanceof ResourceLoader) {
            this.resourceLoader = (ResourceLoader)this.registry;
        } else {
        	//创建resourceLoader对象,类型为DefaultResourceLoader
            this.resourceLoader = new PathMatchingResourcePatternResolver();
        }
    }
  1. Llamar al método AbstrcatBeanDefinitionReader:
public int loadBeanDefinitions(String location, Set<Resource> actualResources) throws BeanDefinitionStoreException {
		//获取上一步初始化时创建的resourceLoader对象
        ResourceLoader resourceLoader = this.getResourceLoader();
        if (resourceLoader == null) {
            //异常处理代码
        } else {
            int loadCount;
            //接下来的代码是根据loaction的格式创建不同的Resource对象。
            if (!(resourceLoader instanceof ResourcePatternResolver)) {
    		//省略部分代码
            } else {
                try {
                //根绝loaction格式,创建像一面的Resource对象
                    Resource[] resources = ((ResourcePatternResolver)resourceLoader).getResources(location);
               //从resource对象中加载beanDefinition对象
                    loadCount = this.loadBeanDefinitions(resources);
                   	//省略部分代码
                    return loadCount;
                } catch (IOException var10) {
                    //省略部分代码
                }
            }
        }
    }

  escudos de interfaz de recursos las diferencias en el acceso a diferentes recursos, proporcionan un acceso unificado de recursos para la interfaz superior.

  1. Después de obtener los objetos de recursos, primavera usará el objeto de crear una objetos EncodedResource, principalmente para facilitar el proceso de codificación

  El código siguiente es un método de clase XmlBeanDefinitionReader

public int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException {
        return this.loadBeanDefinitions(new EncodedResource(resource));
    }
  1. Después de obtener objeto EncodedResource, llamar al siguiente archivo de análisis XML métodos, y empaquetado en beanDefinition objetos almacenados en la beanFactroy.
public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException {
       //省去异常处理
        Set<EncodedResource> currentResources = (Set)this.resourcesCurrentlyBeingLoaded.get();
        if (currentResources == null) {
            currentResources = new HashSet(4);
            this.resourcesCurrentlyBeingLoaded.set(currentResources);
        }

        if (!((Set)currentResources).add(encodedResource)) {
            throw new BeanDefinitionStoreException("Detected cyclic loading of " + encodedResource + " - check your import definitions!");
        } else {
            int var5;
            try {
                InputStream inputStream = encodedResource.getResource().getInputStream();

                try {
                    InputSource inputSource = new InputSource(inputStream);
                    if (encodedResource.getEncoding() != null) {
                        inputSource.setEncoding(encodedResource.getEncoding());
                    }
					//此处开始进行解析加载
                    var5 = this.doLoadBeanDefinitions(inputSource, encodedResource.getResource());
                } finally {
                    inputStream.close();
                }
            } catch (IOException var15) {
               //异常处理
            } finally {
                ((Set)currentResources).remove(encodedResource);
                if (((Set)currentResources).isEmpty()) {
                    this.resourcesCurrentlyBeingLoaded.remove();
                }

            }

            return var5;
        }
    }
  1. fuente Método doLoadBeanDefinitions como sigue:
protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource) throws BeanDefinitionStoreException {
        try {
        	//这里将从resource中加载资源,并封装成Document对象
            Document doc = this.doLoadDocument(inputSource, resource);
            //解析doucument对象,生成beanDefinition对象并注册到BeanDefinitionRegistry中(BeanFactory接口的默认实现类同时也实现了BeanDefinitionRegistry接口,因此可以从BeanDefinitionRegistry获取所有的beanDefinition对象)
            return this.registerBeanDefinitions(doc, resource);
        } catch (BeanDefinitionStoreException var4) {
            //连续一串的异常处理
        } 
    }
  1. métodos registerBeanDefinitions, efecto del proceso es el objeto de uso DocumentReader para leer el contenido del objeto de documento, y genera beanDefinition de análisis de objetos y para registrarse BeanDefinitionRegistry marcha. proceso de análisis detallado no continúa a entrar aquí.
public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
		//创建documentReader对象
        BeanDefinitionDocumentReader documentReader = this.createBeanDefinitionDocumentReader();
        int countBefore = this.getRegistry().getBeanDefinitionCount();
       	//解析document对象,生成beanDefinition对象并注册
        documentReader.registerBeanDefinitions(doc, this.createReaderContext(resource));
        return this.getRegistry().getBeanDefinitionCount() - countBefore;
    }
  1. Resumen: se puede encontrar a partir de los pasos anteriores, el análisis de XML específica no fue hecho por el BeanDefinitionReader objetos, sino por DocumentReader objetos para completar. La siguiente es una clase clase diagrama XmlBeanDefinitionReader para ordenar a cabo todo el proceso de acuerdo con este diagrama de clases.
    Aquí Insertar imagen Descripción
      Después de más BeanDefinitionReader formato de archivo de configuración del nombre de ruta de clase, genera una clase de implementación de la interfaz de Recursos diferente, el objetivo es proteger a las diferencias de diferente carga de recursos, el acceso a los objetos de recursos, BeanDefinitionReader objeto la utilización de recursos, la creación de un objetos EncodedResource, recurso conveniente el proceso de codificación. Entonces BeanDefinitionReader analizar objetos EncodedResource, generar objetos Doucement, y finalmente el uso de objeto interno BeanDefinitionReader DoucementReader para resolver Doucement, generando por ello objeto BeanDefinition y registrado para BeanDefinitionRegistry ir. Esto completa los archivos de configuración de análisis sintáctico. Explicar aquí AbstractBeanDefinitionReader clase de implementación más que un XmlBeanDefinitionReader, hay PropertiesBeanDefinitionReader, diferente archivo de configuración con una clase de implementación diferente, pero también de acuerdo con su costumbre necesita una clase de implementación BeanDefinitionReader, para completar el perfil mecánico carga de trabajo.
Publicado tres artículos originales · ganado elogios 5 · Vistas 117

Supongo que te gusta

Origin blog.csdn.net/ranxiaochuan1994/article/details/105231174
Recomendado
Clasificación