Chapter 16. SpringBoot: Custom starter

Author: Dream 1819
Original: https://blog.csdn.net/weixin_39759846/article/details/93032658
Copyright: This article is a blogger original article, reproduced, please attach Bowen link!

Foreword

  This project some time to finish the work, so the family blog is not updated as frequently before, hope understanding.

  SpringBoot easy to use them, it defaults to the mainstream Java integrated framework. It is also a major feature SpringBoot, easy to use, require any framework or technology, only need to introduce corresponding starter can be. The current official has integrated the major technical starters, you can view  the document .

  Most authors began to consider the topic was once a face questions: how to customize a custom launcher?

  This article will explain about the interview questions.

 

Custom starter

  Before custom starter, let's review SpringBoot officials have integrated starter. When we use, simply introducing corresponding  spring-boot-starter-xxxto use (that is, we often say that out of the box).

  Meanwhile, also pre-set default values, if the default values need to be modified, only need to be modified or application.properties application.yml profile. For example: SpringBoot default port number is 8080, if you need to modify the port number, just add the attribute in application.properties  server.port=9090 can.

  Create a custom launcher, you need to create the following two components:

  • Automatic configuration class and the attribute class custom configuration;
  • Maven corresponding dependent.

 

First, create a custom starter project, and the introduction maven dependent on:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-autoconfigure</artifactId>
    <version>2.1.4.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-configuration-processor</artifactId>
    <version>2.0.0.RELEASE</version>
    <optional>true</optional>
</dependency>

 

Then, create entity classes. Prefix plus the name of the field can be created in the name of the property application.properties file.

package com.yanfei1819.springbootstarter.entity;
import org.springframework.boot.context.properties.ConfigurationProperties;

/**
 * Created by 追梦1819 on 2019-05-10.
 */
@ConfigurationProperties(prefix = "spring.person")
public class PersonProperties {
    private String name;
    private int age;
    private double salary;
    // set/get 省略
}

 

The third step is the definition of core services class, which mainly defines the core functions of the starter.

package com.yanfei1819.springbootstarter.service;
import com.yanfei1819.springbootstarter.entity.PersonProperties;

/**
 * Created by 追梦1819 on 2019-05-10.
 */
public class PersonService {
    private PersonProperties properties;
    public PersonService(PersonProperties properties) {
        this.properties = properties;
    }
    public PersonService() {
    }
    public void say() {
        System.out.println("hello,I am " + properties.getName() + ",and I am " + properties.getAge() +
                ",and My salary " + properties.getSalary());
    }
}

 

The fourth step, custom configuration class. Each starter usually has at least one class configuration. Naming is also very obvious, the general naming rules use XxxAutoConfiguration, for example RedisAutoConfiguration and so on. Such functionality is injected into the core SpringBoot context.

package com.yanfei1819.springbootstarter.configuration;

import com.yanfei1819.springbootstarter.entity.PersonProperties;
import com.yanfei1819.springbootstarter.service.PersonService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * Created by 追梦1819 on 2019-05-10.
 */
@Configuration
@EnableConfigurationProperties(PersonProperties.class)
@ConditionalOnClass(PersonService.class)
@ConditionalOnProperty(prefix = "spring.person", value = "enabled", matchIfMissing = true)
public class PersonServiceAutoConfiguration {

    @Autowired
    private PersonProperties properties;

    @Bean
    @ConditionalOnMissingBean(PersonService.class)  // 当容器中没有指定Bean的情况下,自动配置PersonService类
    public PersonService personService() {
        PersonService personService = new PersonService(properties);
        return personService;
    }
}

 

Finally, create a spring.factories file:

org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.yanfei1819.springbootstarter.configuration.PersonServiceAutoConfiguration

  When SpringBoot starts, it looks in the class path  spring.factories  file, this condition is enabled by the initialization @ConditionalOnClass comment. This file maps the name to Spring Boot will try different configurations classes running. Thus, according to this fragment, Spring Boot try all configuration classes run RabbitMQ, Cassandra, MongoDB and Hibernate.

  The key feature is the use of SpringFactoriesLoader.loadFactoryNames @EnableAutoConfiguration method to scan the jar package has a META-INF / spring.factories file, so our automated configuration classes to take effect, so we create a META-INF / spring in resources autoconfigure module. factories document.

 

Use custom starter

Create a new project, the introduction of self-reliance maven defined starter:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter</artifactId>
</dependency>

<dependency>
    <groupId>com.yanfei1819</groupId>
    <artifactId>customize-spring-boot-starter</artifactId>
    <version>0.0.1-SNAPSHOT</version>
</dependency>

  Here we should pay attention to naming rules, the official named spring-boot-starter-xxx , custom named  xxx-spring-boot-starter .

Then the configuration file write test data:

spring.person.name=starter
spring.person.age=26

Let's modify the startup type to be a simple test:

package com.yanfei1819.customizestartertest;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class CustomizeStarterTestApplication implements CommandLineRunner {
    @Value("${spring.person.name}")
    private String name;
    @Value("${spring.person.age}")
    private int age;
    
    public static void main(String[] args) {
        SpringApplication.run(CustomizeStarterTestApplication.class, args);
    }
    @Override
    public void run(String... args) throws Exception {
        System.out.println("姓名是:"+name+",年龄是:"+age);
    }
}

  The above starting CommandLineRunner class implements the interface, and overrides the run method. Spring boot of CommandLineRunnerthe interface is mainly used for application after initialization, a code block to perform logic, this initialization code will only be executed once in the entire application lifecycle. (The effect of the interface can be referred to the official website described ).

  Here is a written test in order to save the class only implements this interface.

 

Finally, start the project, you can see the following results:

 

to sum up

  Based on the above analysis and examples, it can be roughly summed up the work flow starter:

  1. Looking JAR file containing spring.factories when SpringBoot start;

  2. Spring.factories read class file for automatic configuration AutoConfiguration configuration;

  3. The automatic configuration class satisfies the condition (@ConditionalOnXxx) is put into @Bean Springoot context;

  4. Developer directly.

     

Sentiment

  SpringBoot custom launcher greatly facilitate the development of independent functional jar, eliminating a lot of configuration work.

  Yihuhuhuapiao, starter write a custom, it is actually very simple, pay attention to a few notes on it. But we really need to do is to understand the source code by automatically configure principle, the principle is the soul, know, know why, so go the custom starter will be handy. We will continue to follow the principle of shared automatically configure the SpringBoot.

 

reference

SpringBoot official website



Guess you like

Origin blog.csdn.net/weixin_39759846/article/details/93032658