Writing in the front

In view of the message that someone wants to learn SpringBoot related knowledge, I am going to write a related blog about SpringBoot series, the goal is to let students read this series of blog posts, can have a glimpse of SpringBoot. This preliminary set down a series of blog posts including SpringBoot introduction, introduction, configuration, log, web development, data access, combined with related docker, caching, message queue, retrieve, tasks, security, distributed and so on a series of blog posts, a lot of work, is a long process, every step I have detailed as far as possible, deserve to go up screenshot shows, I hope it’s really useful for those of you who are watching. I just want to share technical blog posts, but also want to say that if you think it is useful, please click on the following, give a like, also a relief to me, after all, I have to lose a lot of hair, hey hey hey

Serial article transport bar

Detailed SpringBoot tutorial introduction (1) detailed SpringBoot tutorial introduction (2) detailed SpringBoot tutorial configuration file (1) detailed SpringBoot tutorial configuration file (2) detailed SpringBoot tutorial log framework Detailed SpringBoot tutorial Web development (1) detailed SpringBoot tutorial Web development (2) detailed SpringBoot tutorial Web development (3) detailed SpringBoot tutorial data access detailed SpringBoot tutorial boot configuration principle Detailed SpringBoot tutorial for cache development

Startup Configuration Principles

Here, we just explained that we are actually enough to develop some relatively small SpringBoot applications, but we can with the process of use, the underlying principle of SpringBoot analysis, so that we can really use SpringBoot handy, Then we can also develop our own starter scenario, isn’t that exciting? We’ll talk about it later, but I’ll start with a few important event callback mechanisms

As we mentioned before, our configuration core is usually in meta-INF/Spring.Factories for each configuration, whereas our SpringBoot boot is relevant

  • ApplicationContextInitializer
  • SpringApplicationRunListener

Just put it in an IOC container

  • ApplicationRunner
  • CommandLineRunner

Start the process

Create the SpringApplication object

initialize(sources);
private void initialize(Object[] sources) {
    // Save the master configuration class
    if(sources ! =null && sources.length > 0) {
        this.sources.addAll(Arrays.asList(sources));
    }
    // Check whether the current application is a Web application
    this.webEnvironment = deduceWebEnvironment();
    / / from the classpath find meta-inf/spring. All ApplicationContextInitializer factories configuration; And save it
    setInitializers((Collection) getSpringFactoriesInstances(
        ApplicationContextInitializer.class));
    // Find all applicationListeners in the ETA-INF/ spring.Factories configuration from the classpath
    setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
    // Find the main configuration class with the main method from multiple configuration classes
    this.mainApplicationClass = deduceMainApplicationClass();
}
Copy the code

Run the run method

public ConfigurableApplicationContext run(String... args) {
   StopWatch stopWatch = new StopWatch();
   stopWatch.start();
   ConfigurableApplicationContext context = null;
   FailureAnalyzers analyzers = null;
   configureHeadlessProperty();
    
   / / get SpringApplicationRunListeners; Factories from meta-INF /spring.factories under the classpath
   SpringApplicationRunListeners listeners = getRunListeners(args);
    / / callback all get SpringApplicationRunListener. Starting () method
   listeners.starting();
   try {
       // Encapsulate command line arguments
      ApplicationArguments applicationArguments = new DefaultApplicationArguments(
            args);
      // Prepare the environment
      ConfigurableEnvironment environment = prepareEnvironment(listeners,
            applicationArguments);
       		/ / create environment after the completion of the callback SpringApplicationRunListener environmentPrepared (); Indicates that the environment is ready
       
      Banner printedBanner = printBanner(environment);
       
       // Create ApplicationContext; Decide whether to create a Web IOC or a plain IOC
      context = createApplicationContext();
       
      analyzers = new FailureAnalyzers(context);
       // Prepare the context; Save the environment to ioc; And applyInitializers ();
       / / applyInitializers () : the callback previously saved all ApplicationContextInitializer the initialize method
       / / callback all SpringApplicationRunListener contextPrepared ();
       //
      prepareContext(context, environment, listeners, applicationArguments,
            printedBanner);
       / / prepareContext completion callback after all SpringApplicationRunListener contextLoaded ();
       
       //s refresh the container; The IOC container is initialized (and embedded Tomcat is also created for Web applications); The Spring annotations version
       // Where to scan, create, and load all components; (Configuration classes, components, automatic configuration)
      refreshContext(context);
       // Get all applicationRunners and CommandLineRunner from the IOC container for callbacks
       //ApplicationRunner callback, CommandLineRunner callback
      afterRefresh(context, applicationArguments);
       / / all SpringApplicationRunListener finished callback methods
      listeners.finished(context, null);
      stopWatch.stop();
      if (this.logStartupInfo) {
         new StartupInfoLogger(this.mainApplicationClass)
               .logStarted(getApplicationLog(), stopWatch);
      }
       // Return the ioc container after the SpringBoot application is started;
      return context;
   }
   catch (Throwable ex) {
      handleRunFailure(context, listeners, analyzers, ex);
      throw newIllegalStateException(ex); }}Copy the code

Event monitoring mechanism

Configuration in the meta-inf/spring. Factories

ApplicationContextInitializer

public class HelloApplicationContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
    @Override
    public void initialize(ConfigurableApplicationContext applicationContext) {
        System.out.println("ApplicationContextInitializer... initialize..."+applicationContext); }}Copy the code

SpringApplicationRunListener

public class HelloSpringApplicationRunListener implements SpringApplicationRunListener {

    // Mandatory constructor
    public HelloSpringApplicationRunListener(SpringApplication application, String[] args){}@Override
    public void starting(a) {
        System.out.println("SpringApplicationRunListener... starting...");
    }

    @Override
    public void environmentPrepared(ConfigurableEnvironment environment) {
        Object o = environment.getSystemProperties().get("os.name");
        System.out.println("SpringApplicationRunListener... environmentPrepared.."+o);
    }

    @Override
    public void contextPrepared(ConfigurableApplicationContext context) {
        System.out.println("SpringApplicationRunListener... contextPrepared...");
    }

    @Override
    public void contextLoaded(ConfigurableApplicationContext context) {
        System.out.println("SpringApplicationRunListener... contextLoaded...");
    }

    @Override
    public void finished(ConfigurableApplicationContext context, Throwable exception) {
        System.out.println("SpringApplicationRunListener... finished..."); }}Copy the code

Configure (meta-INF /spring.factories)

org.springframework.context.ApplicationContextInitializer=\
com.atguigu.springboot.listener.HelloApplicationContextInitializer

org.springframework.boot.SpringApplicationRunListener=\
com.atguigu.springboot.listener.HelloSpringApplicationRunListener
Copy the code

Just put it in an IOC container

ApplicationRunner

@Component
public class HelloApplicationRunner implements ApplicationRunner {
    @Override
    public void run(ApplicationArguments args) throws Exception {
        System.out.println("ApplicationRunner... run...."); }}Copy the code

CommandLineRunner

@Component
public class HelloCommandLineRunner implements CommandLineRunner {
    @Override
    public void run(String... args) throws Exception {
        System.out.println("CommandLineRunner... run..."+ Arrays.asList(args)); }}Copy the code

Custom starter

Starter starter starter starter starter starter starter starter starter starter starter starter



Then we will go to the screen here, where we can create modules for empty projects. If we want to have our own launcher, we basically need two modules, but which two modules? We’re going to talk about it here.

We need to be clear about two things, as follows

  • What are the dependencies that this scenario needs to use?
  • How do I write automatic configuration

Let’s get a starter to do the analysis, as follows

@Configuration  // Specify that this class is a configuration class
@ConditionalOnXXX  // The auto-configuration class takes effect if the specified condition is true
@AutoConfigureAfter  // Specify the order of the auto-configuration classes
@Bean  // Add components to the container

@ConfigurationPropertie  // Bind the related configuration with the related xxxProperties class
@EnableConfigurationProperties // add xxxProperties to the container

// The auto-configuration class must be loadable
// Automatically configure classes that need to be loaded on startup, configured in meta-INF /spring.factories
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\
org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\
Copy the code

Now we

So we should conform to the following pattern:

  • Initiators are only used for dependency imports;
  • Write an auto-configuration module specifically;
  • Initiators rely on automatic configuration. Other people just need to introduce a starter
  • Like mybatis-spring-boot-starter, we should name the custom starter -spring-boot-starter





Back to the familiar interface, we will create two, one is a SpringBoot project with nothing checked, and one is a Web module checked only. Once we have created this, we will make the following changes in pom.xml

Initiator module


      
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.atguigu.starter</groupId>
    <artifactId>atguigu-spring-boot-starter</artifactId>
    <version>1.0 the SNAPSHOT</version>

    <! -- Initiator -->
    <dependencies>

        <! -- Introducing automatic configuration module -->
        <dependency>
            <groupId>com.atguigu.starter</groupId>
            <artifactId>atguigu-spring-boot-starter-autoconfigurer</artifactId>
            <version>0.0.1 - the SNAPSHOT</version>
        </dependency>
    </dependencies>

</project>
Copy the code

Automatic configuration module


      
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
   <modelVersion>4.0.0</modelVersion>

   <groupId>com.atguigu.starter</groupId>
   <artifactId>atguigu-spring-boot-starter-autoconfigurer</artifactId>
   <version>0.0.1 - the SNAPSHOT</version>
   <packaging>jar</packaging>

   <name>atguigu-spring-boot-starter-autoconfigurer</name>
   <description>Demo project for Spring Boot</description>

   <parent>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-parent</artifactId>
      <version>1.5.10. RELEASE</version>
      <relativePath/> <! -- lookup parent from repository -->
   </parent>

   <properties>
      <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
      <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
      <java.version>1.8</java.version>
   </properties>

   <dependencies>

      <! -- Introducing spring-boot-starter; Basic configuration of all starter -->
      <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter</artifactId>
      </dependency>

   </dependencies>



</project>
Copy the code
package com.atguigu.starter;

import org.springframework.boot.context.properties.ConfigurationProperties;

@ConfigurationProperties(prefix = "atguigu.hello")
public class HelloProperties {

    private String prefix;
    private String suffix;

    public String getPrefix(a) {
        return prefix;
    }

    public void setPrefix(String prefix) {
        this.prefix = prefix;
    }

    public String getSuffix(a) {
        return suffix;
    }

    public void setSuffix(String suffix) {
        this.suffix = suffix; }}Copy the code
package com.atguigu.starter;

public class HelloService {

    HelloProperties helloProperties;

    public HelloProperties getHelloProperties(a) {
        return helloProperties;
    }

    public void setHelloProperties(HelloProperties helloProperties) {
        this.helloProperties = helloProperties;
    }

    public String sayHellAtguigu(String name){
        return helloProperties.getPrefix()+"-"+name + helloProperties.getSuffix(); }}Copy the code
package com.atguigu.starter;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
@ConditionalOnWebApplication // Only the web application takes effect
@EnableConfigurationProperties(HelloProperties.class)
public class HelloServiceAutoConfiguration {

    @Autowired
    HelloProperties helloProperties;
    @Bean
    public HelloService helloService(a){
        HelloService service = new HelloService();
        service.setHelloProperties(helloProperties);
        returnservice; }}Copy the code

The next article

SpringBoot official website actually gives us a lot of cases for reference, integrated with a lot of module example code, SpringBoot on GitHub can be downloaded to run and then study, next time to explain caching.