springBoot中自定义starter

一、 前言

  在springBoot项目中,我们会发现有各种starter(redis、nacos、mybaits等),我们需要用mybaits,只需引入对应的starter,然后springBoot会自动装配对应的bean到spring容器中。我们直接使用即可,同时会有一些配置,我们可以根据自己的实际情况配置。

  springBoot如何装配所需的类?在实际开发中,我们如何自定义starter呢?本文章将从这两点讲述starter。

二、 springBoot如何装配对应的bean

  首先,我们需要了解一个注解:@SpringBootApplication。在一个springBoot项目中,我们在启动类上都会加上@SpringBootApplication这个注解

@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
		@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {

我们会发现,这个注解相当于@SpringBootConfiguration、@EnableAutoConfiguration、@ComponentScan

  • @SpringBootConfiguration
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration
public @interface SpringBootConfiguration {
    @AliasFor(
        annotation = Configuration.class
    )
    boolean proxyBeanMethods() default true;
}

@SpringBootConfiguration继承自@Configuration,二者功能也一致,标注当前类是配置类,并会将当前类内声明的一个或多个以@Bean注解标记的方法的实例纳入到spring容器中,并且实例名就是方法名。

  • @ComponentScan
    这个类就不用解释,他会讲对应的扫描包下的含有相应注解(@Controller、@Service、@RestController、@Component、@configure、@Repository,简而言之就是含有@Component注解)的类注册到spring容器中
  • @EnableAutoConfiguration
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {

进入@Import(AutoConfigurationImportSelector.class)对应的类->selectImports->getAutoConfigurationEntry->getCandidateConfigurations->loadFactoryNames,我们会发现,他会加载META_INF/spring.facotories中的读取,然后以健值对的形式返回,然后在通过各种条件注解解决类是否装配到容器中。

protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
		if (!isEnabled(annotationMetadata)) {
			return EMPTY_ENTRY;
		}
		AnnotationAttributes attributes = getAttributes(annotationMetadata);
		List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes);
		configurations = removeDuplicates(configurations);
		Set<String> exclusions = getExclusions(annotationMetadata, attributes);
		checkExcludedClasses(configurations, exclusions);
		configurations.removeAll(exclusions);
		configurations = getConfigurationClassFilter().filter(configurations);
		fireAutoConfigurationImportEvents(configurations, exclusions);
		return new AutoConfigurationEntry(configurations, exclusions);
	}

下图是读取spring.facotories文件,然后返回自动装配类的方法
在这里插入图片描述
下图是redis自动装配的类

@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(RedisOperations.class)
@EnableConfigurationProperties(RedisProperties.class)
@Import({ LettuceConnectionConfiguration.class, JedisConnectionConfiguration.class })
public class RedisAutoConfiguration {

	@Bean
	@ConditionalOnMissingBean(name = "redisTemplate")
	public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory)
			throws UnknownHostException {
		RedisTemplate<Object, Object> template = new RedisTemplate<>();
		template.setConnectionFactory(redisConnectionFactory);
		return template;
	}

	@Bean
	@ConditionalOnMissingBean
	public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory)
			throws UnknownHostException {
		StringRedisTemplate template = new StringRedisTemplate();
		template.setConnectionFactory(redisConnectionFactory);
		return template;
	}

}

三、自定义starter

3.1 创建springBoot工程,引入依赖

注意artifactId为xx-spring-boot-starter,同时需要引入下边的依赖到项目中

       <!--自定义starter必须要引入的依赖-->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-actuator-autoconfigure</artifactId>
		</dependency>

3.2 定义相关类

3.2.1 定义配置属性

/**
 * @author luyi
 * starter对应demo的配置属性
 */
@ConfigurationProperties(prefix = "spring.starter",ignoreInvalidFields = true)
public class DemoProperties {
    private String name="luyi";

    public String getName() {
        return name;
    }

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

3.2.2 定义业务以及实现类

/**
 * @author luyi
 */
public interface StarterDemo {

     void welcome();
}
/**
 * @author luyi
 * 定义实现类
 *
 */
public class StarterDemoImpl implements StarterDemo {
    @Autowired
    private DemoProperties demoProperties;

    @Override
    public void welcome() {
        System.out.println(demoProperties.getName()+",欢迎啦");
    }
}

3.2.3 定义配置类

/**
 * @author luyi
 * 自动配置demo类
 */
@Configuration
@ConditionalOnClass
@EnableConfigurationProperties(DemoProperties.class)
public class DemoAutoConfiguration {

    @Bean
    @ConditionalOnMissingBean
    public StarterDemoImpl initDemoImpl(){
       return  new StarterDemoImpl();
    }
    
}

3.3 配置spring.factories

在resources下新建META-INF目录,并在这个目录下添加spring.factories文件,并增加配置

#=后边的根据实际情况配置类的全路径
org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.ly.starter.DemoAutoConfiguration

在这里插入图片描述

3.4 安装install

我们可以用mvn clean install,或者maven选项的安装
在这里插入图片描述

安装完成后,我们会发现本地的maven仓库中会有对应的依赖
在这里插入图片描述

3.5 使用

像平时引入其他的starter一样即可。

@SpringBootApplication
//@EnableScheduling//开启定时
public class TimerApplication implements CommandLineRunner {

	@Autowired
	private StarterDemo starterDemo;

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

	@Override
	public void run(String... args) throws Exception {
		starterDemo.welcome();
	}
}

我们在yml中配置如下:,启动项目

spring:
  starter:
    name: test

控制台输出如下,说明我们starter成功啦引入starter启动图

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值