springboot-自定义starter

在实际业务开发过程当中,有很多公共的功能。针对这些功能,可以自己开发公共的starter模块

命名

对于自己开发的starter模块,一般使用xxx-spring-boot-starter,而spring自己生态圈的starter,一般都是spring-boot-starter-xxx格式命名

maven依赖(pom.xml)

	<!-- 版本自己定 -->
	<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.4.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>

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

属性类

package com.leewan.vue.starter.properties;

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


@ConfigurationProperties(prefix = "leewan.vue")
public class LeewanVueProperties {

    private String rootPath;

    public String getRootPath() {
        return rootPath;
    }

    public void setRootPath(String rootPath) {
        this.rootPath = rootPath;
    }
}

通过@ConfigurationProperties注解,注入属性

配置类(最核心)

package com.leewan.vue.starter.config;

import com.leewan.vue.starter.condition.ConditionalHasProperties;
import com.leewan.vue.starter.controller.LeewanPageController;
import com.leewan.vue.starter.pageContext.ClassPathPageContext;
import com.leewan.vue.starter.pageContext.FilePageContext;
import com.leewan.vue.starter.pageContext.PageContext;
import com.leewan.vue.starter.properties.LeewanVueProperties;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.ResourceUtils;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;

import java.lang.reflect.Method;
import java.net.URL;

@Configuration
//开启LeewanVueProperties配置对象,如不配置,则无法自动注入LeewanVueProperties类
@EnableConfigurationProperties(LeewanVueProperties.class)
//条件注解  
@ConditionalHasProperties(propertyName = "leewan.vue.root-path")
public class LeewanVueConfiguration {

    @Autowired
    private LeewanVueProperties properties;


    @Bean
    public PageContext pageContext() {
        String rootPath = properties.getRootPath();
        if(rootPath.startsWith(ResourceUtils.CLASSPATH_URL_PREFIX)) {
            String path = rootPath.substring(ResourceUtils.CLASSPATH_URL_PREFIX.length());
            URL url = Thread.currentThread().getContextClassLoader().getResource(path);
            if(ResourceUtils.isJarURL(url)) {
                return new ClassPathPageContext(path);
            }else {
                return new FilePageContext(rootPath);
            }
        }else {
            return new FilePageContext(rootPath);
        }
    }

    @Bean("leewanPageController")
    public LeewanPageController pageController(){
        return new LeewanPageController();
    }

    @Bean
    public ApplicationContextAware aware(){
        return new ApplicationContextAware() {
            @Override
            public void setApplicationContext(ApplicationContext application) throws BeansException {
                //手动注册controller
                RequestMappingHandlerMapping handlerMapping = application.getBean(RequestMappingHandlerMapping.class);

                try {
                    Method method=handlerMapping.getClass().getSuperclass().getSuperclass().
                            getDeclaredMethod("detectHandlerMethods",Object.class);
                    method.setAccessible(true);
                    method.invoke(handlerMapping, "leewanPageController");
                } catch (Exception e) {
                    e.printStackTrace();
                }

            }
        };
    }

}


@EnableConfigurationProperties(LeewanVueProperties.class)

表示开启LeewanVueProperties配置对象,否则无法注入LeewanVueProperties对象

后续使用IDE(如idea,eclipse)编辑yml文件时,会根据LeewanVueProperties进行自动提示

条件注解

有些starter虽然引入,但实际运行过程中 需要满足一些特定条件才会运行。所以还需要条件注解来进行判断。springboot自带了很多条件注解,如@ConditionalOnProperty、@ConditionalOnBean等。

但是对于一些比较复杂的业务场景,使用spring自带的条件注解无法满足需求时,我们还可以自定义注解。 自定义注解一般需要两个类,一是注解,一是具体的条件匹配实现类

注解类
package com.leewan.vue.starter.condition;

import org.springframework.context.annotation.Conditional;

//配置条件匹配类
@Conditional(HasPropertiesCondition.class)
public @interface ConditionalHasProperties {

    String propertyName() default "";

}
条件匹配实现类

需要实现org.springframework.context.annotation.Condition类,
通过AnnotatedTypeMetadata可以获取注解类里的一些配置
通过conditionContext可以获取上下文一些配置参数

package com.leewan.vue.starter.condition;

import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.type.AnnotatedTypeMetadata;
import org.springframework.util.StringUtils;

import java.util.Map;


public class HasPropertiesCondition implements Condition {
    @Override
    public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
        Map<String, Object> annotationAttributes = annotatedTypeMetadata.getAnnotationAttributes(ConditionalHasProperties.class.getName());
        String propertyName = (String) annotationAttributes.get("propertyName");
        String property = conditionContext.getEnvironment().getProperty(propertyName);

        if(StringUtils.hasText(property)){
            return true;
        }
        return false;
    }
}

配置文件

最后需要告诉spring 你的这个starter的自动配置类是哪个。通过配置文件进行配置
1、resources目录下 新建META-INF目录
2、新建文件spring.factories
3、在spring.factories中

org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.leewan.vue.starter.config.LeewanVueConfiguration

在这里插入图片描述

一切搞定

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
自定义Spring Boot Starter是一种用于简化Spring Boot应用程序配置和依赖管理的机制。它由几个组件组成,包括starter包、autoconfiguration包和配置文件。 首先,你需要创建一个Maven工程,并创建三个模块。其中,starter包负责引入依赖,autoconfiguration包负责实现装配。在autoconfiguration包中,你需要定义对应的properties类、configuration类和核心业务类。此外,你还需要在autoconfiguration包的/resources/META-INF/目录下添加spring.factories文件,并配置org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.qiejk.demo.springboot.autoconfiguration.DemoAutoConfiguration。这一步是Spring Boot装配的核心,只有添加了这个内容,Spring Boot才会进行自动装配。\[1\] 在父模块的pom文件中,你需要引入Spring Boot的依赖,例如spring-boot-starter-web,以及指定Spring Boot的版本。这样,你的自定义starter模块就可以基于Spring Boot进行开发和使用。\[2\] 最后,你需要创建一个配置文件,用于告诉Spring Boot在启动时扫描该配置文件,并将其中的配置类加载到Spring容器中。这个配置文件的作用是指定自动配置类的位置。\[3\] 通过以上步骤,你就可以创建自定义的Spring Boot Starter,并在应用程序中使用它来简化配置和依赖管理。 #### 引用[.reference_title] - *1* [如何自定义springboot-starter](https://blog.csdn.net/sinat_29434159/article/details/123995794)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [SpringBoot自定义Starter篇](https://blog.csdn.net/m0_46571920/article/details/122910726)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值