Home  >  Article  >  Java  >  How to implement SpringBoot SPI mechanism and custom starter

How to implement SpringBoot SPI mechanism and custom starter

WBOY
WBOYforward
2023-05-16 19:58:101519browse

    1. The SPI mechanism in SpringBoot

    What is spi? The full name is Service Provider Interface. In simple translation, it is the service provider interface, which is a mechanism for finding service implementations.

    In fact, it is a standard definition, or an implementation standard.

    To use an example in life, you buy a Xiaomi mobile phone.

    But the charger you use does not have to be a Xiaomi charger. You can use chargers from other manufacturers to charge. As long as it meets the protocol, port and other requirements, then it can be charged. This is also a hot-swappable idea, which is not fixed.

    It’s the same in terms of code. I defined an interface, but I didn’t want to fix the specific implementation class, because if I wanted to change the implementation class, I would have to change the source code, which is often not possible. suitable.

    Then I can also define a specification. When I need to change the implementation class or add other implementation classes later, I will comply with this specification. I can also dynamically discover these implementation classes.

    In SpringBoot, the current SpringBoot platform has defined some norms and standards. Now I want the SpringBoot platform to accept me.

    How should I do it?

    It’s very simple, do things according to its standards and specifications.

    When SpringBoot starts, it will scan all jar packages resource/META-INF/spring.factories files, and use the reflection mechanism to Bean# based on the fully qualified name of the class. ##Load into the container.

    2. Custom starter

    Let me talk about my little practice:

    In this starter, implement

    • Template for sending short lines

    • Template for object storage

    Auto-assembly~

    There are roughly four steps:

    • #The class xxxxProperties used to map the configuration in the configuration file

    • The interface used to operate xxxx and Clients, etc., such as OssTemplate

    • in this article, automatically configure the class xxxxAutoConfiguration, and inject xxxxTemplate

    • into the container in spring.factories Add xxxxAutoConfiguration to the vaule collection of EnableAutoConfiguration

    I use Alibaba Cloud's oss for object storage, and the configurations in it are all available. For text messages, it is a simulation~ , don’t blame me

    How to implement SpringBoot SPI mechanism and custom starter

    2.1. Prepare a Maven project

    Delete the src directory,

    Then create two Maven projects (I personally Habit, accustomed to creating an empty Maven project, in fact the same is true for creating a SpringBoot project)

    How to implement SpringBoot SPI mechanism and custom starter

    The outermost pom.xml

     <parent>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-parent</artifactId>
         <version>2.5.2</version>
         <relativePath/>
     </parent>
    
     <properties>
         <maven.compiler.source>8</maven.compiler.source>
         <maven.compiler.target>8</maven.compiler.target>
     </properties>
    
    
     <dependencies>
         <dependency>
             <groupId>org.projectlombok</groupId>
             <artifactId>lombok</artifactId>
         </dependency>
         <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-web</artifactId>
         </dependency>
         <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter</artifactId>
         </dependency>
         <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-test</artifactId>
         </dependency>
         <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-configuration-processor</artifactId>
             <optional>true</optional>
         </dependency>
     </dependencies>

    2.2. Prepare the Properties class

    is used to map the configuration file~

     /**
      * @author Ning Zaichun
      */
     @Data
     @ConfigurationProperties(prefix = "nzc.oss")
     public class OssProperties {
    
         private String accessKey; 
         private String secret;
         private String bucketName;
         private String url;
         private String endpoint;
     }
     @Data
     @ConfigurationProperties(prefix = "nzc.sms")
     public class SmsProperties {
    
         private String name;
     }

    2.3. Prepare the class to be injected

    is the class we will finally inject into the SpringBoot operation through automatic assembly

    My here are OssTemplate and SmsTemplate

     /**
      * @author Ning Zaichun
      */
     public class OssTemplate {
    
         private OssProperties ossProperties;
    
         public OssTemplate(OssProperties ossProperties) {
             this.ossProperties = ossProperties;
         }
    
         public String test() {
             System.out.println(ossProperties.getBucketName());
             return "test";
         }
         public String upload(String filename, InputStream is) {
             // yourEndpoint填写Bucket所在地域对应的Endpoint。以华东1(杭州)为例,Endpoint填写为https://oss-cn-hangzhou.aliyuncs.com。
             String endpoint = ossProperties.getEndpoint();
             // 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建RAM账号。
             String accessKeyId = ossProperties.getAccessKey();
             String accessKeySecret = ossProperties.getSecret();
    
             // 创建OSSClient实例。
             OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
    
             String storePath = new SimpleDateFormat("yyyy/MM/dd").format(new Date()) + "/" + UUID.randomUUID() + filename.substring(filename.lastIndexOf("."));
    
             System.out.println(storePath);
             // 依次填写Bucket名称(例如examplebucket)和Object完整路径(例如exampledir/exampleobject.txt)。Object完整路径中不能包含Bucket名称。
             ossClient.putObject(ossProperties.getBucketName(), storePath, is);
    
             String url = ossProperties.getUrl() + storePath;
    
             // 关闭OSSClient。
             ossClient.shutdown();
             return url + "#" + storePath;
        }
    
         public void remove(String fileUrl) {
             // yourEndpoint填写Bucket所在地域对应的Endpoint。以华东1(杭州)为例,Endpoint填写为https://oss-cn-hangzhou.aliyuncs.com。
             String endpoint = ossProperties.getEndpoint();
             // 阿里云账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM用户进行API访问或日常运维,请登录RAM控制台创建RAM用户。
             String accessKeyId = ossProperties.getAccessKey();
             String accessKeySecret = ossProperties.getSecret();
             // 填写Bucket名称。
             String bucketName = ossProperties.getBucketName();
             // 填写文件完整路径。文件完整路径中不能包含Bucket名称。
             //2022/01/21/f0870eb3-4714-4fae-9fc3-35e72202f193.jpg
             String objectName = fileUrl;
    
             // 创建OSSClient实例。
             OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
    
             // 删除文件或目录。如果要删除目录,目录必须为空。
             ossClient.deleteObject(bucketName, objectName);
    
             // 关闭OSSClient。
             ossClient.shutdown();
         }
     }
     public class SmsTemplate {
    
         private SmsProperties properties;
    
         public SmsTemplate(SmsProperties properties) {
             this.properties = properties;
         }
    
         public void sendSms(String mobile, String code){
             System.out.println(properties.getName()+"=="+mobile+"===="+code);
         }
     }

    2.4, AutoConfiguration

     @EnableConfigurationProperties({
         SmsProperties.class,
         OssProperties.class
             })
     public class CommonAutoConfig {
    
         @Bean
         public SmsTemplate smsTemplate(SmsProperties smsProperties){
             return new SmsTemplate(smsProperties);
         }
    
         @Bean
         public OssTemplate ossTemplate(OssProperties ossProperties){
             return new OssTemplate(ossProperties);
         }
    
     }

    2.5, write spring.factories

    In the resource directory, create a META-INF file folder,

    Create a spring.factories file under the META-INF folder

    The content is

     org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
       com.nzc.CommonAutoConfig

    If there are multiple ones:

     org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
       com.nzc.CommonAutoConfig \
       com.xxx.xxx

    How to implement SpringBoot SPI mechanism and custom starter

    After reaching this step, we will create a Jar package for this project, and then introduce it into the project to be used.

    How to implement SpringBoot SPI mechanism and custom starter

    2.6. Application Test

    • #1. Create a SpringBoot startup class. Testing can only be done if there is a startup class, otherwise there will be no context. Environment~

    • 2. Write the configuration file

    •  spring:
         application:
           name: app-server
       nzc:
         sms:
           name: ningzaichun
         oss:
           accessKey: xxx
           secret: xxx
           endpoint: oss-cn-shenzhen.aliyuncs.com
           bucketName: xxx
           url: xxx
    It can be used if you modify the oss configuration correctly~

    Write test class:

     @RunWith(SpringRunner.class)
     @SpringBootTest(classes = AppServerApplication.class)
     public class TemplateTest {
    
         @Autowired
         private OssTemplate ossTemplate;
         @Test
         public void testOss(){
             String s = ossTemplate.test();
             System.out.println(s);
         }
         @Test
         public void testUpload(){
             try {
                 File file = new File("D:\evectionflow01.png");
                 InputStream inputStream = new FileInputStream(file);
                 ossTemplate.upload("123.jpg",inputStream);
             } catch (FileNotFoundException e) {
                 e.printStackTrace();
             }
         }
         @Autowired
         private SmsTemplate smsTemplate;
    
         @Test
         public void testSendSms(){
             smsTemplate.sendSms("17670090715","123456");
         }
     }

    Prove that it can be used~

    How to implement SpringBoot SPI mechanism and custom starter

    The above is the detailed content of How to implement SpringBoot SPI mechanism and custom starter. For more information, please follow other related articles on the PHP Chinese website!

    Statement:
    This article is reproduced at:yisu.com. If there is any infringement, please contact admin@php.cn delete