技术标签: Spring Boot自动配置 java Spring Spring Boot自动配置原理、实战
原创: javastack Java技术栈 Java技术栈
微信号 javastack
功能介绍 专注分享Java技术干货,包括多线程、JVM、Spring Boot、Spring Cloud、Intellij IDEA、Dubbo、Zookeeper、Redis、架构设计、微服务、消息队列、Git、面试题、程序员攻略、最新动态等。
2017-09-11
Spring Boot的自动配置注解是@EnableAutoConfiguration, 从上面的@Import的类可以找到下面自动加载自动配置的映射。
org.springframework.core.io.support.SpringFactoriesLoader.loadFactoryNames(Class<?>, ClassLoader)
public static List<String> loadFactoryNames(Class<?> factoryClass, ClassLoader classLoader) {
String factoryClassName = factoryClass.getName();
try {
Enumeration<URL> urls = (classLoader != null ? classLoader.getResources(FACTORIES_RESOURCE_LOCATION) :
lassLoader.getSystemResources(FACTORIES_RESOURCE_LOCATION));
List<String> result = new ArrayList<String>();
while (urls.hasMoreElements()) {
URL url = urls.nextElement();
Properties properties = PropertiesLoaderUtils.loadProperties(new UrlResource(url));
String factoryClassNames = properties.getProperty(factoryClassName);
result.addAll(Arrays.asList(StringUtils.commaDelimitedListToStringArray(factoryClassNames)));
}
return result;
}
catch (IOException ex) {
throw new IllegalArgumentException("Unable to load [" + factoryClass.getName() +
"] factories from location [" + FACTORIES_RESOURCE_LOCATION + "]", ex);
}
}
这个方法会加载类路径及所有jar包下META-INF/spring.factories配置中映射的自动配置的类。
/**
* The location to look for factories.
* <p>Can be present in multiple JAR files.
*/
public static final String FACTORIES_RESOURCE_LOCATION = "META-INF/spring.factories";
查看Spring Boot自带的自动配置的包: spring-boot-autoconfigure-1.5.6.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,\
org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration,\
org.springframework.boot.autoconfigure.cloud.CloudAutoConfiguration,\
...
再来看看数据源自动配置的实现注解
@Configuration
@ConditionalOnClass({ DataSource.class, EmbeddedDatabaseType.class })
@EnableConfigurationProperties(DataSourceProperties.class)
@Import({ Registrar.class, DataSourcePoolMetadataProvidersConfiguration.class })
public class DataSourceAutoConfiguration {
...
@Configuration,@ConditionalOnClass就是自动配置的核心,首先它得是一个配置文件,其次根据类路径下是否有这个类去自动配置。
所以,了解了自动配置的原理,来自己实现一个自动配置的玩意其实很简单。
添加配置类:
import org.slf4j.Logger;
import org.springframework.context.EnvironmentAware;
import org.springframework.core.env.Environment;
import com.oceanpayment.common.utils.logger.LoggerUtils;
public class EnvConfig implements EnvironmentAware {
private final Logger logger = LoggerUtils.getLogger(this);
private Environment env;
public String getStringValue(String key) {
return env.getProperty(key);
}
public Long getLongValue(String key) {
String value = getStringValue(key);
try {
return Long.parseLong(value);
} catch (Exception e) {
logger.error("字符串转换Long失败:{} = {}", key, value);
}
return 0L;
}
public int getIntValue(String key) {
return getLongValue(key).intValue();
}
@Override
public void setEnvironment(Environment environment) {
this.env = environment;
}
}
添加自动配置类:
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.PropertyResolver;
@Configuration
@ConditionalOnClass(PropertyResolver.class)
public class EnvAutoConfig {
@Bean
public EnvConfig envConfig() {
return new EnvConfig();
}
}
创建META-INF/spring.factories文件,添加自动配置映射:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\\
com.oceanpayment.common.config.env.EnvAutoConfig
这样就搞定了。
怎么查看自己加的自动配置类有没有被加载,或者查看所有自动配置激活的和未激活的可以通过以下几种试查看。
spring-boot:run运行的在对话框Enviroment中加入debug=true变量
java -jar xx.jar --debug
main方法运行,在VM Argumanets加入-Ddebug
直接在application文件中加入debug=true
如果集成了spring-boot-starter-actuator监控,通过autoconfig端点也可以查看。
启动后会在控制台看到以下自动配置报告信息:
=========================
AUTO-CONFIGURATION REPORT
=========================
Positive matches:
-----------------
AopAutoConfiguration matched:
- @ConditionalOnClass found required classes 'org.springframework.context.annotation.EnableAspectJAutoProxy', 'org.aspectj.lang.annotation.Aspect', 'org.aspectj.lang.reflect.Advice'; @ConditionalOnMissingClass did not find unwanted class (OnClassCondition)
- @ConditionalOnProperty (spring.aop.auto=true) matched (OnPropertyCondition)
...
EnvAutoConfig matched:
- @ConditionalOnClass found required class 'org.springframework.core.env.PropertyResolver'; @ConditionalOnMissingClass did not find unwanted class (OnClassCondition)
ErrorMvcAutoConfiguration matched:
- @ConditionalOnClass found required classes 'javax.servlet.Servlet', 'org.springframework.web.servlet.DispatcherServlet'; @ConditionalOnMissingClass did not find unwanted class (OnClassCondition)
- @ConditionalOnWebApplication (required) found StandardServletEnvironment (OnWebApplicationCondition)
ErrorMvcAutoConfiguration#basicErrorController matched:
- @ConditionalOnMissingBean (types: org.springframework.boot.autoconfigure.web.ErrorController; SearchStrategy: current) did not find any beans (OnBeanCondition)
...
Negative matches:
-----------------
ActiveMQAutoConfiguration:
Did not match:
- @ConditionalOnClass did not find required classes 'javax.jms.ConnectionFactory', 'org.apache.activemq.ActiveMQConnectionFactory' (OnClassCondition)
AopAutoConfiguration.JdkDynamicAutoProxyConfiguration:
Did not match:
- @ConditionalOnProperty (spring.aop.proxy-target-class=false) found different value in property 'proxy-target-class' (OnPropertyCondition)
ArtemisAutoConfiguration:
Did not match:
- @ConditionalOnClass did not find required classes 'javax.jms.ConnectionFactory', 'org.apache.activemq.artemis.jms.client.ActiveMQConnectionFactory' (OnClassCondition)
BatchAutoConfiguration:
Did not match:
- @ConditionalOnClass did not find required class 'org.springframework.batch.core.launch.JobLauncher' (OnClassCondition)
...
Positive matches:已经启用的自动配置
Negative matches:未启用的自动配置
从报告中看到自己添加的EnvAutoConfig已经自动配置了。
文章浏览阅读785次,点赞15次,收藏14次。Java线程池中子线程出现死循环是并发编程中常见的问题,其识别与解决需结合代码审查、异常处理、超时机制、中断支持、守护线程或线程池监控等多种策略。通过严谨的编码实践、合理的超时设定、灵活的中断响应、以及有效的监控手段,可以有效预防和处理此类问题,保障系统的稳定性和资源的有效利用。在实际应用中,应根据具体业务场景选择合适的解决方案,甚至综合运用多种策略以提高系统的健壮性和自我修复能力。
文章浏览阅读296次。第一款:iis7服务器管理软件iis7远程桌面管理软件,是一款绿色小巧,功能实用的FTP工具软件,其界面简洁,操作方便,它支持FTP批量上传下载,它可以同时连接多台ftp服务器进行文件传输工作,还可以在线解压缩文件,支持文件查找,在线编辑等功能。同时它还能够同时远程操作多台服务器,并且多台服务器间可以自由切换,适合机房管理、站长、运维工作、程序员使用。适用于Windows系统,Linux系统和VPS服务器等。在众多好用实用的功能当中,最大的亮点还是属定时上传下载的强大功能了,它可以定时备份,自动更新等,_ftp 工具精简绿色
文章浏览阅读165次。摘自:http://www.cnblogs.com/pinard/p/7160330.html先看下列三篇,再理解此篇会更容易些(个人意见)skip-gram,CBOW,Word2Vec词向量基础CBOW与Skip-Gram用于神经网络语言模型词向量基础用词向量来表示词并不是word2vec的首创,在很久之前就出现了。最早的词向量是很冗长的,它使用是词向..._使用skipgram会导致内存不够
文章浏览阅读144次。之前发牢骚说AndEngine中的Text对象有个很头疼的问题,目前已经解决原因如下:个人理解~同字体字符类型使用过多,如英文字母,数字,符号字符,中文字符都需要显示的话,需要占用更大的纹理存储空间,而纹理空间声明的太小,保存不下所有的字符,所以有很多字符显示不出来。。解决方法:增加字体的纹理大小Code:[code="java"]mFontTexture = ...
文章浏览阅读1.4k次,点赞17次,收藏18次。光伏预测是光伏发电系统稳定运行和电网安全的重要保障。本文提出了一种基于开普勒算法优化注意力机制卷积神经网络结合双向门控循环单元(KOA-Attention-CNN-biGRU)的光伏预测模型。该模型通过开普勒算法优化注意力机制,增强了模型对光伏时间序列数据的局部特征提取能力;同时,结合双向门控循环单元,充分利用了光伏时间序列数据的长期依赖关系,提高了预测精度。在北神山光伏电站实际数据上的实验结果表明,所提出的模型在预测精度和鲁棒性方面均优于传统的光伏预测模型。引言。_cnn-bigru-msa koa
文章浏览阅读783次。Python是一种跨平台的计算机程序设计语言。是一个高层次的结合了解释性、编译性、互动性和面向对象的脚本语言。最初被设计用于编写自动化脚本(shell),随着版本的不断更新和语言新功能的添加,越多被用于独立的、大型项目的开发。Python OS模块是负责程序与操作系统的交互,提供了访问操作系统底层的接口和非常丰富的方法用来处理文件和目录。Python contextlib模块提供了一种方便的方式来管理上下文管理器(context manager),它可以帮助我们简化代码,提高可读性和可维护性。_yolov5 profile
文章浏览阅读1.1k次。网上关于反射枚举的案例似乎不多,也许是因为枚举在java里面枚举类型其实算个准类了,java编译的时候同样会生成一个enumname.Class文件,同时Enum是可以被子类直接继承的,所以有时候在反编译的时候反过跟头,掉过阴沟,真的坐船翻船,坐车爆胎,走路都要被石头绊倒的郁闷.同样也是证明不懂java基本知识,后果很严重!!!今天还是靠公司同事提醒了一下,发现枚举类型具有类的一些特性,虽然后_android 反射枚举
文章浏览阅读4.5k次。读 2018年IEEE/ACM TON论文LBP:Robust Rate Adaptation Algorithm for SVC Video StreamingTip:思考问题的流程1.视频流视频流是指视频数据的传输,例如,它能够被作为一个稳定的和连续的流通过网络处理。因为流动,客户机浏览器或插件能够在整个文件被传输完成前显示多媒体数据。视频流技术基于 密钥技术,视频译码技术和可升级的视..._视频流
文章浏览阅读4.4w次,点赞21次,收藏109次。https://www.cnblogs.com/liugp/p/10509123.htmlui->tableWidget_1->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);ui->tableWidget_1->horizontalHeader()->setSectionResi..._setsectionresizemode
文章浏览阅读205次。同步函数--卖票示例同步函数用是哪一个锁呢??---this函数需要被对象调用。那么函数都有一个所属对象引用。就是this。通过该程序进行验证。使用两个线程来卖票。一个线程在同步函数中,一个在同步代码块中。都在执行卖票动作。class Ticket2 implements Runnable //extends Thread{ private in_线程同步 解决之道是什么
文章浏览阅读2k次,点赞2次,收藏6次。这里写自定义目录标题注册企业微信shell脚本发送微信,代码全文如下,zabbix-server后台配置 Media types后台配置 Triggers配置报警信息接收人配置达到报警给指定人发微信注册企业微信打开企业微信注册页面,发下图,选择“立即注册”根据页面要求,填写相关信息后,进入管理页面,选择 “应用管理”拉到页面下方,选择 “自建”-“新建应用”应用建立完成后,打开 “我的企业”拉到页面最下方,查看“企业ID”,脚本需要用到这个参数然后再打开 “应用管理”拉到页面_shell脚本执行alertsend
文章浏览阅读1.2w次。查看服务器是否配置RAID以及HP RAID详情 有时候新接手维护服务器,或者在考虑当前服务器容灾备份机制时,首先得知道服务器到底是否存在RAID卡,是否已经配置RAID。最简单的方式就是重启服务器,然后根据提示查看相关信息。但很多情况下不能随便重启机器,那么我们可以通过特定的操作系统命令,或者查看相关日志得到该信息。注:此处讨论的是硬件RAID,不包括软件RAID1、查看硬件是否支持RAID:# lspci | grep RAID 02:00.0 RAID bus controller: Hew_raid bus controller