Spring core components works Brief

Spring Framework has three core components: Spring Core, Spring Context and Spring Beans, they laid the foundation for Spring and propped up the framework of Spring. Other features, such as Spring Web, AOP, JDBC, etc. are developed on the basis of its implementation.

Bean Components

Spring use the factory mode management object (Bean) used in the program, the uppermost Bean plants the BeanFactory interface, a simple point of view, the plant is a corresponding return Bean instance needed.

public interface BeanFactory {
    //...        
    Object getBean(String name);
}

In Factory mode, the factory implementation class generated Bean returned to the calling client, which requires the client to provide the required class instance to generate their own factory class, increase the burden on customers. Spring conjunction with the control and dependency inversion required injection provide examples for the client, simplifying the operation of the client. Specific implementation is as follows.

public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory
        implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable {
    /** Map of bean definition objects, keyed by bean name */
    private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<String, BeanDefinition>;
    public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition){     
        //...
    }
}

beanDefinitionMap Specific Bean container, Spring objects created instance save them. Clients need, use getBean method plant to try to give the corresponding instance, if the instance already exists, this instance is returned; if it does not exist, first generate corresponding instance by registerBeanDefinition method to save in beanDefinitionMap in (Lazy Initialization ), then return the instance to the client.

13341631-fa7f8c2ee4ded7fa.png
Inheritance Spring Bean Factory

Spring relevant code package is org.springframework.beans

beanDefinitionMap not directly save the instance itself, but will be stored in the instance encapsulates BeanDefinition object. BeanDefinition instance contains all the information, which is defined in the following simplified version.

public class BeanDefinition {
    private Object bean;

    private Class<?> beanClass;
    private String beanClassName;

    // Bean 属性字段的初始化值
    private BeanPropertyValues beanPropertyValues;

    //...
}

Spring Bean Factory production when Bean

  1. Save first instance to a type parameter and beanClass beanClassName, to save the need to initialize the beanPropertyValues ​​field names and values, this process is achieved by controlling the inversion Spring, the second section will be briefly described herein
  2. Generating bean instance, and will need to be initialized by the reflection mechanism write bean instance field value, stored in the bean instance, the complete construct BeanDefinition.
    Suppose we have completed step 1) operation, after the process is expressed with the following code.
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition){
    //生成 bean 实例,并完成初始化
    Object bean = createBean(beanDefinition);
    //将 bean 实例保存在 beanDefinition 中
    beanDefinition.setBean(bean);
    //将 beanDefinition 实例保存在 Spring 容器中
    beanDefinitionMap.put(beanName, beanDefinition);
}

protected Object createBean(BeanDefinition beanDefinition) {
    try{
        Object bean = beanDefinition.getBeanClass().newInstance();
        try {
            setBeanPropertyValues(bean, beanDefinition);
        } catch (NoSuchFieldException | SecurityException | IllegalArgumentException e) {
            e.printStackTrace();
        }
        return bean;
    }catch(InstantiationException e){
        e.printStackTrace();
    }catch(IllegalAccessException e){
        e.printStackTrace();
    }

    return null;
}

protected void setBeanPropertyValues(Object bean, BeanDefinition beanDefinition) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException{
    for(PropertyValue pv : beanDefinition.getBeanPropertyValues().getBeanPropertyValues()){
        Field beanFiled = bean.getClass().getDeclaredField(pv.getName());
        beanFiled.setAccessible(true);
        beanFiled.set(bean, pv.getValue());
    }
}

Context Components

In general, the traditional program design, either use the factory to create an instance, or create the instance, examples of the caller must first take the initiative to create an instance before you can use. Inversion of Control (Inverse of Control) will be handed over to create a process instance container implementation, the caller will hand over control, the so-called inversion of control.
Dependency injection (Dependence Injection) further on the basis of the control on the reversal. If there is no dependency injection container creates an instance and saved, the caller needs to use getBean (String beanName) to get to the instance. When using dependency injection, the container will be automatically injected into the completion Bean instance caller the appropriate configuration for further use.

Context component by the above-described injection control and dependency inversion assisting implements the Spring Ioc container. Here we explain Bean instance as required to a Service class. Practical applications, we will need to manage a lot of Spring Bean instance.

public class SampleService {
    private String service;
        public String getService() {
        return service;
    }
    public void setService(String service) {
        this.service= service;
    }
}

The program is running, you need a SampleService, we do not let a new instance of the caller, but that instances of the SampleService handed over to the Spring container manages the configuration file, and specify its initialization parameters. That resource configuration file, which reads as follows.

<?xml version="1.0" encoding="UTF-8"?>
<beans>
    <bean name="sampleService " class="com.service.SampleService ">
        <property name="service" value="This is a service"></property>
    </bean>
</beans>

Spring Core ResourceLoader component provides an interface to facilitate read xml files or other resource files. The core function code should be provided as follows.

public class ResourceLoader {
    public Resource getResource(String location){
        URL resource = this.getClass().getClassLoader().getResource(location);
        return new UrlResource(resource);
    }
}

// UrlResource 的功能代码
public class UrlResource implements Resource {
    private final URL url;

    public UrlResource(URL url){
        this.url = url;
    }

    @Override
    public InputStream getInputStream() throws IOException {
        URLConnection urlConnection = url.openConnection();
        urlConnection.connect();
        return urlConnection.getInputStream();
    }

}

That load the resource file and returns in the form of a data stream. The Context resources defined to form the corresponding bean and stored in a container, bean name is SampleService, the program for further use. This completes the inversion of control work. Then we need to inject sampleService use it where it is needed, i.e. dependency injection operation is completed.
Assuming now that the objects SampleController used SampleService, Spring provides three dependency injection manner, constructor injection, injection and the setter injection annotations.

public class SampleController {
    /**
     * 3\. 注解注入
    **/
    /* @Autowired */
    private SampleService sampleService;

    /**
     * 1\. 构造器注入
    **/
    public SampleController(SampleService sampleService){
        this.sampleService = sampleService;
    }
    //无参构造函数
    public SampleController(){}

    // 类的核心功能
    public void process(){
        System.out.println(sampleService.getService());
    }
    /**
     * 2\. setter 注入
    **/
    /*public void setService(SampleService service) {
        this.service= service;
    }*/
}

Injection mode corresponding to the three kinds of different configurations in the configuration file, based on the previous xml file, we can achieve injection of these three ways, respectively. It should be noted here SampleController is generated using Spring's Ioc container management.

<?xml version="1.0" encoding="UTF-8"?>
<beans>
    <bean name="sampleService " class="com.service.SampleService ">
        <property name="service" value="This is a service"></property>
    </bean>

<!-- 1\. 构造器注入方式为SampleContorller 的 bean 注入 SampleService -->
    <bean name="sampleContorller" class="com.controller.SampleContorller">
        <!-- index 是构造方法中相应参数的顺序 -->
        <constructor-arg index="0" ref="sampleService"></constructor-arg>
    </bean>

<!-- 2\. setter 注入方式为SampleContorller 的 bean 注入 SampleService -->
<!--    
    <bean name="sampleContorller" class="com.controller.SampleContorller">
        <property name="sampleService " ref="sampleService"></property>
    </bean>
-->

<!-- 3\. 注解注入方式为SampleContorller 的 bean 注入 SampleService -->
<!--    
    <bean name="sampleContorller" class="com.controller.SampleContorller">

    <!-- 不需要配置,Spring 自动按照类型注入相应的 bean -->
    </bean>
--> 
</beans>

Guess you like

Origin blog.csdn.net/weixin_34220179/article/details/90794229