我们在使用spring-boot的时候会发现这个框架用起来是真的非常的简单,我们只需要在它的一个名为application的外化配置文件中配一些私人化的属性,其他一些比较公共的配置都消失了,这其中就是spring-boot的自动配置功能在起作用。
当我们留意到spring-boot的依赖的时候我们会发现,spring本身支持的一些主流框架的的artifactId的名字一般叫spring-boot-starter-xxx,而一些spring-boot官方没做支持的一些框架为了能够使用spring-boot这个框架自身做了相关的支持,例如我们常用的持久层框架mybatis为了能在spring-boot里使用,本身就提供了一个叫mybatis-spring-boot-starter的依赖,这个共有的starter就是实现自动配置的关键。
我们在ssm框架中整合mybatis框架是如果你是使用的java配置类的方式来整合的话,需要配置数据源,和一个sqlSessionFactoryBean的这样一个bean,而到了spring-boot中则不再需要去配置相关的一些东西,并不是这些配置就消失了,而是说spring的自动配置帮你做了这些工作。下面本文会解释一下mybatis-plus的自动实现的过程,之后会提供自己写一个实现快递查询的的依赖和他的starter。
spring-boot 会扫描读取依赖中位于resources里的 META-INF/spring.factories文件,我们找到mybatis-plus-boot-starter的这个文件

点开之后我们会看到这样一个文件

# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.baomidou.mybatisplus.autoconfigure.MybatisPlusAutoConfiguration

这个文件的的代码上面一行是由spring提供的,EnableAutoConfiguration,简单的翻译就是说能够自动配置的文件路径,后``面则是一个文件的全路径,接着点开

@Configuration
@ConditionalOnClass({SqlSessionFactory.class, SqlSessionFactoryBean.class})
@ConditionalOnSingleCandidate(DataSource.class)
@EnableConfigurationProperties({MybatisPlusProperties.class})
@AutoConfigureAfter({DataSourceAutoConfiguration.class})
public class MybatisPlusAutoConfiguration implements InitializingBean {private static final Logger logger = LoggerFactory.getLogger(MybatisPlusAutoConfiguration.class);private final MybatisPlusProperties properties;private final Interceptor[] interceptors;private final TypeHandler[] typeHandlers;private final LanguageDriver[] languageDrivers;private final ResourceLoader resourceLoader;private final DatabaseIdProvider databaseIdProvider;private final List<ConfigurationCustomizer> configurationCustomizers;private final List<MybatisPlusPropertiesCustomizer> mybatisPlusPropertiesCustomizers;private final ApplicationContext applicationContext;

我们会看到这个类上的五个注解:
第一个是标注这个类是一个配置类,第二第三个注解的意思是spring中引用了里面的文件才会生成这个bean,第四个注解这是支出要引入的字段的位置,第五个注解是说在加载配置的类之后再加载当前类。接着我们点开第四个注解后面的文件

@ConfigurationProperties(prefix = "mybatis-plus"
)
public class MybatisPlusProperties {private static final ResourcePatternResolver resourceResolver = new PathMatchingResourcePatternResolver();private String configLocation;private String[] mapperLocations = new String[]{"classpath*:/mapper/**/*.xml"};private String typeAliasesPackage;private Class<?> typeAliasesSuperType;private String typeHandlersPackage;private boolean checkConfigLocation = false;private ExecutorType executorType;private Class<? extends LanguageDriver> defaultScriptingLanguageDriver;private Properties configurationProperties;

这个类里面只有一个注解标明了,这个类回去读取,外化配置文件中以什么开头的那些配置,这里是说这个类回去读取application.yml或者application.properties文件中以mybatis-plus开头的配置,这个类里面的字段大家看上去很眼熟了,就是我们ssm中集成mybatis需要配置的一些配置了,有的是写死的是因为spring有一个理念叫做约定优于配置,有些东西必须要放在那个地方,所以这些东西大家都一样,所以就不需要设置了,但有些东西,比如你连接数据库的一些url,root,password还有你自己建的项目结构各有不同,所以集中放在了application.yml或者application.properties文件中,这就是spring-boot的另一个特点,外化配置。最后我们看一下yml的配置

mybatis-plus:mapper-locations: classpath:mappers/**/*.xmlconfiguration:map-underscore-to-camel-case: truelog-impl: org.apache.ibatis.logging.slf4j.Slf4jImpltype-aliases-package: com.woniuxy.boot.mybatisplusdemo.model

这些以mybatis-plus:开头的配置就会被填入文件,这样才完成了对你的mybatis的集成。
下面是一个自己写一个能接入spring-boot的快递查询的项目,具体的细节就不多赘述,只是说让自己亲身体会一下这个过程的实现。
类似于spring-boot依赖mybatis-plus-boot-starter,mybatis-plus-boot-starter再依赖于mybatis-plus,这样的结构,我们先写一个kuaidiniao的项目安装到本地仓库,我们只需创建一个quickstart的mvn项目,无需添加任何依赖,只需写三个java类

package com.woniuxy.tool;public class ExprsTrackConfig {/*** 用户key*/private String userKey;/*** 用户密码*/private String userSecret;/*** 请求地址*/private String apiUrl;public String getUserKey() {return userKey;}public void setUserKey(String userKey) {this.userKey = userKey;}public String getUserSecret() {return userSecret;}public void setUserSecret(String userSecret) {this.userSecret = userSecret;}public String getApiUrl() {return apiUrl;}public void setApiUrl(String apiUrl) {this.apiUrl = apiUrl;}
}
package com.woniuxy.tool;import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.security.MessageDigest;
import java.util.HashMap;
import java.util.Map;/**** 快递鸟物流轨迹即时查询接口** @技术QQ群: 456320272* @see: http://www.kdniao.com/YundanChaxunAPI.aspx* @copyright: 深圳市快金数据技术服务有限公司** DEMO中的电商ID与私钥仅限测试使用,正式环境请单独注册账号* 单日超过500单查询量,建议接入我方物流轨迹订阅推送接口** ID和Key请到官网申请:http://www.kdniao.com/ServiceApply.aspx*/
public class KuaiDiNiaoQueryAPI {//电商IDprivate String EBusinessID;//电商加密私钥,快递鸟提供,注意保管,不要泄漏private String AppKey;//请求urlprivate String ReqURL;public KuaiDiNiaoQueryAPI(ExprsTrackConfig config){this.EBusinessID=config.getUserKey();this.AppKey=config.getUserSecret();this.ReqURL=config.getApiUrl();}/*** Json方式 查询订单物流轨迹* @param expCode  物流公司的编码* @param expNo    物流号* @return 查询结果* @throws Exception*/public String getOrderTracesByJson(String expCode, String expNo) throws Exception{String requestData= "{'OrderCode':'','ShipperCode':'" + expCode + "','LogisticCode':'" + expNo + "'}";Map<String, String> params = new HashMap<String, String>();params.put("RequestData", urlEncoder(requestData, "UTF-8"));params.put("EBusinessID", EBusinessID);params.put("RequestType", "1002");String dataSign=encrypt(requestData, AppKey, "UTF-8");params.put("DataSign", urlEncoder(dataSign, "UTF-8"));params.put("DataType", "2");String result=sendPost(ReqURL, params);//根据公司业务处理返回的信息......return result;}/*** MD5加密* @param str 内容* @param charset 编码方式* @throws Exception*/@SuppressWarnings("unused")private String MD5(String str, String charset) throws Exception {MessageDigest md = MessageDigest.getInstance("MD5");md.update(str.getBytes(charset));byte[] result = md.digest();StringBuffer sb = new StringBuffer(32);for (int i = 0; i < result.length; i++) {int val = result[i] & 0xff;if (val <= 0xf) {sb.append("0");}sb.append(Integer.toHexString(val));}return sb.toString().toLowerCase();}/*** base64编码* @param str 内容* @param charset 编码方式* @throws UnsupportedEncodingException*/private String base64(String str, String charset) throws UnsupportedEncodingException {String encoded = base64Encode(str.getBytes(charset));return encoded;}@SuppressWarnings("unused")private String urlEncoder(String str, String charset) throws UnsupportedEncodingException{String result = URLEncoder.encode(str, charset);return result;}/*** 电商Sign签名生成* @param content 内容* @param keyValue Appkey* @param charset 编码方式* @throws UnsupportedEncodingException ,Exception* @return DataSign签名*/@SuppressWarnings("unused")private String encrypt (String content, String keyValue, String charset) throws UnsupportedEncodingException, Exception{if (keyValue != null){return base64(MD5(content + keyValue, charset), charset);}return base64(MD5(content, charset), charset);}/*** 向指定 URL 发送POST方法的请求* @param url 发送请求的 URL* @param params 请求的参数集合* @return 远程资源的响应结果*/@SuppressWarnings("unused")private String sendPost(String url, Map<String, String> params) {OutputStreamWriter out = null;BufferedReader in = null;StringBuilder result = new StringBuilder();try {URL realUrl = new URL(url);HttpURLConnection conn =(HttpURLConnection) realUrl.openConnection();// 发送POST请求必须设置如下两行conn.setDoOutput(true);conn.setDoInput(true);// POST方法conn.setRequestMethod("POST");// 设置通用的请求属性conn.setRequestProperty("accept", "*/*");conn.setRequestProperty("connection", "Keep-Alive");conn.setRequestProperty("user-agent","Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");conn.connect();// 获取URLConnection对象对应的输出流out = new OutputStreamWriter(conn.getOutputStream(), "UTF-8");// 发送请求参数if (params != null) {StringBuilder param = new StringBuilder();for (Map.Entry<String, String> entry : params.entrySet()) {if(param.length()>0){param.append("&");}param.append(entry.getKey());param.append("=");param.append(entry.getValue());//System.out.println(entry.getKey()+":"+entry.getValue());}//System.out.println("param:"+param.toString());out.write(param.toString());}// flush输出流的缓冲out.flush();// 定义BufferedReader输入流来读取URL的响应in = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8"));String line;while ((line = in.readLine()) != null) {result.append(line);}} catch (Exception e) {e.printStackTrace();}//使用finally块来关闭输出流、输入流finally{try{if(out!=null){out.close();}if(in!=null){in.close();}}catch(IOException ex){ex.printStackTrace();}}return result.toString();}private static char[] base64EncodeChars = new char[] {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H','I', 'J', 'K', 'L', 'M', 'N', 'O', 'P','Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X','Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f','g', 'h', 'i', 'j', 'k', 'l', 'm', 'n','o', 'p', 'q', 'r', 's', 't', 'u', 'v','w', 'x', 'y', 'z', '0', '1', '2', '3','4', '5', '6', '7', '8', '9', '+', '/' };public static String base64Encode(byte[] data) {StringBuffer sb = new StringBuffer();int len = data.length;int i = 0;int b1, b2, b3;while (i < len) {b1 = data[i++] & 0xff;if (i == len){sb.append(base64EncodeChars[b1 >>> 2]);sb.append(base64EncodeChars[(b1 & 0x3) << 4]);sb.append("==");break;}b2 = data[i++] & 0xff;if (i == len){sb.append(base64EncodeChars[b1 >>> 2]);sb.append(base64EncodeChars[((b1 & 0x03) << 4) | ((b2 & 0xf0) >>> 4)]);sb.append(base64EncodeChars[(b2 & 0x0f) << 2]);sb.append("=");break;}b3 = data[i++] & 0xff;sb.append(base64EncodeChars[b1 >>> 2]);sb.append(base64EncodeChars[((b1 & 0x03) << 4) | ((b2 & 0xf0) >>> 4)]);sb.append(base64EncodeChars[((b2 & 0x0f) << 2) | ((b3 & 0xc0) >>> 6)]);sb.append(base64EncodeChars[b3 & 0x3f]);}return sb.toString();}
}
package com.woniuxy.tool;public enum ShipperEnum {SF("顺丰速运","SF"),HTKY("百世快递","HTKY"),ZTO("中通快递","ZTO"),STO("申通快递","STO"),YTO("圆通速递","YTO"),YD("韵达速递","YD"),EMS("EMS","EMS"),HHTT("天天快递","HHTT"),JD("京东快递","JD"),UC("优速快递","UC"),DBL("德邦快递","DBL"),ZJS("宅急送","ZJS");private String name;private String code;ShipperEnum(String name,String code){this.name=name;this.code=code;}}

这里是一些支持查询的快递公司。然后直接安装即可
然后写一个kuaidiniao-spring-boot-starter的项目
同样的是新建一个quickstart的mvn项目,这里需要导入一些spring-boot相关的依赖,才能使用spring-boot提供的注解,让自己的文件被扫描到,先贴依赖`

org.springframework.boot
spring-boot-starter
${spring-boot.version}

    <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot</artifactId><version>${spring-boot.version}</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-autoconfigure</artifactId><version>${spring-boot.version}</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-configuration-processor</artifactId><version>${spring-boot.version}</version><optional>true</optional></dependency><dependency><groupId>com.woniuxy.tool</groupId><artifactId>kuaidiniao</artifactId><version>1.0-SNAPSHOT</version></dependency>

`
最后一个是之前写的kuaidiniao的依赖也要导进来,参照mybatis-plus的做法,我们在先写两个java类

package com.woniuxy.tool.config;import com.woniuxy.tool.ExprsTrackConfig;
import com.woniuxy.tool.KuaiDiNiaoQueryAPI;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration//标记配置类
@EnableConfigurationProperties(KuaidiniaoProperties.class)//关联一个属性类
public class KuaidiniaoAutoConfiguration {//外化配置读入该配置属性类@Autowiredprivate  KuaidiniaoProperties kuaidiniaoProperties;@Beanpublic KuaiDiNiaoQueryAPI kuaiDiNiaoQueryAPI(){ExprsTrackConfig config = new ExprsTrackConfig();config.setApiUrl(kuaidiniaoProperties.getApiUrl());config.setUserKey(kuaidiniaoProperties.getUserKey());config.setUserSecret(kuaidiniaoProperties.getUserSecret());KuaiDiNiaoQueryAPI api = new KuaiDiNiaoQueryAPI(config);return api;}}
package com.woniuxy.tool.config;import org.springframework.boot.context.properties.ConfigurationProperties;@ConfigurationProperties(prefix = "kuaidiniao")
public class KuaidiniaoProperties {/*** 用户key*/private String userKey;/*** 用户密码*/private String userSecret;/*** 请求地址*/private String apiUrl;public String getUserKey() {return userKey;}public void setUserKey(String userKey) {this.userKey = userKey;}public String getUserSecret() {return userSecret;}public void setUserSecret(String userSecret) {this.userSecret = userSecret;}public String getApiUrl() {return apiUrl;}public void setApiUrl(String apiUrl) {this.apiUrl = apiUrl;}
}

然后非常重要的一点,我们在resources里新建一个名为META-INF的文件夹,里面建一个spring.factories的文件写上我们之前看到的类似的代码,指向我们自己写的自动配置类

# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.woniuxy.tool.config.KuaidiniaoAutoConfiguration

这些写完之后,安装到本地即可。
最后新建一个spring-boot的项目,在application文件中写上kuaidiniao使用所需的url,user-key,user-secret

kuaidiniao:api-url: http://api.kdniao.com/Ebusiness/EbusinessOrderHandle.aspxuser-key: 1663user-secret: 0d253737-fc22-4064-87cd-

里面的key和secret都修改过,需要使用可以自己去网址申请http://www.kdniao.com/ServiceApply.aspx
然后调用即可

package com.woniuxy.boot.mybatisplusdemo.controller;import com.woniuxy.tool.KuaiDiNiaoQueryAPI;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
public class KuaiDiNiaoTestController {@Autowiredprivate KuaiDiNiaoQueryAPI api;@GetMapping("/kuaidi")public String getKuaidi(String expCode,String expNo) throws Exception {return api.getOrderTracesByJson(expCode,expNo);}}

开服,按照之前的 SF(“顺丰速运”,“SF”),
HTKY(“百世快递”,“HTKY”),
ZTO(“中通快递”,“ZTO”),
STO(“申通快递”,“STO”),
YTO(“圆通速递”,“YTO”),
YD(“韵达速递”,“YD”),
EMS(“EMS”,“EMS”),
HHTT(“天天快递”,“HHTT”),
JD(“京东快递”,“JD”),
UC(“优速快递”,“UC”),
DBL(“德邦快递”,“DBL”),
ZJS(“宅急送”,“ZJS”);使用restfultool,即可完成测试。

spring-boot自动配置的原理及实现相关推荐

  1. springboot自动配置原理_今日份学习之Spring Boot自动配置实现原理

    通过前面章节的学习,我们掌握了使用Spring Boot框架进行实际应用开发的方法.在使用Spring Boot 的过程中,我们时常会为一些看似简单,但实际上蕴藏了强大功能的实现而惊呼,下面就让我们来 ...

  2. Spring Boot 自动配置的原理、核心注解以及利用自动配置实现了自定义 Starter 组件

    本章内容 自定义属性快速入门 外化配置 自动配置 自定义创建 Starter 组件 摘录:读书是读完这些文字还要好好用心去想想,写书也一样,做任何事也一样 图 2 第二章目录结构图 第 2 章 Spr ...

  3. Spring boot 自动配置工作原理

    自动配置工作原理

  4. Spring Boot - 自动配置实现原理

    文章目录 Pre @SpringBootApplication 注解 @ComponentScan 注解 @SpringBootConfiguration 注解 @EnableAutoConfigur ...

  5. Spring Boot自动配置原理

    要了解Spring Boot的自动配置首先我需要先了解Spring Boot的两个机制,一个是配置文件如何进入到系统变成属性,二是如何将这些属性加入到容器中. 首先我们需要有一个组件,这个组件中的属性 ...

  6. Spring Boot自动配置原理分析

    一.写在前面 随着时间的迁移Spring Boot 越来越多的出现在Java 后端程序员的视野中,Spring Boot 之所以会那么流行,很大的一个原因是自身集成了很多的Bean,简化了传统Srin ...

  7. 芋道 Spring Boot 自动配置原理

    转载自  芋道 Spring Boot 自动配置原理 1. 概述 友情提示:因为本文是分享 Spring Boot 自动配置的原理,所以需要胖友有使用过 Spring Boot 的经验.如果还没使用过 ...

  8. Spring Boot - 自动配置实例解读

    文章目录 Pre 启用 debug=true输出自动配置 HttpEncodingAutoConfiguration 什么情况下,Spring Boot 会自动装配 HttpEncodingAutoC ...

  9. Spring Boot 自动配置的 “魔法” 是如何实现的?

    转载自  Spring Boot 自动配置的 "魔法" 是如何实现的? Spring Boot是Spring旗下众多的子项目之一,其理念是约定优于配置,它通过实现了自动配置(大多数 ...

  10. Spring Boot自动配置原理、实战

    Spring Boot自动配置原理 Spring Boot的自动配置注解是@EnableAutoConfiguration, 从上面的@Import的类可以找到下面自动加载自动配置的映射. org.s ...

最新文章

  1. Relay IR表示
  2. 脚本1)启动jetty的脚本
  3. centos mate桌面_CentOS 7安装桌面汇总
  4. 全球及中国汽车涂料市场盈利预测与发展策略分析报告2022版
  5. 百度地图api公交路线,IE下跳转百度地图后中文变成乱码的解决办法
  6. CSS 基础入门语法
  7. linux 变量c file代表的内容.,LinuxC编程基础--mak.ppt
  8. Matlab Tricks(二十八)—— 笛卡尔积的实现
  9. 如何降低BI系统建设的风险
  10. python web框架【补充】自定义web框架
  11. 如何打造自动驾驶的数据闭环
  12. matlab能替代几何画板吗,比几何画板更强大的工具软件GeoGebra,数学老师值得拥有...
  13. 重庆计算机c语言二级成绩查询,历届重庆市计算机C语言二级考试试题及答案.pdf...
  14. kux格式怎么转换成mp3_kux格式怎么转换成mp4?快速转换格式的方法
  15. 包含WebRoot的Web工程在Eclipse中的搭建和配置
  16. 计算机如何取消自动关机,电脑怎么设置自动关机及取消自动关机
  17. glassfish java环境_CentOS安装JDK和安装Glassfish
  18. 最新 --》》如何推销自己
  19. 计算机自动关机启机唤醒设置,电脑在哪设置定时关机(如何设置电脑的自动关机和自动开机)...
  20. excel数据表转成insert语句插入数据库

热门文章

  1. nginx反向代理异步传输模式(原理)
  2. MATLAB 中如何使用 help
  3. 静态时序分析 Static Timing Analysis 教程
  4. Snapper:通过同义、分类关键词快速定位并调用WAV文件
  5. 摘抄整理:基于数据驱动的故障诊断方法综述
  6. 极值点 驻点 鞍点 拐点
  7. DPM目标检测算法(毕业论文节选)
  8. 【计算机科学】【2017】无组织三维点云的边缘检测
  9. Recoil 的使用
  10. 著名的光伏系统设计——pvsyst7.2中文版