热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

如何实现自己的SpringBoot自动配置

SpringBoot基本原理SpringBoot可以帮助我们更好的使用Spring,更快的配置一个可以运行的Spring应用。SpringBoot实现自动配置实现的入

SpringBoot基本原理

SpringBoot可以帮助我们更好的使用Spring,更快的配置一个可以运行的Spring应用。

SpringBoot实现自动配置实现的入口是@EnableAutoConfiguration注解,该注解又通过@Import注解导入了AutoConfigurationImportSelector,在该类中实现了对META-INF/spring.factoriesorg.springframework.boot.autoconfigure.EnableAutoConfiguration属性指定的所有配置,如org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration

//文件:spring-boot-autoconfigure-2.1.3.RELEASE.jar!/META-INF/spring.factories# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\
org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\
org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration,\
org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration,\
org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration,\

在CacheAutoConfiguration中,通过条件注解@ConditionalOnXXX,以及@Import注解来实现对缓存功能的相关Bean的自动配置。

// 文件:spring-boot-autoconfigure-2.1.3.RELEASE-sources.jar!/org/springframework/boot/autoconfigure/cache/CacheAutoConfiguration.java@Configuration
@ConditionalOnClass(CacheManager.class)
@ConditionalOnBean(CacheAspectSupport.class)
@ConditionalOnMissingBean(value = CacheManager.class, name = "cacheResolver")
@EnableConfigurationProperties(CacheProperties.class)
@AutoConfigureAfter({ CouchbaseAutoConfiguration.class, HazelcastAutoConfiguration.class,HibernateJpaAutoConfiguration.class, RedisAutoConfiguration.class })
@Import(CacheConfigurationImportSelector.class)
public class CacheAutoConfiguration {@Bean@ConditionalOnMissingBeanpublic CacheManagerCustomizers cacheManagerCustomizers(ObjectProvider> customizers) {return new CacheManagerCustomizers(customizers.orderedStream().collect(Collectors.toList()));}

实现自己的AutoConfiguration

在实际开发过程中,我们可能需要将公司内部的,或者Spring官方还不支持的第三方类库集成到我们的项目中。但是为了重用,最好能够按照SpringBoot的自动配置来配置。

第一步:引入Spring官方依赖

项目的pom文件:

"1.0" encoding="UTF-8"?>
"http://maven.apache.org/POM/4.0.0" xmlns:xsi&#61;"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation&#61;"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">4.0.0geektime.spring.hellogeektime-spring-boot-autoconfigure0.0.1-SNAPSHOTgeektime-spring-boot-autoconfigureDemo project for Spring Boot1.82.1.3.RELEASEorg.springframework.bootspring-boot-dependencies${spring-boot.version}<type>pomtype>importorg.springframework.bootspring-boot-autoconfiguregeektime.spring.hellogreeting0.0.1-SNAPSHOTprovided

第二步&#xff1a;编写Java Configuration&#xff0c;并添加条件注解

Spring支持的条件注解&#xff1a;

  • 条件注解&#64;Conditional
  • 类条件&#64;ConditionalOnClass&#xff0c;&#64;ConditionalOnMissingClass
  • 属性条件&#64;ConditionalOnProperty
  • Bean 条件&#64;ConditionalOnBean&#xff0c;&#64;ConditionalOnMissingBean&#xff0c;&#64;ConditionalOnSingleCandidate
  • 资源条件&#64;ConditionalOnResource
  • Web 应⽤用条件&#64;ConditionalOnWebApplication&#xff0c;&#64;ConditionalOnNotWebApplication
  • 其他条件&#64;ConditionalOnExpression&#xff0c;&#64;ConditionalOnJava&#xff0c;&#64;ConditionalOnJndi

Java Configuration代码如下&#xff1a;

&#64;Configuration
&#64;ConditionalOnClass(GreetingApplicationRunner.class)
public class GreetingAutoConfiguration {&#64;Bean&#64;ConditionalOnMissingBean(GreetingApplicationRunner.class)&#64;ConditionalOnProperty(name &#61; "greeting.enabled", havingValue &#61; "true", matchIfMissing &#61; true)public GreetingApplicationRunner greetingApplicationRunner() {return new GreetingApplicationRunner();}
}

第三步&#xff1a;定位自动配置

在当前项目的resource目录下的META-INF目录下创建spring.factories文件&#xff0c;内容如下&#xff1a;

org.springframework.boot.autoconfigure.EnableAutoConfiguration&#61;\
geektime.spring.hello.greeting.GreetingAutoConfiguration

第四步&#xff1a;定义自动配置的执行顺序

主要的注解有&#xff1a;

  • &#64;AutoConfigureBefore
  • &#64;AutoConfigureAfter
  • &#64;AutoConfigureOrder

一般不需要&#xff0c;具体使用可以参考Spring官方的自动配置。

如何在不支持SpringBoot的老版本Spring中实现SpringBoot

如果在老版本的Spring中实现类似SpringBoot的自动配置功能&#xff0c;则需要使用Spring的扩展点机制&#xff0c;原理可以参考博文Spring框架的扩展点。

添加一个Configuration&#xff1a;

&#64;Configuration
public class GreetingAutoConfiguration {&#64;Beanpublic static GreetingBeanFactoryPostProcessor greetingBeanFactoryPostProcessor() {return new GreetingBeanFactoryPostProcessor();}
}

自定义一个BeanFactoryPostProcessor实现类似条件注解的功能&#xff1a;

&#64;Slf4j
public class GreetingBeanFactoryPostProcessor implements BeanFactoryPostProcessor {public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {boolean hasClass &#61; ClassUtils.isPresent("geektime.spring.hello.greeting.GreetingApplicationRunner",GreetingBeanFactoryPostProcessor.class.getClassLoader());if (!hasClass) {log.info("GreetingApplicationRunner is NOT present in CLASSPATH.");return;}if (beanFactory.containsBeanDefinition("greetingApplicationRunner")) {log.info("We already have a greetingApplicationRunner bean registered.");return;}register(beanFactory);}private void register(ConfigurableListableBeanFactory beanFactory) {if (beanFactory instanceof BeanDefinitionRegistry) {GenericBeanDefinition beanDefinition &#61; new GenericBeanDefinition();beanDefinition.setBeanClass(GreetingApplicationRunner.class);((BeanDefinitionRegistry) beanFactory).registerBeanDefinition("greetingApplicationRunner",beanDefinition);} else {beanFactory.registerSingleton("greetingApplicationRunner",new GreetingApplicationRunner());}}
}

参考资料
  1. Spring框架的扩展点
  2. Spring全家桶视频课程之SpringBoot
  3. Spring全家桶课程代码



推荐阅读
author-avatar
CHEN--MIN--珊
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有