Spring basic usage 1 - Spring's core mechanism: IOC, DI

       Foreword: I have always wanted to write a series of articles about Spring, but I have been thinking about it for a long time but I don't know how to explain it. After all, it is not so easy to explain a complex framework clearly, and I can only do my best. The Spring series of articles are intended to be expanded in this order: an overall introduction to Spring in the form of a mind map -> an introduction to the basic usage of Spring -> an in-depth use of Spring -> a peek at the Spring source code -> if necessary, a mind map to summarize and outline Spring. This article introduces the basic usage of Spring. The purpose is more to get started with Spring usage. The demo and accessory items are tools for quickly querying the basic usage of Spring.

This article focuses on the following issues:

  • Overview of Spring Core Features
  • Basic concepts of IOC and DI
  • Two ways of dependency injection

1. Spring core functions

       Spring is a very active open source framework, it manages your code in a non-intrusive way, Spring advocates "least intrusion", and even in the process of project development, you don't feel Spring at all.

There are two core functions of        the Spring Framework :

  • One is that the Spring container, as a super factory, is responsible for creating and managing all java objects, which are called beans. (IOC implementation)
  • The second is the dependencies between the Spring container management beans. (DI implementation)

2. Basic concepts of IOC and DI

       IOC : Inversion of control, which entrusts the creation, initialization, and destruction of objects to the spring container, and the spring container controls the life cycle of the object.

* Control: refers to the control of the life cycle of object creation, maintenance, destruction, etc. This process is generally controlled by me    
        Our program to actively control, such as using the new keyword to create an object (create), in the use of  
        Keep references during use (maintenance), and the GC will recycle the object after losing all references (pin  
        destroy).   
* Reversal: It means that the control of the life cycle of object creation, maintenance, destruction, etc. is changed from program control to IOC  
        Container control, when you need an object, you can directly get it from the IOC container by name.  

         

         DI: Dependency Injection is an important implementation of IOC, which describes the same concept as IOC.

        The creation of an object often involves the creation of other objects. For example, a member variable of an object A holds a reference to another object B. This is a dependency, and A depends on B. Since the IOC mechanism is responsible for the creation of objects, this dependency must be taken care of by the IOC container. The responsible way is DI - dependency injection , by writing dependencies into configuration files, and then when creating objects with dependencies, the IOC container injects the dependent objects. For example, when creating A, it checks that there is a dependency, IOC The container creates the object B that A depends on and injects it into A (assembly, implemented through reflection mechanism), and then returns A to the object requester to complete the work.

       Its working process is shown in the following figure:


        Corresponding to the two core functions of Spring, the programmers have to do two things:

  • One is to develop beans: Spring recommends interface-oriented programming. The coupling between java objects is only at the interface level, and there is no need to care about the specific implementation of services;
  • The second is to configure beans: inform Spring through xml configuration files or annotations, which beans need to be managed by Spring, and the dependencies between beans;

        When you need to use the bean, you can get it directly from the container.

3. The way of dependency injection

         Dependency injection (DI) usually has the following two ways:

  • Set value injection: The IOC container uses the setter method of the member variable to inject the dependent object;
  • Constructor injection: IOC containers use constructors to inject dependent objects.

3.1 Set value injection

       Setter injection: The IOC container uses the setter method of the member variable to inject the dependent object.

     The development process is as follows: (This is described in the form of an xml configuration file)

Step 1: Develop Bean to
       define service class interface:

            * Pen.java: used to implement the signature function;

            * Person.java: Need to use Pen to sign, that is, Person.java depends on Pen.java

       Implement the service class function:

            * BallpointPen.java:提供用圆珠笔实现签名的功能;

            * Pencil.java:提供用铅笔实现签名的功能;

            * Chinese.java:Person的子类,表示中国人来签名;

 

          Chinese.java代码如下,类中需要定义Pen接口对象的成员变量pen,并提供其setter方法,用于设值注入: 

package com.wj.chapter1.ioc.setter.xml.Service;  
  
import com.wj.chapter1.ioc.setter.xml.IService.Pen;  
import com.wj.chapter1.ioc.setter.xml.IService.Person;  
  
public class Chinese implements Person {  
  
    private Pen pen;    /** 代码耦合的层次仅限于接口层次. */  
      
    // 设值需要的setter方法  
    public void setPen(Pen pen) {  
        this.pen = pen;  
    }  
  
    @Override  
    public void signOwnName() {  
        pen.signName("中国人");  
    }  
  
}  

  步骤二:配置Bean

 

        通过xml配置文件的方式告知Spring,需要Spring管理哪些Bean,以及Bean之间的依赖关系。

 

<?xml version="1.0" encoding="UTF-8"?>  
<beans xmlns="http://www.springframework.org/schema/beans"  
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
       xsi:schemaLocation="http://www.springframework.org/schema/beans  
                           http://www.springframework.org/schema/beans/spring-beans-4.3.xsd">  
      
    <!-- 设值注入(XML方式):通过成员变量的setter方法注入被依赖对象. -->  
    <!-- 属性id    : Bean在Spring容器中的唯一标识.      -->  
    <!-- 属性class : 指定该Bean的具体实现类,而不能是接口.  -->  
    <bean id="chinese"      class="com.wj.chapter1.ioc.setter.xml.Service.Chinese">  
        <!-- 驱动调用chinese的setPen()方法,将容器中pencil(或ballpointPen)作为传入参数 -->  
        <!-- property子节点指明依赖关系 -->  
        <property name="pen" ref="pencil"></property>  
    </bean>  
      
    <!-- 定义Pen.class的两个实现类Bean. -->  
    <bean id="pencil"       class="com.wj.chapter1.ioc.setter.xml.Service.Pencil"></bean>  
    <bean id="ballpointPen" class="com.wj.chapter1.ioc.setter.xml.Service.BallpointPen"></bean>  
</beans> 

         xml配置文件中,每个Bean对应Spring容器里的一个java实例,property节点元素指明Bean之间的依赖关系。

 

步骤三:调用Bean

      使用前面定义的服务,实现中国人用铅笔签名的功能:

 

package com.wj.chapter1.ioc.setter.xml.main;  
  
import org.springframework.context.ApplicationContext;  
import org.springframework.context.support.ClassPathXmlApplicationContext;  
  
import com.wj.chapter1.ioc.setter.xml.IService.Person;  
  
public class Main {  
      
    // 1.指明xml配置文件位置,便于Spring读取,从而知道Bean的相关信息  
    private static final String PATH_XML = "com/wj/chapter1/ioc/setter/xml/applicationContext-setter.xml";  
  
    @SuppressWarnings("resource")  
    public static void main(String[] args) {  
        // 2.根据xml配置文件,创建Spring IOC容器的上下文  
        ApplicationContext cxt     = new ClassPathXmlApplicationContext(PATH_XML);  
          
        // 3.在需要使用服务的时候,直接从Spring容器中获取  
        Person             chinese = cxt.getBean("chinese", Person.class);  
          
        // 4.获取提供服务的对象后,调用Bean的服务  
        chinese.signOwnName();  
    }  
}  

  步骤四:查看调用结果

3.2 构造注入

       构造注入:IOC容器使用构造器来注入被依赖对象。

     开发过程如下:(此处以xml配置文件的形式说明)

步骤一:开发Bean

      定义服务类接口:

            * Pen.java:用于实现签名功能;

            * Person.java:需要使用Pen来签名,即Person.java依赖于Pen.java

      实现服务类功能:

            * BallpointPen.java:提供用圆珠笔实现签名的功能;

            * Pencil.java:提供用铅笔实现签名的功能;

            * Chinese.java:Person的子类,表示中国人来签名;

 

      Chinese.java代码如下,类中需要定义Pen接口对象的成员变量pen,并提供带参数的构造函数,用于构造注入:

 

package com.wj.chapter1.ioc.constructor.xml.Service;  
  
import com.wj.chapter1.ioc.constructor.xml.Iservice.Pen;  
import com.wj.chapter1.ioc.constructor.xml.Iservice.Person;  
  
public class Chinese implements Person {  
  
    private Pen pen;    /** 代码耦合的层次仅限于接口层次. */  
      
    // 构造注入所需的带参数的构造器  
    public Chinese(Pen pen) {  
        this.pen = pen;  
    }  
  
    @Override  
    public void signOwnName() {  
        pen.signName("中国人");  
    }  
} 

 步骤二:配置Bean

 

        通过xml配置文件的方式告知Spring,需要Spring管理哪些Bean,以及Bean之间的依赖关系。

 

<?xml version="1.0" encoding="UTF-8"?>  
<beans xmlns="http://www.springframework.org/schema/beans"  
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
       xsi:schemaLocation="http://www.springframework.org/schema/beans  
                           http://www.springframework.org/schema/beans/spring-beans-4.3.xsd">  
      
    <!-- 构造注入(XML方式):通过调用构造函数注入被依赖对象. -->  
    <!-- 属性id    : Bean在Spring容器中的唯一标识.      -->  
    <!-- 属性class : 指定该Bean的具体实现类,而不能是接口.  -->  
    <bean id="chinese"      class="com.wj.chapter1.ioc.constructor.xml.Service.Chinese">  
        <!-- 下面只有一个constructor-arg子元素,驱动Spring调用Chinese带一个参数的构造器来创建对象 -->  
        <constructor-arg name="pen" ref="ballpointPen" index="0"></constructor-arg>  
    </bean>  
    <bean id="pencil"       class="com.wj.chapter1.ioc.constructor.xml.Service.Pencil"></bean>  
    <bean id="ballpointPen" class="com.wj.chapter1.ioc.constructor.xml.Service.BallpointPen"></bean>  
      
</beans>

 步骤三:调用Bean

        使用前面定义的服务,实现中国人用圆珠笔签名的功能:

package com.wj.chapter1.ioc.constructor.xml.main;  
  
import org.springframework.context.ApplicationContext;  
import org.springframework.context.support.ClassPathXmlApplicationContext;  
  
import com.wj.chapter1.ioc.constructor.xml.Iservice.Person;  
  
public class Main {  
      
    // 1.指明xml配置文件位置,便于Spring读取,从而知道Bean的相关信息  
    private static final String PATH_XML = "com/wj/chapter1/ioc/constructor/xml/applicationContext-constructor.xml";  
  
    @SuppressWarnings("resource")  
    public static void main(String[] args) {  
        // 2.根据xml配置文件,创建Spring IOC容器的上下文  
        ApplicationContext cxt     = new ClassPathXmlApplicationContext(PATH_XML);  
          
        // 3.在需要使用服务的时候,直接从Spring容器中获取  
        Person             chinese = cxt.getBean("chinese", Person.class);  
          
        // 4.获取提供服务的对象后,调用Bean的服务  
        chinese.signOwnName();  
    }  
}  

 步骤四:查看调用结果

3.3 两种注入方式的对比

      建议采用以设值注入为主,构造注入为辅的注入策略。对于依赖关系无需变化的注入,可以考虑采用构造注入,其他依赖关系的注入,则尽量用设值注入。

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326299039&siteId=291194637