- Spring
type: channel
link: http://lithum.tech/index.php/category/Spring/
items: Spring Elasticsearch(Neumann)
items: SpringBoot流程(上)
items: Spring源码导入IDEA

Spring Elasticsearch(Neumann)
type: item
date: 2022-02-11T16:02:00+08:00
description: 简介从文档 Spring Data Elasticsearch - Reference Documentation 可以查看到Spring 与 Elasticsearch之间的版本关系。这里由于项目的需要，我们选取的是 Neumann版本，对应的是Spring Data Elasticsearch 4.0.xElasticsearch 7.6.2Spring Framework 5.2.12Spring Boot 2.3.x官方文档 Spring Data Neumann goes GA，注意需要使用的是这个文档。Elasticsearch 和 数据库 对比SQL数据库Elasticsearchcolumn(列)field(字段)row(行)document(文档)table(表)index(索引)schema(模式)mapping(映射)database server(数据库服务器)Elasticsearch 集群实例测试方法我们使用如下测试代码作为测试基础package com.example.demo; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; @SpringBootTest public class ElasticsearchTests { @Autowired private ElasticsearchRestTemplate elasticsearchRestTemplate; @Test void testQuery() { // 测试代码 } }只需要修改testQuery内代码，就可以完成针对不同代码的测试。查询所有文档查询一个索引中的所有数据。类似于查询语句select * from metric_server;接下来是获取Elasticsearch数据@Data class TestObject { private String name; private String region; private String resourceId; } @Test void testQuery() { Query query = new NativeSearchQueryBuilder() .withQuery(matchAllQuery()) .build(); IndexCoordinates indexCoordinates = IndexCoordinates.of("metric_server"); List<TestObject> objs = elasticsearchRestTemplate.queryForList(query, TestObject.class, indexCoordinates); for ( int i = 0 ; i < objs.size() ;i++) { System.out.println(objs.get(i)); } }根据条件简单查询加上条件再做查询,类似于以下select * from metric_server where name = 'agenttest';代码也比较简单，使用termQuery来匹配@Test void testQuery() { TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("name", "agenttest"); Query query = new NativeSearchQueryBuilder() .withQuery(termQueryBuilder) .build(); IndexCoordinates indexCoordinates = IndexCoordinates.of("metric_server"); List<TestObject> objs = elasticsearchRestTemplate.queryForList(query, TestObject.class, indexCoordinates); for ( int i = 0 ; i < objs.size() ;i++) { System.out.println(objs.get(i)); } }各匹配类型说明Query类型说明matchQuery分词，然后调用termQuerytermQuery不分词，严格匹配wildcardQuery通配符匹配fuzzyQuery模糊匹配rangeQuery…

SpringBoot流程(上)
type: item
date: 2021-11-26T16:29:00+08:00
description: SpringBoot启动流程Spring启动流程，最重要的就是这个函数。我们也是从这里开始入手。SpringApplication.run(DemoApplication.class, args);在网上，我找到一个比较不错的分析图启动代码主要分成2部分。构造SpringApplication执行run方法构造SpringApplication构造函数包括一系列重载函数，最后调用下面这个函数@SuppressWarnings({ "unchecked", "rawtypes" }) public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) { this.resourceLoader = resourceLoader; Assert.notNull(primarySources, "PrimarySources must not be null"); this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources)); // #1 侦测web application type this.webApplicationType = WebApplicationType.deduceFromClasspath(); // #2 获取bootstrap registry initializers this.bootstrapRegistryInitializers = getBootstrapRegistryInitializersFromSpringFactories(); // #3 // 获取 ApplicationContextInitializer 设置initializers // 获取 ApplicationListener 设置listeners setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class)); setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class)); // #4 获取main函数所在类 this.mainApplicationClass = deduceMainApplicationClass(); }1 侦测web application type有三种类型的web application typeNONESERVLETREACTIVE2 获取bootstrap registry initializersBootstrapper 同时调用初始化3 设置initializers和listener修改一下代码，方便调试的时候可以直接查看变量setInitializers只是简单的设置，不赘述public void setInitializers(Collection<? extends ApplicationContextInitializer<?>> initializers) { this.initializers = new ArrayList<>(initializers); }listeners同理获取实例的方法如下，我们跟进去看下代码易得private <T> Collection<T> getSpringFactoriesInstances(Class<T> type, Class<?>[] parameterTypes, Object... args) { ClassLoader classLoader = getClassLoader(); // Use names and ensure unique to protect against duplicates // 从每个包的META-INF/spring.factories处获取实现了对应接口的class Set<String> names = new LinkedHashSet<>(SpringFactoriesLoader.loadFactoryNames(type, classLoader)); // 利用反射实例化！ List<T> instances = createSpringFactoriesInstances(type, parameterTypes, classLoader, args, names); // 根据order权重排序，初始化是有顺序的，数字越小越靠前 AnnotationAwareOrd…

Spring源码导入IDEA
type: item
date: 2021-11-26T10:23:00+08:00
description: 参考文章Idea导入SpringBoot源码终极版(基于Gradle)IDEA、JDK 与GradleIntelliJ IDEA使用sdkman安装JDK11,注意安装的版本是11.0.12-open，不要使用11.0.11.j9-adpt使用sdkman安装Gradle源码准备如果是linux上，比如我用的mint，直接可以下载拉取代码git clone https://github.com/spring-projects/spring-boot.git如果在windows上，请注意，你有可能会碰到Filename too long的报错，这种情况下，如果使用win8以上系统，你可以如下设置,参考git config --global core.longpaths true切换到对应v2.5.7 taggit tag v2.5.7添加测试模块(参考上面文章)新建模块名字改为spring-boot-debug修改build.gradle文件，把java插件改成applicationplugins { id 'application' } group 'org.springframework.boot' version '2.5.7' repositories { mavenCentral() } dependencies { annotationProcessor("org.projectlombok:lombok:1.18.22") annotationProcessor(project(":spring-boot-project:spring-boot-tools:spring-boot-configuration-processor")) implementation(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-web")) implementation(enforcedPlatform(project(":spring-boot-project:spring-boot-dependencies"))) implementation(project(":spring-boot-project:spring-boot")) implementation("jakarta.validation:jakarta.validation-api") implementation("org.projectlombok:lombok:1.18.22") } application { mainClass="org.springframework.debug.DemoApplication" }DemoApplication.java代码package org.springframework.debug; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class DemoApplication { public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } }现在可以在模块中随便写一些测试代码同时，我们给对SpringApplication.java代码Banner代码上下打印出标识符号，如图所示。运行这个application，如图输出则表示成功