Play with Spring - customize Spring Starter

1 what is Spring Starter

From the official website

Starters are a set of convenient dependency descriptors that you can include in your application. You get a one-stop shop for all the Spring and related technologies that you need without having to hunt through sample code and copy-paste loads of dependency descriptors. For example, if you want to get started using Spring and JPA for database access, include the spring-boot-starter-data-jpa dependency in your project.

Translation:

Initiators are a convenient set of dependency descriptors that you can include in your application. You can get all the one-stop services you need for Spring and related technologies without looking up sample code and copying and pasting a lot of dependency descriptors. For example, if you want to start using Spring and JPA for database access, include the Spring -boot-starter-data- JPA dependency in your project.

2 customize Starter's Hello World

2.1 general process of customizing Spring Starter

(1) New Spring Boot project

(2) Add dependency

(3) Adjust project structure

(4) Custom Configuration class

(5) Add spring Factories file that specifies the auto configuration class

(6) maven install to the local warehouse

(7) Introduction of other items

Now let's realize it one by one:

2.2 specific process

2.2.1 create a new Spring Boot project
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.1.4.RELEASE</version>
    <relativePath/> 
</parent>

<groupId>org.ymx</groupId>
<artifactId>go-kafka-log-spring-starter</artifactId>
<version>0.0.1-RELEASE</version>
2.2.2 add dependency
<!--introduce web Dependency, which is used by the custom interceptor below-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--custom starter Required dependencies autoconfigure-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-autoconfigure</artifactId>
</dependency>
<!--custom starter Required dependencies configuration-processor-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-configuration-processor</artifactId>
    <optional>true</optional>
</dependency>
<!-- lombok-->
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <optional>true</optional>
</dependency>
2.2.3 adjusting the project structure

Generally:

  • Delete main startup class
  • Delete test package
  • Delete master profile
2.2.4 custom Configuration class

LogAutoConfig.java

@Configuration
@EnableConfigurationProperties({ConfigProperties.class})
@ConditionalOnProperty(prefix = "go.kafka.log", name = "enable", havingValue = "true")
public class LogAutoConfig {

    @Autowired
    private ConfigProperties configProperties;

    @Bean(name = "logService")
    public LogService getLogService() {
        LogService logService = new LogService();
        logService.setConfigProperties(configProperties);
        return logService;
    }
}

ConfigProperties.java

@Component
@ConfigurationProperties("go.kafka.log")
public class ConfigProperties {
    private String name;

    public String getName() {
        return name;
    }

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

LogService.java

public class LogService {

    private ConfigProperties configProperties;

    public String getName() {
        return configProperties.getName();
    }

    public void setConfigProperties(ConfigProperties configProperties) {
        this.configProperties = configProperties;
    }

    public String hello() {
        return "Hello " + getName() + "!";
    }

}
2.2.5 add spring Factories file that specifies the auto configuration class

spring.factories

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.ymx.log.config.LogAutoConfig
2.2.6 maven install to local warehouse

2.2.7 testing

New Spring Boot project

<dependency>
    <groupId>org.ymx</groupId>
    <artifactId>go-kafka-log-spring-starter</artifactId>
    <version>0.0.1-RELEASE</version>
</dependency>

application.properties

server.port=8888
go.kafka.log.name=Spring Starter
go.kafka.log.enable=true

HelloController.java

@RestController
public class HelloController {

    @Resource
    private LogService logService;

    @GetMapping("/hello")
    public String hello() {
        return logService.hello();
    }
}

Test:

3. Customized Starter implementation interceptor

3.1 writing custom interceptors

@Component
public class LogInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("----------------------"+request.getMethod()+"----------------------");
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("----------------------"+request.getMethod()+"----------------------");
        HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
    }
}

3.2 adding configuration classes to starter

@Configuration
@ConditionalOnProperty(prefix = "go.kafka.log.interception", name = "enable", havingValue = "true")
public class LogInterceptorConfig implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new LogInterceptor())
                .addPathPatterns("/**") ;
    }
}

3.3 the caller adds the content of the configuration file and the main startup class adds comments

Profile:

go.kafka.log.enable=true

Main startup class:

@SpringBootApplication
@ComponentScans(value = {@ComponentScan("org.ymx.log"),@ComponentScan("com.example.demo")})
public class DemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }

}

3.4 testing

Access any url

4. Customize Starter to realize global exception handling

4.1 write starter global exception handling class

@RestControllerAdvice
public class LogAdviceHandler {

    @ExceptionHandler(value = NullPointerException.class)
    public String exceptionHandlerJwt(NullPointerException e) {
        e.printStackTrace();
        return "error----NullPointerException";
    }

    @ExceptionHandler(value = Exception.class)
    public String exceptionHandler(Exception e) {
        e.printStackTrace();
        return "error----Exception";
    }
}

4.2 caller manufacturing exception test

@GetMapping("/ex")
public String ex() {
    String str = null;
    str.equals("2");
    return "22";
}

Test results:

5 summarize several important notes

  • @ConditionalOnProperty(prefix = "go.kafka.log", name = "enable", havingValue = "true")

    Prefix is the prefix in the configuration file,
    Name is the name of the configuration
    havingValue is the ratio to the configured value. When the two values are the same and return true, the configuration class takes effect

  • @EnableConfigurationProperties({ConfigProperties.class})

    Validate @ ConfigurationProperties() annotation

  • @ConfigurationProperties("go.kafka.log")

    See article: https://blog.csdn.net/Mr_YanMingXin/article/details/119249740

  • @ComponentScans(value = {@ComponentScan("org.ymx.log"),@ComponentScan("com.example.demo")})

    The path of the scanned bean. Here is the path of the scanned starter plus the path of the project

Keywords: Java Spring Spring Boot

Added by edgev on Sun, 09 Jan 2022 08:57:18 +0200