Don’t say no spring! Spring’s first day, learn to enter the factory!

Time:2020-11-26

In the process of work and interview, as Java development, spring is around us. Many people have little knowledge. This time, it will take 14 days to interpret the annotations, components and source codes in the container. AOP concept will be introduced 360 ° without dead corner. The knowledge introduction and explanation of spring MVC will introduce the whole spring as a whole and learn to contract all the installations in the back of you Force, hang and beat the interviewer. Have you learned to be useless~

Don't say no spring! Spring's first day, learn to enter the factory!

1、 Spring foundation

What is spring

Spring is an open source lightweight framework created to solve the complexity of enterprise application development. Spring is committed to solving all layers of Java EE solutions, not just one layer solution.

The development of spring

In February 2003, spring framework officially became an open source project. Spring is committed to various solutions of J2EE application, not only focusing on one layer of solutions. It can be said that spring is a “one-stop” choice for enterprise application development. Spring runs through the presentation layer, business layer and persistence layer. However, spring does not want to replace those existing frameworks, but integrates with these existing frameworks with a high degree of openness.

Spring’s goal

  1. Making existing technologies easier to use
  2. Promote good programming habits

Spring is a comprehensive solution that adheres to one principle:Never reinvent the wheel

In areas where there are already better solutions, spring will never repeat its implementation. For example: object persistence and or mapping;

Spring only supports the existing JDBC, hibernate and other technologies to make it easier to use without repeated implementation. The spring framework has many features, which consist of seven well-defined modules.

Spring architecture

SpringCore

ApplicationContext

SpringWeb

MVC

SpringDAO

ORM

AOP

1. Spring CoreSpring core, which is the most basic part of the framework, provides IOC and dependency injection features;

2. Spring Context: Spring context container, which is a sub interface of beanfactory;

3. Spring WebIt provides support for web application development;

4. Spring MVCIt aims at the realization of MVC in web application;

5. Spring DAO: provide JDBC abstract layer, simplify JDBC coding, at the same time, coding is more robust;

6. Spring ORM: it supports the integration of popular ORM frameworks, such as spring + hibernate, spring + ibatis, etc;

7. Spring AOPAOP (aspect oriented programming) provides a programming implementation compatible with AOP alliance.

(the concepts of IOC and AOP will be explained in secret later.)

Spring common components

Don't say no spring! Spring's first day, learn to enter the factory!

Next, we will analyze the components and annotations in detail

1、 From XML to annotation

As javaers, we all know that in the beginning, bean objects are injected into XML files

bean.xml

<?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="person" class="com.cansluck.spring1.Person">
    <property name="name" value="Cansluck"></property>
    <property name="age" value="29"></property>
  </bean>
</beans>

Similar to the above bean object, it is very troublesome to inject and define properties in the XML file.

If we call it, we need to use the classpathxmlapplicationcontext class to get the XML under the classpath.

Create a person entity class:

public class Person {
  private String name;
  private Integer age;
​
  public Person(){
    super();
  }
  public String getName() {
    return name;
  }
  public void setName(String name) {
    this.name = name;
  }
  public Person(String name, Integer age) {
    super();
    this.name = name;
    this.age = age;
  }
  public Integer getAge() {
    return age;
  }
  @Override
  public String toString() {
    return "Person [name=" + name + ", age=" + age + "]";
  }
  public void setAge(Integer age) {
    this.age = age;
  }
}

Define a test class again

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
​
public class MainTest1 { 
  public static void main(String[] args) {
    //Put beans.xml The class of is loaded into the container
    ApplicationContext app 
        = new ClassPathXmlApplicationContext("bean.xml");
    //Get bean from container
    Person person = (Person) app.getBean("person");
    System.out.println(person);
  }
}

Obviously, if developers don’t need to write an annotation like this, they can’t bear it. Therefore, spring provides the @ configuration annotation. For the use of configuration annotation, the official document describes:

  1. @The con fi definition annotation class indicates that its primary purpose is to serve as a source for bean definitions
  2. @The con fi definition class allows you to define dependencies between beans by calling other @ bean methods in the same class

In the author’s opinion, @ configuration is equal to configuration file, which is as follows:

package com.cansluck.spring1.config;
​
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
​
import com.enjoy.cap1.Person;
​
//Configuration class = = = = = configuration file
@Configuration
public class MainConfig {
​
  //Register a bean in the container with the type of return value
  @Bean
  public Person person01(){
    return new Person("Cansluck", 20);
  }
}

By defining a configuration class mainconfig and adding the @ configuration annotation, there is no need to write more bean object instances in the XML file.

By using:

@Annotationconfigapplicationcontext annotation to get the IOC container.

Annotation configapplicationcontext can be used to implement Java based configuration class loading spring application context.

Avoid use application.xml Configure. It is more convenient than XML configuration.

Through the test class, it can be found that there is no need to define the XML file, and the bean object can be obtained directly by loading the class.

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
​
import com.enjoy.cap1.config.MainConfig;
​
public class MainTest2 { 
  public static void main(String[] args) {
    //Put beans.xml The class of is loaded into the container
    // ApplicationContext app 
    //    = new ClassPathXmlApplicationContext("beans.xml");
​
    ApplicationContext app 
        = new AnnotationConfigApplicationContext(MainConfig.class);
​
    //Get bean from container
    // Person person = (Person) app.getBean("person01");
    // System.out.println(person);
​
    String[] namesForBean = app.getBeanNamesForType(Person.class);
    for (String name : namesForBean) {
      System.out.println(name);
    }
  }
}

2、 Componentscan scan rules

ComponentScan:Define scanning rules and determine which components to scan

First, let’s take a look at the componentscan interface. We mainly focus on the following parameters:

Don't say no spring! Spring's first day, learn to enter the factory!

value:Specify packages to scan

useDefaultFilters:The default value is true, which means that all components are scanned. If you want to customize the scanning range, you must change it to false

includeFilters:Filter [] specifies which components need to be included when scanning

excludeFilters:Filter [] specifies the rules and components to exclude when scanning

The scanning rules are as follows:

Don't say no spring! Spring's first day, learn to enter the factory!

FilterType.ANNOTATION:Scan according to annotation

FilterType.ASSIGNABLE_TYPE:According to the given type, such as the personservice type

FilterType.ASPECTJ:Using AspectJ expressions

FilterType.REGEX:Using regular expressions

FilterType.CUSTOM:Use custom rules to write a class and implement the typefilter interface

See the realization:

1. Use @ componentscan (value=“ com.cansluck.spring1 “) means to scan all packages in this directory.

Configuration class:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.ComponentScan.Filter;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
​
import com.enjoy.cap1.Person;
​
@Configuration
@ComponentScan(value="com.cansluck.spring1")
public class MainConfig {
  //Register a bean in the container with the type of return value, 
  @Bean
  public Person person01() {
    return new Person("Cansluck", 20);
  }
}

2. Customize the filtering rules during package scanning

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.ComponentScan.Filter;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
​
import com.enjoy.cap1.Person;
​
@Configuration
@ComponentScan(value="com.cansluck.spring1", includeFilters = {    
  @Filter(type=FilterType.CUSTOM, classes={CansluckTypeFilter.class})    
}, useDefaultFilters=false)
public class MainConfig {
  //Register a bean in the container with the type of return value, 
  @Bean
  public Person person01(){
    return new Person("Cansluck", 20);
  }
}

Add scan configuration @ filter: custom scan rules to the configuration class mainconfig

The scanning rules are as follows:

FilterType.ANNOTATION:Scan according to annotation

FilterType.ASSIGNABLE_TYPE:According to the given type, such as the personservice type

FilterType.ASPECTJ:Using AspectJ expressions

FilterType.REGEX:Using regular expressions

FilterType.CUSTOM:Use custom rules to write a class and implement the typefilter interface

5, the above is the custom rule. The rest can be implemented by yourself, mainly including annotation and assignable_ Type (according to the given type).

Define a configuration class: canslucktypefilter to implement the typefilter interface:

import java.io.IOException;
​
import org.springframework.core.io.Resource;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.core.type.ClassMetadata;
import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.core.type.classreading.MetadataReaderFactory;
import org.springframework.core.type.filter.TypeFilter;
​
public class CansluckTypeFilter implements TypeFilter{
  private ClassMetadata classMetadata;
​
  /*
   *Metadatareader: read information about the class currently being scanned
   *Metadatareaderfactory: you can get any other class information
   */
  public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory)
      throws IOException {
    //Gets the information of the current class annotation
    AnnotationMetadata annotationMetadata 
        = metadataReader.getAnnotationMetadata();
    //Gets the class information currently being scanned
    classMetadata = metadataReader.getClassMetadata();
    //Get current class resource (path of class)
    Resource resource = metadataReader.getResource();
​
    String className = classMetadata.getClassName();
    System.out.println("----->" + className);
    //If the class contains the ER character, the matching is successful and returns true
    if(className.contains("er")) {
      return true;
    }
    return false;
  }
}

3、 Scope scan rules

Before the @ scope annotation is added to the method, the default bean is singleton
Don't say no spring! Spring's first day, learn to enter the factory!

prototype:For multiple instances, the IOC container does not call the method to create the object in the container, but calls the method to create the object every time it gets it. See the following example for details

singleton:Single instance (by default), the IOC container will call the method to create the object into the IOC container, and each time it is retrieved from the container, it can be understood that map.get (“) object)

request:Mainly for web applications, create an instance of synonym request

session:Create an instance of the same session

(request and session are not used much, just understand)

Configuration class:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.ComponentScan.Filter;
import org.springframework.context.annotation.ComponentScans;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;
​
import com.enjoy.cap1.Person;
import com.enjoy.cap2.controller.OrderController;
​
@Configuration
public class MainConfig {
  //Register a bean in the container. The type is the return value type. The default is single instance
  /*
   *Prototype: multi instance, when the IOC container starts, the IOC container does not call the method to create the object, but calls the method to create the object every time it gets it
   *Singleton: single instance (default). When the IOC container is started, it will call the method to create the object and put it into the IOC container. In the future, each time the object is retrieved, it will be taken directly from the container Map.get )The same bean of
   *Request: mainly for web applications, submit a request to create an instance
   *Session: create an instance of the same session
   */
  @Scope("prototype")
  @Bean
  public Person person() {
    return new Person("Cansluck", 20);
  }
}

Test class:

public class Test {
  @Test
  public void test01(){
    AnnotationConfigApplicationContext app 
        = new AnnotationConfigApplicationContext(MainConfig.class);
​
    String[] names = app.getBeanDefinitionNames();
​
    for(String name : names) {
      System.out.println(name);
    }
    //Take the person instance twice from the container to see if it is the same bean
    Object bean1 = app.getBean("person");
    Object bean2 = app.getBean("person");
    System.out.println(bean1 == bean2);
    //Conclusion: bean1 is bean2, the same object
  }
}

Conclusion

  1. @Scope (“Singleton”), the result obtained is true, which proves that the bean of the same person is retrieved and only instantiated once
  2. @Scope (“prototype”), the result obtained is false, proving that the bean retrieved is not the same person, indicating that it has been instantiated multiple times

4、 Lazy load

Configuration class:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.ComponentScan.Filter;
import org.springframework.context.annotation.ComponentScans;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.context.annotation.Lazy;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;
​
import com.enjoy.cap1.Person;
import com.enjoy.cap2.controller.OrderController;
​
@Configuration
public class MainConfig {
  //Register a bean in the container. The type is the return value type. The default is single instance
  /*
   *Lazy loading: mainly for single instance beans: objects are created when the container is started by default
   *Lazy loading: the container does not create an object at startup, but is created and initialized only when the bean is first used
   */
  @Lazy
  @Bean
  public Person person(){
    System.out.println (add person to container...);
    return new Person("Cansluck", 20);
  }
}

Test class:

public class Test {
  @Test
  public void test01(){
    AnnotationConfigApplicationContext app = new AnnotationConfigApplicationContext(MainConfig.class);
​
    System.out.println ("IOC container created......";
    //The bean is created and initialized when the fetch is performed
    app.getBean("person");
  }
}

When @ lazy is added to the configuration class, it will be loaded into the container only when getbean() is obtained.

In the next 14 days, we will continue to update spring related knowledge, and explain the annotation, source code and other code.

Don't say no spring! Spring's first day, learn to enter the factory!

Java geek thinking

WeChat sweep away official account

Recommended Today

The course of using Chinese software of poedit Pro

Poedit pro (formerly known as poedit) is a free (professional version charge), open source and cross platform gettext class (. Po format, gettext is used in the application program for program internationalization) International Translation editor. It is also one of the most widely used software of the same type. At present, it is available in […]