Spring Boot Starter principle

Spring Boot divides common development functions into one starter after another, so that we only need to introduce the corresponding starter when developing features, instead of importing a bunch of dependencies! The starter can be regarded as a dependency group. Its main functions are importing dependencies and initial configuration. The official Spring naming convention for the starter is spring-boot-starter-xxx, and the third-party naming convention is xxx-spring-boot-starter.

Here we use RocketMQ’s dependency rocketMq-spring-boot-starter to learn the principle of starter.

By introducing RocketMq-spring-boot-starter into your project, you actually introduce some of rocketMQ’s related dependencies.

In rocketmq – spring – the boot class have an automatic assembly RocketMQAutoConfiguration, my answers from a piece of code, including a look at.

@Configuration
@EnableConfigurationProperties(RocketMQProperties.class)
@ConditionalOnClass({MQAdmin.class})
@ConditionalOnProperty(prefix = "rocketmq", value = "name-server", matchIfMissing = true)
@Import({MessageConverterConfiguration.class, ListenerContainerConfiguration.class, ExtProducerResetConfiguration.class, RocketMQTransactionConfiguration.class})
@AutoConfigureAfter({MessageConverterConfiguration.class})
@AutoConfigureBefore({RocketMQTransactionConfiguration.class})

public class RocketMQAutoConfiguration {
    private static final Logger log = LoggerFactory.getLogger(RocketMQAutoConfiguration.class);

    public static final String ROCKETMQ_TEMPLATE_DEFAULT_GLOBAL_NAME =
        "rocketMQTemplate";

    @Autowired
    private Environment environment;

    @Bean(destroyMethod = "destroy")
    @ConditionalOnBean(DefaultMQProducer.class)
    @ConditionalOnMissingBean(name = ROCKETMQ_TEMPLATE_DEFAULT_GLOBAL_NAME)
    public RocketMQTemplate rocketMQTemplate(DefaultMQProducer mqProducer, RocketMQMessageConverter rocketMQMessageConverter) {
        RocketMQTemplate rocketMQTemplate = new RocketMQTemplate();
        rocketMQTemplate.setProducer(mqProducer);
        rocketMQTemplate.setMessageConverter(rocketMQMessageConverter.getMessageConverter());
        returnrocketMQTemplate; }}Copy the code
  • @Configuration indicates that this is a Configuration class, and the method annotated by @Bean is a Spring Bean, for examplerocketMQTemplate.
  • @ EnableConfigurationProperties, enabled by @ ConfigurationProperties beans, are introduced hereRocketMQProperties

RocketMQProperties are the properties that need to be written in the YML file.

@ConfigurationProperties(prefix = "rocketmq")
public class RocketMQProperties {

    private String nameServer;

    private String accessChannel;

    private Producer producer;

    private Consumer consumer = new Consumer();
}
Copy the code

In the Spring when you start the Boot program will only scan the lower directory by default with @ Configuration annotation class, so RocketMQAutoConfiguration as mentioned in this article is how to scan? When the project starts, all the spring.factories in the project are loaded, and then the configuration classes are loaded.

Now that we understand the principle, let’s simply implement a starter of our own! The main function of the starter is to concatenate a string to the end of an object!

I. New projects

Create a new project called javatip-spring-boot-starter and introduce the following dependencies

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

2. Add configuration classes

Set the properties file corresponding to the class to javatip.name.

@ConfigurationProperties(prefix = "javatip")
public class JavatipPorperties {

    private String name;

    public String getName(a) {
        return name;
    }

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

New method of concatenating string

This method basically concatenates a fixed string for the object

public class StrUt {

    private String name;

    public String strTo(Object object){

        return object +"-"+ getName();
    }

    public String getName(a) {
        return name;
    }

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

4. Add the automatic configuration class

Using annotations @ EnableConfigurationProperties enable JavatipProperties configuration class

Use the @Configuration annotation with @Bean to register a concatenated string Bean object.

@Configuration
@EnableConfigurationProperties(JavatipPorperties.class)
public class JavatipAutoConfiguration {

    @Autowired
    private JavatipPorperties javatipPorperties;

    @Bean
    public StrUt strut(a){
        StrUt strut = new StrUt();
        strut.setName(javatipPorperties.getName());
        returnstrut; }}Copy the code

5. Add the discovery file

In the Resources folder, create a meta-INF folder, and in the Meta-INF folder, create a configuration discovery file, spring.factories, and write the auto-configuration classes to the file.

org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.javatip.str.configuration.JavatipAutoConfiguration
Copy the code

Six, packaging test

Use the MVN install command to push the project package to the local Maven repository, then create a new test project and import the packaged dependencies.

<dependency>
    <groupId>com.javatip</groupId>
    <artifactId>javatip-spring-boot-starter</artifactId>
    <version>0.0.1 - the SNAPSHOT</version>
</dependency>
Copy the code

Write the attribute javatip.name for the auto-concatenated string to the application.yml file.

javatip:
  name: Java journey
Copy the code

Then write a test class by hand:

@RestController
public class Test {
    
    @Autowired
    private StrUt strUt;

    @GetMapping("test")
    public String test(a){

        String str = strUt.strTo("who are you?");
        returnstr; }}Copy the code

After running the test class, the page returns

who are you? - Java journeyCopy the code

In this way, a simple starter is written, as long as you understand the principle of the starter, it is very simple to implement, the first point is that the starter is equivalent to a dependency group, the other point is that the starter can complete the initial configuration.