Spring

What is the

Spring is a hierarchical Java SE/EE application full-Stack lightweight open source framework based on Inverse Of Control and AOP (Aspect Oriented Programming: For the kernel, provides the presentation layer Spring MVC and persistence layer Spring JDBC and business layer transaction management and other enterprise-level application technology, but also can integrate many well-known third-party frameworks and class libraries in the open source world, gradually become the most used Java EE enterprise application open source framework.

advantages

  1. Program to interfaces, not classes. The Spring framework reduces the complexity of using interfaces to zero.
  2. Spring is an open source, free framework (container)
  3. Spring is a lightweight, non-invasive framework.
  4. Inversion of Control (IOC), Aspect Oriented Programming (AOP)
  5. Support transaction processing, support for framework integration

The effect of the Spring

  1. It is convenient to decouple and simplify the development of IoC container provided by Spring. The dependencies between objects can be all managed by Spring container, avoiding excessive program confusion and coupling caused by hard coding. Users no longer have to write code for such low-level requirements as singleton classes and property file parsing, and can focus more on upper-level applications.
  2. Support for AOP programming Is facilitated by Spring’s AOP capabilities for faceted programming, making it easy to handle many functions that are not easily implemented with traditional OOP.
  3. The support of declarative transaction can free us from monotonous and boring transaction management code, and flexibly manage transactions through declarative way, improve development efficiency and quality.
  4. Convenient program testing, can be used in a non-container-dependent programming way to test work.
  5. Make it easier to integrate frameworks. Spring makes it easier to use frameworks and provides direct support for excellent frameworks (Struts, Hibernate, Hessian, Quartz, etc.).
  6. Spring encapsulates JavaEE apis (such as JDBC, JavaMail, and remote calls), making them easier to use.

Spring Architecture

The diagram above shows the Architecture of the Spring framework. These components are divided into modules called Core Containers, AOP(Aspect Oriented Programming), Data Access integration, Web layer integration and Test unit Test components.

  1. The Core module is the Core container of Spring. It implements the IOC container pattern and provides the basic functions of the Spring framework. The BeanFactory class contained in this module is the core Spring class responsible for the configuration and management of Javabeans. It implements IOC, or dependency injection, using the Factory Factory pattern.
  2. The Context module inherits the BeanFactory (or Spring core) class and adds event handling, internationalization, resource loading, transparent loading, and data validation. It also provides frame-like Bean access and many enterprise-class features such as JNDI access, SUPPORT for EJBs, remote calls, integration template framework, Email, and scheduled task scheduling.
  3. Spring’s AOP module makes it possible to AOP any Spring-managed object through transaction management. Spring provides an AOP framework written in the standard Java language, most of which is developed based on the API of the AOP consortium. It enables applications to dispense with the complexities of EJBs, but with the key functionality of traditional EJBs.
  4. DAO is the abbreviation of DataAccessObject. The idea of DAO mode is to separate the business logic code from the database interaction code and reduce their coupling. The DAO pattern makes the structure clearer and the code more concise. The DAO module provides a JDBC abstraction layer, simplifies exception errors from database vendors (no longer inheriting large chunks of code from SQLException), significantly reduces code writing, and provides support for declarative and programmatic transactions.
  5. The Web module is based on the Context, which provides the Servlet listener Context and the Web application Context. Provides integration with existing Web frameworks such as JSF, Tapestry, Structs, and so on. Structs is built on the universally recognized good model of MVC. Struts is involved in M, V and C, but it mainly provides a good controller and a set of customized tag library, that is to say, its focus is on C and V. Therefore, it naturally has a series of advantages brought by MVC, such as: Hierarchical structure, high reusable, increased the robustness and scalability of the program, easy to develop and design division of labor, provide centralized and unified authority control, verification, internationalization, logging and so on.
  6. The Test module provides support for using JUnit and TestNG to Test Spring components, provides a consistent ApplicationContext and caches those contexts, and provides mock objects to Test your code independently.

What is program coupling

Coupling, also known as Coupling, is a measure of the degree of connection between modules. The strength of coupling depends on the complexity of module indirect port, and the coupling degree between modules refers to the dependency between modules, including control relation, call relation and data transfer relation.

The more interconnected each module is, the stronger its coupling is, and the less independent it is (reducing the coupling can improve its independent extensibility). In software engineering, coupling refers to dependencies between objects.

The higher the coupling between objects, the higher the maintenance cost. So objects should be designed to minimize coupling between classes and modules. In software design, coupling degree and cohesion degree are commonly used as standards to measure the degree of module independence. One criterion for partitioning modules is high cohesion and low coupling.

It is classified as follows:

(1) Content coupling: When one module directly modifies or manipulates the data of another module, or when one module transfers to another module without passing through the normal entry point, such coupling is called content coupling. Content coupling is the highest level of coupling and should be avoided.

(2) Common coupling: two or more modules reference a global data item together. This coupling is called common coupling. In structures with a lot of common coupling, it can be difficult to determine which module assigned a particular value to a global variable.

(3) External coupling: when a group of modules all access the same global variable instead of the same global data structure, and do not pass the information of the global variable through the parameter list, it is called external coupling.

(4) Control coupling: a module transmits a control signal to another module through the interface, and the module receiving the signal takes appropriate actions according to the signal value. This coupling is called control coupling.

(5) Tag coupling: if A module A transmits A public parameter to two modules B and C through an interface, then there is A tag coupling between modules B and C.

(6) Data coupling: data is transferred between modules through parameters, which is called data coupling. Data coupling is the lowest type of coupling, and it is common in systems because the output data of some modules is used as the input data of others in order to perform meaningful functions.

(7) Non-direct coupling: there is no direct relationship between the two modules, and the connection between them is completely realized by the control and call of the main module.

conclusion

Coupling is an important factor affecting software complexity and design quality. The following principles should be adopted in design:

Cohesion and coupling

If there must be coupling between modules, use data coupling as much as possible, control coupling as little as possible, limit the scope of common coupling, and avoid content coupling as much as possible. Cohesion, which is a natural extension of the concept of information concealment and localization, is a symbol of how closely the elements of a module are combined with each other. Cohesion measures relationships within modules from a functional perspective, and a good cohesive module should do exactly one thing. It describes the functional relationships within a module.

Coupling is a measure of the interconnection between modules in a software structure. The coupling strength depends on the complexity of the module’s indirect interface, the points that enter or access a module, and the data that passes through the interface. The program pays attention to low coupling and high cohesion. The elements of the same module should be highly close to each other, but the interdependence between the modules is not so close. Cohesion and coupling are closely related. A module with high coupling with other modules means low cohesion, while a module with high cohesion means low coupling with other modules. So in software design, we should strive to achieve high cohesion, low coupling.

A popular explanation for coupling:

Dependency refers to dependencies between programs, including dependencies between classes and methods

Spring Quick Start

New Maven Project

Create a New Maven project called Spring and import the following dependencies

<dependencies>
    <! -- https://mvnrepository.com/artifact/org.springframework/spring-context -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>5.2.9. RELEASE</version>
    </dependency>
    <! Provide get&set and constructor dependencies -->
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.10</version>
    </dependency>
    <! -- Unit test dependencies -->
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
        <scope>test</scope>
    </dependency>
</dependencies>
Copy the code

Creating entity objects

Create a new User object and provide member variables and get&set methods

@Data // Provide annotations for the get&set method
@ToString // Provide an annotation to the toString method
public class User {
    private String username;
    private Integer age;
    private String sex;
    private String height;
}
Copy the code

Writing configuration classes

Hand over the User object to the Spring factory to manage in the XML configuration file


      
<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 https://www.springframework.org/schema/beans/spring-beans.xsd">
    
	<! Spring header = spring header = spring header

    
    <! Assign a value to the User object in the configuration file and give it to the Spring container to host the object.
    <bean id="user" class="com.spring.practice.User">
        
        <! Name = member variable name, value = value -->
        <property name="username" value="Trump"/>
        <property name="age" value="3"/>
        <property name="sex" value="No, male, female."/>
        <property name="height" value="150cm"/>
        
    </bean>
</beans>
Copy the code

test

Using the ClassPathXmlApplicationContext reading configuration data, and call the factory method to obtain the attributes in the User object

public class SpringTest {

    @Test
    public void testUser(a) {
        // Create a Spring container object
        ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
        // Get the bean configuration id User bytecode object
        User user = context.getBean("user",User.class); System.out.println(user); }}Copy the code

Test results:

Sping commonly used API

ApplicationContext interface

Org. Springframework. Context. Spring ApplicationContext interface said the IOC container, is responsible for the instantiation, configure, and assemble the bean. The container reads metadata configured in the configuration file to get instructions about which objects to instantiate, configure, and assemble. Configuration metadata is represented as XML, Java annotations, or Java code. It allows you to represent the objects that make up your application and the rich interdependencies between those objects.

Several implementation class is provided by Spring ApplicationContext interface, common practice is to create the ClassPathXmlApplicationContext or FileSystemXmlApplicationContext implementation class. Although XML has been the traditional format for defining configuration metadata, containers can be specified to use Java annotations or code instead of XML forms for the configuration of metadata by providing a small amount of XML configuration to declaratively enable support for these additional metadata formats.

The following figure shows the flow of the SpringIOC container. Application classes are combined with configuration metadata so that there will be a fully configured and executable system or application after the ApplicationContext is created and initialized.

ClassPathXmlApplicationContext

ClassPathXmlApplicationContext is a subclass of ApplicationContext, it can be added to the classpath bean instance configuration file that is used to according to the configuration file access object instance, require configuration file must be in the classpath, can only read in the classpath configuration file. (More common way)

// Create a container to get a configuration instance of the object
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");

// The parent new subclass can also be used.
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
Copy the code

FileSystemXmlApplicationContext

FileSystemXmlApplicationContext class also inherits the ApplicationContext interface, it can be loaded disk configuration files under arbitrary path (must have access to the limit of authority), but must be in the form of an absolute path.

Such as:

ApplicationContext context = 				// Specify the system absolute path to declare the configuration file
        new FileSystemXmlApplicationContext("A:\\markdown-node\\spring\\conf\\bean.xml"); 
Copy the code

AnnotationConfigApplicationContext

AnnotationConfigApplicationContext class is used to read comments on container metadata configuration, using such can realize configuration based on Java class loading Spring application context. Avoid using complex configuration files for configuration. Easier and faster than XML configuration.

ApplicationContext context = new 		// Initializes object instances by reading Java configuration classes instead of XML files.
                   AnnotationConfigApplicationContext(AnnotationConfiguration.class);
Copy the code

Xml-based Spring configuration

Bean label

As you can see from the introductory example above, the bean tag is used to manage objects and create object instances to set their property values. The purpose of the tag is to manage objects in the container.

<! -- Format ↓↓↓ -->
<bean id="Object id" class="Fully qualified class name" >
	<property name="Member variable" value="Attribute value"/>.</bean>
Copy the code

Using bean tags in spring configuration files, object creation can be achieved by adding corresponding properties to the tag. There are many properties in bean tags. The following are common bean properties.

The id attribute

The ID attribute in the bean tag is the unique identity of the object and is used to specify this ID when the container object is created.

Such as:

// Create a container object and specify the configuration file name
ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
// Specify the unique id in the configuration file and get the bytecode object of the User class
User user = context.getBean("user",User.class);
Copy the code

The name attribute

The name attribute and the ID attribute are similar in that they both specify the unique identifier of the object as the tag. If they both specify the unique identifier, they both take effect. Different id can be used as the instantiation flag of the object

<! If the id and name attributes are the same, the id and name attributes can be identified.
<bean name="user" id="user" class="com.spring.practice.User" ></bean>
Copy the code

The class attribute

Provides the fully qualified class name of the managed object for the configuration file to read.

<! -- User class in com.spring.practice package -->
<bean id="user" class="com.spring.practice.User" ></bean>
Copy the code

The scope attribute

The scope property represents the life cycle of the object in the Spring container (IOC container), and can also be understood as how the object is created in the Spring container.

The scope attribute has two default values.

attribute role
singleton Singleton pattern: Containers share an object instance
prototype Multi-instance pattern: Each fetch is a new instance

The default schema for the container is the Singleton singleton schema, so let’s call two object instances for comparison.

ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
User user1 = context.getBean(User.class);
User user2 = context.getBean(User.class);
Since the Spring container defaults to singleton mode, sharing an object instance will print true at this point
System.out.println(user1 == user2);
Copy the code

Change the XML configuration file to the Prototype property and create two object instances for a == comparison.

<bean id="user" class="com.spring.practice.User" scope="prototype"></bean>
Copy the code

As shown in the figure below, creating two object instances for comparison shows false, indicating that the Prototype property is in effect and the Spring container shares multiple instances.

The scope and life cycle of the bean

In Spring, a total of six bean scopes are provided in the container, four of which are valid only for Web applications, and Spring also supports custom scopes. The two default scoped properties were described above.

Here are four more spring scoped properties

attribute role
request Apply the bean definition to the life cycle of a single HTTP request, and the instance is only in thisHTTPValid for the lifetime of the request. Each HTTP request has its own bean instance, and this scope only appliesWebApplicationContextThe environment.
session Apply a single bean definition to the HTTP lifecycleSession, eachHTTP SessionEach has an instance, and that instance is only in thisHTTP SessionIn the life cycle of. This scope only applies toWebApplicationContextThe environment.
application Extend the scope of a single bean definition toServletContextThis scope only applies toWebApplicationContextThe environment.
websocket Extend the scope of a single bean definition toWebSocket. This scope only applies toWebApplicationContextThe environment.

The following figure declares the life cycle of the bean

There are three ways to instantiate beans

No arguments structure

The bean is created using the no-argument constructor, which is just a normal object type with no initial value, but property values can be set using the set method.

<! Create a class with no arguments, specify id unique identifier, and target object fully qualified class name -->
<bean id="user" class="com.spring.practice.User" ></bean>
Copy the code

Call the getBean method to get an instance of the object

@Test
public void testUser(a) {
    ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
    User user = context.getBean(User.class);
    System.out.println(user);
}
Copy the code

Instantiating the bean with no arguments does not set the property value of the object, so the prints are empty.

Factory static method

Using static factory methods to instantiate beans requires specifying a static method in the factory class and defining factory-method properties in the bean properties.

Start by creating a factory class that provides a static method and adds the corresponding constructor argument to return an object type.

public class UserFactory {

    public static User userFactory(String name, Integer age,String sex) {

        return newUser(name,age,sex); }}Copy the code

Configure the bean instance, specifying the instance of factory-method and setting the property values through the constructor.

<! -- Specify static factory classpath, and static method name -->
<bean id="user" class="com.spring.practice.UserFactory" factory-method="userFactory" >
    <! The constructor sets the attribute value, index, in the order of the member variables. -->
    <constructor-arg index="0" value="trump"/>
    <constructor-arg index="1" value="3"/>
    <constructor-arg index="2" value="woman"/>
</bean>
Copy the code

Since static factory instantiation is used, the class attribute must specify the path of the factory class, not the path of the original object. The factory-method attribute specifies the name of the static method in the static factory, that is, the method that returns the instance of the object.

test

@Test
public void testUser(a) {
    // Create a Spring container object
    ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
    User user = context.getBean(User.class);
    System.out.println(user);
}
Copy the code

Prints the value of the constructor property set in the configuration file.

Factory instance method

Similar to the static method instance above, the instance factory method instantiation is used to create new instances by calling non-static methods of other beans from the container. If you want to use this mechanism, you leave the class attribute empty and specify the name of the factory instance bean in the factory-bean attribute, because the container contains the instance method to be called to create the object. The factory-method attribute specifies the non-static method name of the factory class.

Start by creating a factory instance class that provides non-static methods.

public class UserFactoryInstance {

    public User userFactoryInstance(String name, Integer age,String sex) {

        return newUser(name,age,sex); }}Copy the code

Configure XML file injection beans and attributes

The bean of the factory class is first created to provide an object instance for the bean container of the object class

<bean id="userFactoryInstance" class="com.spring.practice.UserFactoryInstance"></bean>
Copy the code

Id represents a unique identifier that can be named arbitrarily, and class is the name of the class that specifies the factory class.

Next, specify the bean container for the User object.

<bean id="userInstance" factory-bean="userFactoryInstance" factory-method="userFactoryInstance">
    
    <constructor-arg index="0" value="Bear"/>
    <constructor-arg index="1" value="18"/>
    <constructor-arg index="2" value="man"/>
</bean>
Copy the code

The factory-bean above requires the id of the corresponding factory bean, and the factory-method requires the non-static method name of the corresponding object instance.

Next, the container object test is called

@Test
public void testUser(a) {
    // Create a Spring container object
    ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
    // Specify the unique identity ID of the User object bean.
    User user = context.getBean("userInstance",User.class);
    System.out.println(user);
}
Copy the code

The printed results are construction properties configured in the bean.

Conclusion: Factory-static methods are similar to factory-instance methods. The only difference is that factory-static methods need only provide a static object method for the User object bean to specify its factory-method. Factory-instance methods do not need to provide static object methods. You also need to create an additional bean container to instantiate the content for the User object bean.

Dependency Injection (DI)

Dependency Injection Overview

Dependency injection (DI) is a process in which objects define their dependencies only through sets, constructors, arguments to factory methods, or properties set on object instances after they are constructed or returned from factory methods. The container then injects property dependencies when the bean is created.

Dependency injection

Set method injection

Inject property values through the set method provided in the class, as shown above in spring Quick Start.

Constructor injection

Properties are injected through a constructor with parameters.

Provides full parameter constructs in the User class, annotated by Lombok

@Data
@AllArgsConstructor // Generate a full-parameter construct
public class User {
    public User(a){}
    private String name;
    private Integer age;
    private String sex;
}
Copy the code

Configure the XML file

<bean id="user" class="com.spring.practice.User">
    <constructor-arg index="0" value="Ted"/>
    <constructor-arg name="age" value="20"/>
    <constructor-arg type="java.lang.String" value="Male"/>
</bean>
Copy the code

There are three types specified by constructor injection, namely index, name and type attributes, which can represent the member variables of the object. The difference is that index represents the index number, which is the position order of the member variables. Name needs to specify the name of the member variables, and type specifies the data type of the member variables.

Create container object tests

@Test
public void testUser(a) {
    // Create a Spring container object
    ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
    User user = context.getBean("user",User.class);
    System.out.println(user);
}
Copy the code
P namespace injection

The P namespace can inject property values using attributes of bean elements instead of nested tag elements.

To use the P tag, you need to import the following into the XML header file

xmlns:p="http://www.springframework.org/schema/p"
Copy the code

Inject the bean’s properties

<! -- p namespace injection, can be directly injected Property p approximately equal to Property Property -->
<bean id="user" class="com.spring.practice.User" p:name="fuckTrump" p:age="3" p:sex="Female"></bean>
Copy the code

The tedious tag is eliminated, and the p tag is used to inject property values according to set

C Named injection

The C tag is similar to the P tag, but it is property injected into the constructor. The c-namespace introduced in Spring3.1 allows inline attributes to configure constructor parameters instead of nested constructor-arg attribute elements.

Using c tags also requires importing the following tags into the XML header file

xmlns:c="http://www.springframework.org/schema/c"
Copy the code

Configuring bean properties

<! Injected using the c namespace Constructor method, the c tag is similar to the Constructor Constructor abbreviation.
<bean id="user2" class="com.spring.practice.User" c:_0="Bear" c:age="19" c:sex="Male"/>
Copy the code

Dependency injection data types

Spring configuration files can easily create instances of objects and inject properties, avoiding excessive use of the new keyword and reducing coupling. Through configuration, you can inject properties of the following three different data types, each with a different attribute tag.

Common properties

Start by creating an object of class User with multiple data types

@Data // provide the get&set method
@AllArgsConstructor // full parameter construction
public class User {
    private String name;// A string of characters
    private Integer age; / / Integer types
    private Address address; // Composite injection object type
    private String[] books; // Array type
    private List<String> hobby; // Set type
    private Map<String,String> card; / / map collections
    private Set<String> games; / / set collection
    private Properties info; / / properties
}
Copy the code

Test injection of common type properties, configure the BEAN properties of XML

<bean id="user" class="com.spring.practice.User">
    <property name="name" value="ted"/>
    <property name="age" value="19"/>
</bean>
Copy the code

Create container object tests

ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
User user = context.getBean("user",User.class);
System.out.println(user);
Copy the code

Object properties

Since the object type is special, we need to assemble an additional bean to inject the property value and then let the class object reference it, as follows.

<! -- Set Address's member variable property value according to the p tag -->
<bean id="address" class="com.spring.practice.Address" p:addressName="beijing"/>

<! Use the ref tag to refer to the bean configured above.
<bean id="user" class="com.spring.practice.User">
    <property name="address" ref="address"/>
</bean>
Copy the code

A collection of attributes

Different collections have different labels, but the way they are injected is relatively simple.

<bean id="user" class="com.spring.practice.User">
    <! -- Array Array type injection -->
    <property name="books">
        <! -- Need to use array tag -->
        <array>
            <! The value tag sets the value of the array -->
            <value>TED</value>
            <value>Bear</value>
            <value>Trump</value>
        </array>
    </property>

    <! -- list set injection -->
    <property name="hobby">
        <! -- Use the list tag -->
        <list>
            <value>List1</value>
            <value>List2</value>
            <value>List3</value>
        </list>
    </property>

    <! -- Map collection injection -->
    <property name="card">
        <map>
            <! -- key is unique and cannot be repeated -->
            <entry key="1" value="Bear"/> <! -- Set key and value -->
            <entry key="2" value="Ted"/>
        </map>
    </property>

    <! -- set set injection -->
    <property name="games">
        <set>
            <value>Dog</value>
            <value>Cat</value>
            <value>Bear</value>
        </set>
    </property>

    <! -- null value injection -->
    <property name="name">
        <! -- Specify a null tag -->
        <null/>
    </property>

    <! -- Properties injection -->
    <property name="info">
        <props>
            <! -- Properties values must be set between Angle brackets -->
            <prop key="1">prop1</prop>
            <prop key="2">prop2</prop>
            <prop key="3">prop3</prop>
        </props>
    </property>
</bean>
Copy the code

The test class

ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
User user = context.getBean("user",User.class);
System.out.println(user);
Copy the code

Annotation-based Spring configuration

An overview of the

Spring also provides a way to manipulate objects using Java configuration classes and annotations, eliminating tedious XML file configuration and requiring only a few annotations to inject objects.

Annotations are special tags in your code that mark the functionality of an attribute.

Format: @ Annotation name (attribute name = attribute value, attribute name = attribute value…)

Spring spring

annotations role
@Component, @Controller, @Service, @Repository, @Configuration, @ComponentScan These six annotations have the same function. They all give the object to the Spring container to manage and let the container create instances of the object. Different names mean different things, @Component means any Component, @Controller represents the control layer, @Service represents the Service layer, @Repository represents the data layer, and @Configuration has the same functions as labels. The difference is that @ComponentScan can scan multiple objects under a package and add them to the container.
@autowired, @Resource, @value Both @Autowired and @Resource represent autowiring properties, with @Autowired being injected by type and @Resource by name.
@Qualifier Specifies that the name of a bean is injected
@Import Import other configuration classes
@Scope Represents the behavior and scope of a bean
@PropertySource Loads the specified properties properties file
@Bean Create a bean for the object, similar to a label in a configuration file

Quick start

Here is a demonstration of spring configuration based on annotation operations.

  1. Create a new project and import the following dependencies
<dependencies>
    <! -- https://mvnrepository.com/artifact/org.springframework/spring-context -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>5.2.9. RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.10</version>
    </dependency>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
        <scope>test</scope>
    </dependency>
</dependencies>
Copy the code
  1. Start by creating a Person class as an object managed by the Spring container
@Data // provide the get&set method
@AllArgsConstructor // full parameter construction
@NoArgsConstructor // No arguments
public class Person {
    private String name;
    private Integer age;
    private String sex;
    private Integer height;
    private String hobby;
}
Copy the code
  1. Object instances are created and dependency injected according to Java configuration classes
@Configuration // indicates that this is a Java configuration class, similar to the 
       big tag in XML
public class AnnotationConfiguration {
    @Bean // Identifies as a bean, similar to the 
       little tag in XML
    public Person person(a) {
		// New a Person object that provides attribute values based on a full-parameter construct
        return new Person("bear".2."man".180."eat"); }}Copy the code
  1. Write a test class, need to use AnnotationConfigApplicationContext annotation container object.
@Test
public void AnnotationTest(a) {
    ApplicationContext context = new AnnotationConfigApplicationContext(AnnotationConfiguration.class);
    //person is the object method name returned in the Java configuration class
    Person person = context.getBean("person", Person.class);
    System.out.println(person);
}
Copy the code

The test results

As you can see above, you only need a Java configuration class and two annotations to manage and inject properties into the Person class, eliminating the need for tags such as


propety, which greatly reduces the number of operations.

Container Management annotations

There are many kinds of annotations that reverse an object to spring container management.

They are: @Component, @Controller, @Service, @Repository, @Configuration, and @ComponentScan

The following configuration classes can use these six annotations to manage objects. The difference is that @ComponentScan requires specifying the package path

@ComponentScan("com.spring") // Scan all objects in the package and hand them over to the Spring container for management
public class AnnotationConfiguration {
    @Bean // Identify as a bean
    public Person person(a) {
        return new Person("bear".2."man".180."eat"); }}Copy the code

@Value

This annotation is used to inject property values of object members, which can be placed on fields or set methods.

Modify the Person class object to demonstrate Value annotations on member variables and set methods

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Person {
    private String name;
    @Value("3")
    private Integer age;
    @ Value (" female ")
    private String sex;
    @Value("150")
    private Integer height;
    @value (" golf ")
    private String hobby;

    @Value("Trump")
    public void setName(String name) {
        this.name = name; }}Copy the code

Replace the constructor parameter in the returned object in the Java configuration class…

@ComponentScan("com.spring")
public class AnnotationConfiguration {
    @Bean
    public Person person(a) {
        return newPerson(); }}Copy the code

The test class

@Test
public void AnnotationTest(a) {
    ApplicationContext context = new AnnotationConfigApplicationContext(AnnotationConfiguration.class);
    Person person = context.getBean("person", Person.class);
    System.out.println(person);
}
Copy the code

The test results are as follows: You can see that the Value displayed is the Value of the @Value injected property

@Scope

This annotation can specify the scope of the objects in the bean container, which defaults to singleton pattern, where multiple objects share an instance, or to Prototype multi-instance pattern, where each object has a different instance, depending on non-Web environments.

Example:

Add the @Scope annotation to the config class object method and set it to Prototype multi-example mode

@ComponentScan("com.spring")
@Import(User.class) // Import the configuration class of the User object
public class AnnotationConfiguration {
    @Bean
    @Scope("prototype") // Change to prototype
    public  Person person(a) {
        return newPerson(); }}Copy the code

Get two bean instance objects in the test class for comparison.

@Test
public void AnnotationTest(a) {
    ApplicationContext context = new AnnotationConfigApplicationContext(AnnotationConfiguration.class);
    Person person1 = context.getBean(Person.class);
    Person person2 = context.getBean(Person.class);
    // Compare whether two objects are still sharing an instance
    System.out.println(person1 == person2);
}
Copy the code

Test results:

You can see that the print result is false, which is what the @scope annotation does, changing the Scope of the bean instance object.

@Import

You can use this annotation when you want to import the configuration of other objects in a Java configuration class.

Test case: Create a User class and a Java configuration class for User.

/* User object */
@Data
public class User {
    @Value("Teddy_Bear")
    private String name;
    @Value("21")
    private Integer age;
}

/* User configuration class */
@Configuration
public class UserConfig {
    // Returns a User object to inject the bean
    @Bean
    public User getUser(a) {
        return newUser(); }}Copy the code

If you want the above User object instance to merge with other bean instances, you need to add an @import annotation to the target class, taking the bytecode form of the imported object.

@ComponentScan("com.spring")
@Import(User.class) // Import the configuration class of the User object
public class AnnotationConfiguration {

    @Bean
    @Scope("prototype")
    public  Person person(a) {

        return newPerson(); }}Copy the code

The test class

@Test
public void AnnotationTest(a) {
    ApplicationContext context = new 	
               AnnotationConfigApplicationContext(AnnotationConfiguration.class);
    Person person= context.getBean("getPerson",Person.class);
    // Get an instance of the User object with the method name and bytecode object in the configuration class.
    User user = context.getBean("getUser",User.class);
    System.out.println(person);
    System.out.println(user);
}
Copy the code

Test results:

You can see that the imported User object instance also prints out the properties specified by @Value.

@Resource

The @Resource annotation is used to assemble the bean instance of the object. By default, it is automatically assembled by the name of the object instance. The target can be specified through the name attribute.

Annotation demo: The mock test inserts a piece of user data

  1. Create the UserDao and UserDaoImpl classes
/* Simulate the data layer */
public interface UserDao {
    // Simulate insert user
    void saveUser(a);
}

/* UserDao implementation class */
@Repository("userDao") // Specify the name of the bean instance
public class UserDaoImpl implements UserDao {

    @Override
    public void saveUser(a) {
        String user = "Bear";
        System.out.println("Insert one." + user + "User"); }}Copy the code
  1. UserService business layer
public interface UserService {
    // Simulate insert user
    void saveUser(a);
}

/* Implementation class */
@Service
public class UserServiceImpl implements UserService{

    @Resource(name = "userDao") // Specify the container-managed name of the UserDaoImpl object
    private UserDao userDao;

    @Override
    public void saveUser(a) {
        // Insert user methods using DAO layer callsuserDao.saveUser(); }}Copy the code

@Resource can also assemble beans according to the set method

Such as:

private UserDao userDao;

@Resource(name = "userDao") // Inject into set
public void setUserDao(UserDao userDao) {
    this.userDao = userDao;
}
Copy the code
  1. The configuration class

Here UserService is configured to be managed in the Spring container by creating an instance of this object to invoke dao layer methods

@ComponentScan("com.spring")
public class UserServiceConfiguration {

    @Bean
    public UserService userService (a){
        return newUserServiceImpl(); }}Copy the code
  1. The test class
@Test
public void test(a) {
    ApplicationContext context = new
        			  AnnotationConfigApplicationContext(UserServiceConfiguration.class);
    
    UserService service = context.getBean("userService",UserService.class);
    // Call the method to print information
    service.saveUser();
}
Copy the code
  1. The test class.

Finally, the bean object instance that calls UserService successfully calls the DAO layer method and prints a message, @resouce

@Autowired

The @AutoWired annotation functions the same as @Resource, except that @AutoWired is Autowired by type.

For example, the UserService instance above:

@Autowired
private UserDao userDao;
Copy the code

The @AutoWired annotation automatically matches classes of type UserDao in the Spring container for property injection.

@Qualifier

This annotation is intended to prevent multiple identical beans from being able to specify one of them, which would result in an error. The @qualifier can specify the name injection for a single bean. Similar to finding instances of beans by name in @Resource.

Let’s create another implementation class for User2Dao with the same content as the other implementation class

@Repository("user2")
public class User2DaoImpl implements UserDao{
    @Override
    public void saveUser(a) {
        System.out.println("Inserted a new user: Trump"); }}Copy the code

The @autowired annotation is used in the UserService layer. This annotation looks up by type, but two implementation classes are created. The Spring container does not know which instance to call, so it needs to use the @qualifier annotation to distinguish between them.

@Service
public class UserServiceImpl implements UserService{

    @Autowired
    @Qualifier("user2") // Specify the bean instance name in User2DaoImpl, and the Spring container will call the implementation class's methods
    private UserDao userDao;

    @Override
    public void saveUser(a) { userDao.saveUser(); }}Copy the code

The test results

The difference between @Resource and @autowired

Both of these are used for autowiring and can be placed on top of property fields

@AutoWired is implemented as byName and must require the object to exist

@resource is implemented by byName by default, and injected by byType if no name is found

- TEDCopy the code