Spring Detailed Explanation (Super Comprehensive)

1. Spring

​ Spring is one of the SSM (Spring, SpringMVC, Mybatis) frameworks. The so-called framework is a design that highly extracts reusable code and is highly versatile;

1 Overview

(1) Spring is an open source framework;

(2) Spring was born to simplify enterprise-level development. Using Spring, JavaBean can make the code very elegant and concise;

(3) Spring is an IoC (DI) and AOP container framework;

(4) Excellent features of Spring

​ Non-intrusive: Objects in applications developed based on Spring may not depend on Spring APIs

​ Dependency injection: DI (Dependency Injection), the most classic implementation of Inversion of Control (IoC);

​ Aspect Oriented Programming: AOP (Aspect Oriented Programming)

Container: Spring is a container because it contains and manages the life cycle of application objects

(5) Componentization: Spring realizes the combination of simple component configurations into a complex application. In Spring, XML and Java annotations can be used to combine these objects;

(6) One-stop shop: On the basis of IoC and AOP, open source frameworks and excellent third-party class libraries of various enterprise applications can be integrated (in fact, Spring itself also provides Spring MVC for presentation layer and Spring JDBC for persistence layer);

(7) Spring module

[External link picture transfer failed, the source site may have an anti-leeching mechanism, it is recommended to save the picture and upload it directly (img-TE3J19zB-1682512561625) (C:\Users\admin\Desktop\ssm\spring component picture.png)]

explain:

​ Each green box represents a functional module; the black box in the green box represents which jar packages are required to use this functional module.

2. Why use Spring

(1) Convenient decoupling and simplified development

​ Spring is a big factory, which can hand over the creation of all objects and the maintenance of dependencies to Spring management.

(2) Convenient integration of various excellent frameworks

​ Spring does not exclude various excellent open source frameworks, and it provides direct support for various excellent frameworks (such as Struts2, Hibernate, MyBatis, etc.).

(3) Reduce the difficulty of using Java EE API

​ Spring provides packaging for some APIs (JDBC, JavaMail, remote calls, etc.) that are very difficult to use in Java EE development, which greatly reduces the difficulty of applying these APIs.

(4) Convenient program testing

​ Spring supports JUnit4, which makes it easy to test Spring programs through annotations.

(5) AOP programming support

​ Spring provides aspect-oriented programming, which can easily implement functions such as permission interception and operation monitoring of programs.

(6) Support for declarative transactions

​ Transaction management can be completed only through configuration, without manual programming;

​ As a Java programmer, the degree of understanding and mastery of Spring is basically the embodiment of programming ability.

3. Spring first experience

  1. Create a Maven project

    Check Build by archetype, select maven-archetype-quickstart

  2. import dependencies

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.2.10.RELEASE</version>
</dependency>
  1. Create interface and implementation class
public interface UserDao {
    
    
    void queryAll();
}
public class UserDaoImpl implements UserDao {
    
    
    public UserDaoImpl(){
    
    
        System.out.println("UserDaoImpl对象创建了");
    }

    @Override
    public void queryAll() {
    
    
        System.out.println("查询了所有用户信息");
    }
}
  1. Create a spring configuration file

​ Create spring-config.xml in the resource directory of the project. In the idea, you can use the menu New–>XML Configuration File–>Spring Config directly in the resource directory to create.

<?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.xsd">
    <!--
        bean标签进行描述
        id指定创建出来的对象在核心容器中的名字(name),用作唯一标识
        class指定创建对象的类的全类名
    -->
    <bean id="userDaoImpl" class="com.hqyj.cl.dao.impl.UserDaoImpl"/>
</beans>
  1. test
public class UserDaoTest {
    
    

    @Test
    public void selectAll() {
    
    
        ApplicationContext ac = new ClassPathXmlApplicationContext("spring-config.xml");
        UserDao userDaoImpl = ac.getBean("userDaoImpl", UserDao.class);
        userDaoImpl.selectAll();
    }
}

Two, IoC

1. Concept

​IoC (Inversion of Control) is Inversion of Control. Before using Spring, we almost always used the new method to obtain objects, but after using Spring, we no longer use the new method to create objects, but let Spring create them for us. The transfer of control is called inversion of control.

2. IoC container

  • The IoC container is the core of Spring and can also be called the Spring container. Spring uses the IoC container to manage the instantiation and initialization of objects, as well as the entire life cycle of objects from creation to destruction.

  • The objects used in Spring are all managed by the IoC container, and we don't need to manually use the new operator to create objects. The objects managed by the IoC container are called Spring Beans, and Spring Beans are Java objects, which are no different from objects created with the new operator.

  • Spring obtains which objects need to be instantiated by reading information in XML or Java annotations.

  • Spring provides 2 different types of IoC containers, BeanFactory and ApplicationContext containers.

2.1 BeanFactory

​ The BeanFactory container, the lowest-level interface in Spring, provides the simplest container functions, and only provides the functions of instantiating objects and taking objects; BeanFactory will not instantiate beans when it starts. Bean will only be instantiated;

BeanFactory ac = new XmlBeanFactory(new ClassPathResource("applicationContext.xml"));

2.2 ApplicationContext

​ Application context, which inherits the BeanFactory interface, is a more advanced container of Spring and provides more useful functions; ApplicationContext adds many enterprise-level functions on the basis of BeanFactory, such as AOP, internationalization, transaction support, etc.; ApplicationContext instantiates all beans when it starts. It can also configure lazy-init=true for Bean to delay Bean instantiation; ApplicationContext interface has two commonly used implementation classes:

2.2.1 ClassPathXmlApplicationContext

​ This class looks for the specified XML configuration file from the class path ClassPath, and completes the instantiation of the ApplicationContext, as follows:

ApplicationContext ac = new ClassPathXmlApplicationContext("spring-config.xml");

2.2.2 FileSystemXmlApplicationContext

​ This class looks for the specified XML configuration file from the specified file system path, and completes the instantiation of ApplicationContext, as follows:

ApplicationContext ac = new FileSystemXmlApplicationContext("D:\\workspace\\spring_demo\\src\\main\\resources\\spring-config.xml");

3. Creation of Spring Bean

​ The objects managed by the Spring IoC container are called beans, and the beans are created based on the information in the Spring configuration file. In general, we manage beans in Spring configuration files.

​ In Spring's configuration file, it is wrapped by a set of <beans></beans>labels, in which <bean></bean>labels are used to manage each object.

1. No parameter construction creation

​ To create a bean in this way, you must have a no-parameter structure, otherwise an error will be reported in the Spring configuration file

<?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.xsd">
    <!--
        bean标签进行描述
        id指定创建出来的对象在核心容器中的名字(name),用作唯一标识
        class指定创建对象的类的全类名
    -->
    <bean id="userDaoImpl" class="com.hqyj.dao.impl.UserDaoImpl" lazy-init="true"/>
</beans>

1.1 bean tag attribute

attribute name describe
id The unique identifier of the bean, and the configuration and management of the bean by the Spring container are completed through this property. The value of id must start with a letter, and symbols such as letters, numbers, and underscores can be used.
name Multiple names can be specified for the Bean in the name attribute, and each name is separated by a comma or a semicolon. The Spring container can configure and manage the Bean in the container through the name attribute.
class This attribute specifies the specific implementation class of the Bean, which must be a complete class name, that is, the fully qualified name of the class.
scope It is used to set the scope of the Bean instance, and the attribute value can be singleton (singleton), prototype (prototype), request, session and global Session. Its default value is singleton
constructor-arg The child element of the element, which can be instantiated by passing in the construction parameters of this element. The index attribute of this element specifies the serial number of the construction parameter (starting from 0), and the type attribute specifies the type of the construction parameter
property The sub-element of the element is used to call the setter method in the Bean instance to assign property values, thus completing dependency injection. The name attribute of this element is used to specify the corresponding property name in the Bean instance
ref The sub-elements of elements such as and , the bean attribute in this element is used to specify a reference to a Bean instance
value Child elements of elements such as and are used to directly specify a constant value
list Dependency injection for encapsulating List or array types
set Dependency injection for encapsulating Set types
map Dependency injection for encapsulating Map types
entry 元素的子元素,用于设置一个键值对。其 key 属性指定字符串类型的键值,ref 或 value 子元素指定其值
init-method This method is called when the container loads the bean, similar to the init() method in Servlet
destroy-method This method is called when the container deletes the bean, similar to the destroy() method in the Servlet. This method is only valid when scope=singleton
lazy-init Lazy loading, if the value is true, the container will create a Bean instance at the first request; if the value is false, the container will create a Bean instance when it starts. This method is only valid when scope=singleton

2. Dynamic factory mode creation

  1. Create a UserDaoFactory factory
public class UserDaoFactory {
    
    
    public UserDao getUserDao(){
    
    
        return new UserDaoImpl();
    }
}
  1. Spring configuration file
<!-- 通过普通工厂创建bean-->
<!-- 第一步,将工厂类本身加入ioc容器-->
<bean id="userDaoFactory" class="com.hqyj.cl.dao.impl.UserDaoFactory"/>
<!-- 第二步,配置bean 
    factory-bean指定由ioc容器创建的工厂bean
    factory-method指定的该工程的工厂方法 -->
<bean id="userDaoImpl" factory-bean="userDaoFactory" factory-method="getUserDao"/>

3. Static factory mode creation

  1. Create a UserDaoFactory factory
public class UserDaoFactory {
    
    
    public static UserDao getUserDao02(){
    
    
        return new UserDaoImpl();
    }
}	
  1. Spring configuration file
<!-- 第二步,配置bean 
	id指定创建出来的对象在核心容器中的名字(name),用作唯一标识
	class指定创建对象的类的全类名
    factory-method指定的该工程的静态工厂方法 -->
<bean id="userDaoImpl" class="com.hqyj.cl.dao.impl.UserDaoFactory" factory-method="getUserDao02"/>

Fourth, the scope of Spring Bean

Scope Description
singleton (Default) Scopes a single bean definition per Spring IoC container to a single object instance.
prototype Scopes a single bean definition to any number of object instances.
request Scopes a single bean definition to the lifetime of a single HTTP request. That is, each HTTP request has a bean instance created behind a single bean definition. Only available in a network-aware Spring ApplicationContext.
session Scope a single bean definition to the lifetime of an HTTP Session. Only valid in the context of a network-aware Spring ApplicationContext.
application 8 Limit the scope of a single bean definition to the lifecycle of the ServletContext. Only valid in the context of a network-aware Spring ApplicationContext.
websocket Scope a single bean definition to the lifetime of a WebSocket. Only valid in the context of a network-aware Spring ApplicationContext.

4.1 Sample code

4.1.1 singleton

  1. Spring configuration file
<bean id="userDaoImpl" class="com.hqyj.cl.dao.impl.UserDaoImpl" scope="singleton"/>
  1. test class
public class UserDaoTest {
    
    
    @Test
    public void selectAll() {
    
    
        ApplicationContext ac = new ClassPathXmlApplicationContext("spring-config.xml");
        UserDao userDaoImpl = ac.getBean("userDaoImpl", UserDao.class);
        UserDao userDaoImpl1 = ac.getBean("userDaoImpl", UserDao.class);
        System.out.println(userDaoImpl==userDaoImpl1);
    }
}

​ The result output is true. The no-argument construction output statement written in the UserDaoImpl class will only be output once, indicating that the object is only created once.

4.1.2 prototype

  1. Spring configuration file
<bean id="userDaoImpl" class="com.hqyj.cl.dao.impl.UserDaoImpl" scope="prototype"/>
  1. test class
public class UserDaoTest {
    
    
    @Test
    public void selectAll() {
    
    
        ApplicationContext ac = new ClassPathXmlApplicationContext("spring-config.xml");
        UserDao userDaoImpl = ac.getBean("userDaoImpl", UserDao.class);
        UserDao userDaoImpl1 = ac.getBean("userDaoImpl", UserDao.class);
        System.out.println(userDaoImpl==userDaoImpl1);
    }
}

​ The output of the result is false. The no-argument construction output statement written in the UserDaoImpl class will be output twice, indicating that the object has been created twice.

Five, the life cycle of Spring Bean

  • In a traditional Java application, the life cycle of a bean is very simple. The bean is instantiated using the keyword new, and when the bean is not needed, Java automatically performs garbage collection.

  • The life cycle of Bean in Spring is more complicated, which can be expressed as: Bean definition -> Bean initialization -> Bean use -> Bean destruction.

  • Spring chooses the management method according to the scope of the bean. For beans with singleton scope, Spring can know exactly when the bean is created, when it is initialized, and when it is destroyed; for beans with prototype scope, Spring is only responsible for creating, when the container creates an instance of the bean After that, the Bean instance is handed over to the client code management, and the Spring container will no longer track its life cycle.

  • When configuring a bean in XML, you can use the init-method attribute and the destroy-method attribute in the Bean tag to define the bean's initialization callback method and destruction callback method respectively.

5.1 Sample code

  1. userDao
public class UserDaoImpl implements UserDao {
    
    

    public UserDaoImpl(){
    
    
        System.out.println("UserDaoImpl对象创建了");
    }

    @Override
    public void selectAll() {
    
    
        System.out.println("执行了selectAll方法");
    }

    public void init(){
    
    
        System.out.println("init");
    }

    public void destroy(){
    
    
        System.out.println("destroy");
    }
}
  1. Spring configuration file
<bean id="userDaoImpl1" class="com.hqyj.cl.dao.impl.UserDaoImpl" scope="prototype"
      init-method="init" destroy-method="destroy"/>
  1. test class
public class UserDaoTest {
    
    

    @Test
    public void selectAll() {
    
    
        AbstractApplicationContext ac = new ClassPathXmlApplicationContext("spring-config.xml");
        ac.registerShutdownHook();
    }
}

​ In the singleton mode of non-web applications, manually load the Spring IoC container, use the AbstractApplicationContext interface to inherit the ApplicationContext interface, and the method registerShutdownHook/close can manually close the container and let the destroy-method execute the corresponding method

六、TUE

​ DI (Dependency Injection), that is, "dependency injection": the dependency between components is determined by the container at runtime, that is, the container dynamically injects a certain dependency into the component. The purpose of dependency injection is not to bring more functions to the software system, but to increase the frequency of component reuse and build a flexible and scalable platform for the system. Through the dependency injection mechanism, we only need to specify the resources required by the target without any code through simple configuration, and complete our own business logic, without caring where the specific resources come from and who implements them.

​ There are two main implementations of dependency injection, namely setter injection and constructor injection.

6.1 Setter injection

​ Refers to the IoC container using the setter method to inject the dependent instance. Setter-based dependency injection can be realized by calling the bean's setter method after instantiating the bean by calling the no-argument constructor or no-argument static factory method.

​ In the process of instantiating Bean in Spring, the default constructor is first called to instantiate the Bean object, and then the setXxx() method is called through Java's reflection mechanism to inject properties. Therefore, setter injection requires that the corresponding class of the Bean must meet the following two requirements:

  • A default no-argument constructor must be provided;

  • Corresponding setter methods must be provided for the properties that need to be injected.

    When using setter injection, in the Spring configuration file, you need to use <bean>the child elements of the element <property>to inject values ​​for each attribute; use construction injection

, in the configuration file, mainly use <constructor-arg>the tag to define the parameters of the construction method, and use its value attribute (or sub-element) to set the value of the parameter.

6.1.1 Example code

​The tag<property> contains attributes such as name, ref, and value. name is used to specify the parameter name; the value attribute is used to inject the value of basic data type and string type; the ref attribute is used to inject the defined Bean

  1. Create a Java class User
public class User {
    
    
    private int id;
    private String username;
    private String password;

    public User() {
    
    
    }

    public User(int id, String username, String password) {
    
    
        this.id = id;
        this.username = username;
        this.password = password;
    }

    public int getId() {
    
    
        return id;
    }

    public void setId(int id) {
    
    
        this.id = id;
    }

    public String getUsername() {
    
    
        return username;
    }

    public void setUsername(String username) {
    
    
        this.username = username;
    }

    public String getPassword() {
    
    
        return password;
    }

    public void setPassword(String password) {
    
    
        this.password = password;
    }

    @Override
    public String toString() {
    
    
        return "User{" +
                "id=" + id +
                ", username='" + username + '\'' +
                ", password='" + password + '\'' +
                '}';
    }
}
  1. Spring configuration file
<?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.xsd">
    <bean id="user" class="com.hqyj.cl.pojo.User">
        <property name="id" value="1"/>
        <property name="username" value="chenlei"/>
        <property name="password" value="111"/>
    </bean>
</beans>
  1. test class
public class UserDaoTest {
    
    

    @Test
    public void selectAll() {
    
    
        ApplicationContext ac = new ClassPathXmlApplicationContext("spring-config.xml");
        User user = ac.getBean("user", User.class);
        System.out.println(user);
    }
}

6.2 Constructor

​ Refers to the IoC container using the constructor to inject the dependent instance. Dependency injection can be implemented by calling a constructor with parameters, each parameter representing a dependency.

​ There are three ways to inject dependent instances by using constructors: via subscript injection, via attribute injection, and via parameter name injection.

6.2.1 Define a User class

public class User {
    
    
    private int id;
    private String username;
    private String password;

    public User() {
    
    
    }

    public User(int id, String username, String password) {
    
    
        this.id = id;
        this.username = username;
        this.password = password;
    }

    public int getId() {
    
    
        return id;
    }

    public void setId(int id) {
    
    
        this.id = id;
    }

    public String getUsername() {
    
    
        return username;
    }

    public void setUsername(String username) {
    
    
        this.username = username;
    }

    public String getPassword() {
    
    
        return password;
    }

    public void setPassword(String password) {
    
    
        this.password = password;
    }

    @Override
    public String toString() {
    
    
        return "User{" +
                "id=" + id +
                ", username='" + username + '\'' +
                ", password='" + password + '\'' +
                '}';
    }
}

6.2.2 Injection via Subscript

​ When the constructor has multiple parameters, you can use the index attribute to specify the position of the parameters. The value of the index attribute starts from 0. If you do not specify the index, the label sequence is used by default.

<bean id="user" class="com.hqyj.cl.pojo.User">
    <constructor-arg index="0" value="1"/>
    <constructor-arg index="1" value="chenchen"/>
    <constructor-arg index="2" value="23"/>
</bean>

6.2.3 Injection via properties

​ The name attribute is injected by specifying the parameter name in the construction method. It is the most commonly used and should be mastered

<bean id="user" class="com.hqyj.cl.pojo.User">
    <constructor-arg type="int" value="2"/>
    <constructor-arg type="java.lang.String" value="chenchen"/>
    <constructor-arg type="java.lang.String" value="123"/>
</bean>

6.2.4 Injection by parameter name

<bean id="user" class="com.hqyj.cl.pojo.User">
    <constructor-arg name="id" value="3"/>
    <constructor-arg name="username" value="chenchen"/>
    <constructor-arg name="password" value="123"/>
</bean>

6.3 Comparison of setter injection and constructor injection

Constructor injection:

Advantages: All the parameters in the constructor must be specified at the time of creation before the bean can be created, which ensures that after the object is created, the member variables must have values.

Disadvantage: All parameters must be specified, otherwise the object cannot be created. Use this method to change the object creation process.

setter injection:

Advantages: When creating an object, there is no need to specify parameters, and the creation of objects will not be restricted.
Disadvantage: When an object has multiple properties that can be injected, there is no guarantee that all or some properties will be injected.
The setter injection method is more flexible and more convenient to use.

6.4 setter injection object

​ There are several cases: common type, List collection, Map collection, String type, object reference type, Set collection, array, Properties, null type

  1. Student class
public class Student {
    
    
    private String name;
    private Counselor counselor;
    private String[] courses;
    private List<String> books;
    private Map<String, String> idCard;
    private Set<String> studentNumber;
    private String wifeName;
    private Properties properties;

    public Student() {
    
    
    }

    public Student(String name, Counselor counselor, String[] courses, List<String> books, Map<String, String> idCard, Set<String> studentNumber, String wifeName, Properties properties) {
    
    
        this.name = name;
        this.counselor = counselor;
        this.courses = courses;
        this.books = books;
        this.idCard = idCard;
        this.studentNumber = studentNumber;
        this.wifeName = wifeName;
        this.properties = properties;
    }

    public String getName() {
    
    
        return name;
    }

    public void setName(String name) {
    
    
        this.name = name;
    }

    public Counselor getCounselor() {
    
    
        return counselor;
    }

    public void setCounselor(Counselor counselor) {
    
    
        this.counselor = counselor;
    }

    public String[] getCourses() {
    
    
        return courses;
    }

    public void setCourses(String[] courses) {
    
    
        this.courses = courses;
    }

    public List<String> getBooks() {
    
    
        return books;
    }

    public void setBooks(List<String> books) {
    
    
        this.books = books;
    }

    public Map<String, String> getIdCard() {
    
    
        return idCard;
    }

    public void setIdCard(Map<String, String> idCard) {
    
    
        this.idCard = idCard;
    }

    public Set<String> getStudentNumber() {
    
    
        return studentNumber;
    }

    public void setStudentNumber(Set<String> studentNumber) {
    
    
        this.studentNumber = studentNumber;
    }

    public String getWifeName() {
    
    
        return wifeName;
    }

    public void setWifeName(String wifeName) {
    
    
        this.wifeName = wifeName;
    }

    public Properties getProperties() {
    
    
        return properties;
    }

    public void setProperties(Properties properties) {
    
    
        this.properties = properties;
    }

    @Override
    public String toString() {
    
    
        return "Student{" +
                "name='" + name + '\'' +
                ", counselor=" + counselor +
                ", courses=" + Arrays.toString(courses) +
                ", books=" + books +
                ", idCard=" + idCard +
                ", studentNumber=" + studentNumber +
                ", wifeName='" + wifeName + '\'' +
                ", properties=" + properties +
                '}';
    }
}
  1. Counselor class
public class Counselor {
    
    
    private String name;

    public Counselor() {
    
    
    }

    public Counselor(String name) {
    
    
        this.name = name;
    }

    public String getName() {
    
    
        return name;
    }

    public void setName(String name) {
    
    
        this.name = name;
    }

    @Override
    public String toString() {
    
    
        return "Counselor{" +
                "name='" + name + '\'' +
                '}';
    }
}
  1. Spring configuration file
<!--引用注入-->
<bean id="counselor" class="com.hqyj.cl.pojo.Counselor">
    <property name="name" value="张老师"/>
</bean>
<!--注入学生类-->
<bean id="student" class="com.hqyj.cl.pojo.Student">
    <!--普通值注入-->
    <property name="name" value="chenchen"/>
    <!--引用注入-->
    <property name="counselor" ref="counselor"/>
    <!--数组注入-->
    <property name="courses">
        <array>
            <value>计算机组成原理</value>
            <value>计算机网络</value>
            <value>数据结构</value>
        </array>
    </property>
    <!--List集合注入-->
    <property name="books">
        <list>
            <value>Java入门到放弃</value>
            <value>Python大数据挖掘与分析</value>
        </list>
    </property>
    <!--Map集合注入-->
    <property name="idCard">
        <map>
            <entry key="idCard" value="29121821212"/>
            <entry key="phone" value="123121212121"/>
        </map>
    </property>
    <!--Set集合注入-->
    <property name="studentNumber">
        <set>
            <value>20200301123</value>
        </set>
    </property>
    <!--null注入-->
    <property name="wifeName">
        <null/>
    </property>
    <!--Properties注入-->
    <property name="properties">
        <props>
            <prop key="username">chenchen</prop>
            <prop key="password">112112</prop>
        </props>
    </property>
</bean>
  1. test class
public class UserDaoTest {
    
    

    @Test
    public void selectAll() {
    
    
        ApplicationContext ac = new ClassPathXmlApplicationContext("spring-config.xml");
        Student student = ac.getBean("student", Student.class);
        System.out.println(student);
    }
}

7. Annotation-based configuration

​ In Spring, although XML configuration files can be used to implement Bean assembly, if the number of beans in the application is large, the XML configuration files will be too bloated, which will bring certain difficulties to maintenance and upgrades.

Java has provided the Annotation function since JDK 5.0, and Spring 2.5 has also provided comprehensive support for Annotation technology. We can use annotations to configure dependency injection.

​ Spring does not use annotations to assemble beans by default, so you need to add tags in the configuration file <context:annotation-config/>to enable annotation support;

​:<context:annotation-config/> It can only work on beans that have already been registered. It does not perform any operations on beans that are not registered in the spring container

​:<context:component-scan/> In addition to <context:annotation-config/the > function, it also has the function of automatically registering objects with annotations such as @component, @service, @Repositoryetc. into the spring container

​ Configuration package scanning annotations:

​ <context:component-scan base-package=“com.hqyj”/>

1. Create Bean-related annotations

1.1 @Component

​ This annotation can be used to describe the Bean in Spring, but it is a generalized concept that only represents a component (Bean) and can be used at any level. When using it, you only need to mark the annotation on the corresponding class.

1.2 @Repository

​ It is used to identify the class of the data access layer (DAO layer) as a bean in Spring, and its function is the same as that of @Component.

1.3 @Service

​ Usually acts on the business layer (Service layer), and is used to identify the class of the business layer as a bean in Spring, and its function is the same as @Component.

1.4 @Controller

​ Usually acts on the control layer (such as Action of Struts2, Controller of SpringMVC), and is used to identify the class of the control layer as a bean in Spring, and its function is the same as @Component.

2. Annotations related to the Bean life cycle

2.1 @Scope

​ Annotation on the class name is used to specify the scope of the bean, which is equivalent to using the scope attribute when configuring the bean in the xml file. Common values ​​singleton, prototype

2.2 @PostConstruct

​ Note on the method, specify the callback method when the bean is created. <bean>It is equivalent to the function of using the init-method attribute in the tag in the xml configuration file .

2.3 @PreDestroy

​ Note on the method, specifying the callback method when the bean is destroyed. <bean>It is equivalent to the function of using the destroy-method attribute in the tag in the xml configuration file .

2.4 @Configuration

Full annotation implementation, @Configuration is similar to xml configuration file beans tag @bean is similar to bean tag

import com.hqyj.pojo.Dog;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class MyBean {  //方法返回值就是定义bean的类型 方法名就是id
    @Bean
    public Dog dog(){
        return new Dog("哈士奇","黑白色");
    }
}
public static void main(String[] args) {
    //通过注解Component
    ApplicationContext ac = new AnnotationConfigApplicationContext(MyBean.class);
    Dog dog = ac.getBean("dog", Dog.class);
    System.out.println(dog);
}

3. Annotations related to dependency injection

3.1 @Autowired

Autowiring:

​ Automatic assembly means that the Spring container can automatically assemble (autowire) the relationship between cooperating beans without using <constructor-arg>and tags, and inject a bean into the property of other beans.<property>

Autowiring enables dependency injection with less code. However, simple data types such as int, boolean, and String cannot be automatically assembled. Compared with explicit assembly, automatic assembly is not controlled by the programmer.

​ @Autowired annotation can be applied to Bean's attribute variables, attribute setter methods, non-setter methods and constructors, etc., and cooperate with the corresponding annotation processor to complete the automatic configuration of Bean. By default, it is assembled according to the type of Bean. Automatic assembly does not require the corresponding set method.

​ There is also an autowired attribute in the bean tag of the configuration file

​ byType: Ensure that the id of the bean is unique, and the type of the bean is also unique

​ byName: Ensure that the id of the bean is unique, and the id of the bean is the method name of the set method corresponding to this type of property

User class

@Data   //提供了getter  setter方法
@AllArgsConstructor   //提供了有参构造方法
@NoArgsConstructor   //提供了无参构造方法
@Component
public class User {
    @Value("zhangsan")
    private String username;
    @Value("111")
    private String password;
    @Autowired
    private Address address;
}

Address class

@Component
public class Address {
    @Value("chengdu")
    private String addr;

    public String getAddr() {
        return addr;
    }

    public void setAddr(String addr) {
        this.addr = addr;
    }

    @Override
    public String toString() {
        return "Address{" +
                "addr='" + addr + '\'' +
                '}';
    }
}

Configuration file bean.xml

<bean id="User" class="com.hqyj.pojo.User">
</bean>
<bean id="address" class="com.hqyj.pojo.Address">
</bean>

test class

public class UserTest {
    public static void main(String[] args) {
        ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
        User user = ac.getBean("User", User.class);
        System.out.println(user);
    }
}

3.2 @Resource

​ The function is the same as Autowired, the difference is that @Autowired is assembled according to the Bean type by default, while @Resource is assembled according to the Bean instance name by default.

​ There are two important attributes in @Resource: name and type.

​ Spring resolves the name attribute to the instance name of the Bean, and the type attribute to the instance type of the Bean. If the name attribute is specified, it will be assembled by instance name; if the type attribute is specified, it will be assembled by Bean type. If none are specified, assemble according to the Bean instance name first, and then assemble according to the Bean type if they cannot match; if they cannot match, NoSuchBeanDefinitionException will be thrown.

User class

@Data   //提供了getter  setter方法
@AllArgsConstructor   //提供了有参构造方法
@NoArgsConstructor   //提供了无参构造方法
@Component
public class User {
    @Value("zhangsan")
    private String username;
    @Value("111")
    private String password;
    /*@Autowired
    @Qualifier("address1")*/
    @Resource(name = "address1")  //相当于@Autowired+@Qualifier
    private Address address;
}

3.3 @Qualifier

​ Used in conjunction with the @Autowired annotation, the default assembly by Bean type will be modified to be assembled by the instance name of the Bean, and the instance name of the Bean is specified by the parameter of the @Qualifier annotation. (you can specify the injected bean)

Address class (remove @Component annotation)

public class Address {
    private String addr;

    public String getAddr() {
        return addr;
    }

    public void setAddr(String addr) {
        this.addr = addr;
    }

    @Override
    public String toString() {
        return "Address{" +
                "addr='" + addr + '\'' +
                '}';
    }
}

configuration file

<context:component-scan base-package="com.hqyj.pojo"/>
<bean id="User" class="com.hqyj.pojo.User">
</bean>
<bean id="address" class="com.hqyj.pojo.Address">
    <property name="addr" value="chengdu"></property>
</bean>
<bean id="address1" class="com.hqyj.pojo.Address">
    <property name="addr" value="haerbin"></property>
</bean>

User class

@Data   //提供了getter  setter方法
@AllArgsConstructor   //提供了有参构造方法
@NoArgsConstructor   //提供了无参构造方法
@Component
public class User {
    @Value("zhangsan")
    private String username;
    @Value("111")
    private String password;
    @Autowired
    @Qualifier("address1")  //指定要注入的bean
    private Address address;
}

test class

public class UserTest {
    public static void main(String[] args) {
        ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
        User user = ac.getBean("User", User.class);
        System.out.println(user); //拿到haerbin
    }
}

Additional Notes:

<context:component-scan base-package="com.hqyj.pojo"/>
<bean id="User" class="com.hqyj.pojo.User" autowire="byType">
</bean>
<bean id="address" class="com.hqyj.pojo.Address" >
    <property name="addr" value="chengdu"></property>
</bean>
<!--<bean id="address1" class="com.hqyj.pojo.Address">
    <property name="addr" value="haerbin"></property>
</bean>-->

You can remove the @autowire annotation in the user and add it in the configuration file, and you can inject byType, but the injected bean needs to be unique.

<context:component-scan base-package="com.hqyj.pojo"/>
<bean id="User" class="com.hqyj.pojo.User" autowire="byName">
</bean>
<bean id="address" class="com.hqyj.pojo.Address" >
    <property name="addr" value="chengdu"></property>
</bean>
<bean id="address1" class="com.hqyj.pojo.Address">
    <property name="addr" value="haerbin"></property>
</bean>

autowire="byName" is to obtain the corresponding value according to the parameter name of the get and set methods in the pojo (you can manually write the getter and setter method tests of the User class)

To inject the corresponding bean, you need to modify the method name of the set method, for example:

public void setAddress1(Address address) {
    this.address = address;
}

3.4 @Value

​ @Autowired injects another bean, while the @Value annotation injects the value. This annotation is used less because of hard-coding problems caused by injecting constant values ​​in java source code.

4. Example code

  1. UserService
public interface UserService {
    
    
    void selectAll();
}
  1. UserServiceImpl
@Service
public class UserServiceImpl implements UserService {
    
    

    @Autowired
    private UserDao userDao;

    // 注入值
    @Value("张三")
    private String username;

    @Override
    public void selectAll() {
    
    
        System.out.println(username);
        userDao.selectAll();
    }
}
  1. Spring configuration file
<context:component-scan base-package="com.hqyj.cl" />
<bean id="man" class="com.hqyj.cl.pojo.Man" />
<bean id="student" class="com.hqyj.cl.pojo.Student">
    <property name="name" value="student1"/>
</bean>
<bean id="student1" class="com.hqyj.cl.pojo.Student">
    <property name="name" value="student1"/>
</bean>
<bean id="counselor" class="com.hqyj.cl.pojo.Counselor">
    <property name="name" value="张老师" />
</bean>
  1. man class
@Data
@AllArgsConstructor
@NoArgsConstructor
@Component
public class Man {
    
    

    @Value("张三")
    private String name;

/*    @Autowired
    @Qualifier("student1")*/
    @Resource(type = Student.class)
    private Student student;

    @Autowired
    private Counselor counselor;
}
  1. test class
public class UserDaoTest {
    
    

    @Test
    public void selectAll() {
    
    
        ApplicationContext ac = new ClassPathXmlApplicationContext("spring-config.xml");
        Man man = ac.getBean("man", Man.class);
        System.out.println(man);
    }
}

Guess you like

Origin blog.csdn.net/ailaohuyou211/article/details/130394148