Spring Boot示例分析讲解自动化装配机制核心注解

目录
  • 1. 自动化装配介绍
  • 2. Spring Boot 自动化配置UML图解
  • 3. Spring Boot 自动化配置核心注解分析
    • 3.1 @Inherited
    • 3.2 @SpringBootConfiguration
    • 3.3 @EnableAutoConfiguration
    • 3.4 @ComponentScan
    • 3.5 @ConfigurationPropertiesScan
    • 3.6 @AutoConfigurationImportSelector
    • 3.7 @AutoConfigurationPackages
  • 4. 总结

1. 自动化装配介绍

Spring Boot针对mvc做了大量封装,简化开发者的使用,内部是如何管理资源配置,Bean配置,环境变量配置以及启动配置等? 实质是SpringBoot做了大量的注解封装,比如@SpringBootApplication, 同时采用Spring 4框架的新特性@Conditional基于条件的Bean创建管理机制来实现;

实际的工作场景中是复杂多样的, 有些项目需要不同的组件, 比如REDIS、MONGODB作缓存; RABBITMQ、KAFKA作消息队列; 有些项目运行环境不同, 比如JDK7、JDK8不同版本,面对众多复杂的需求, 又要做到最大化支持, Spring Boot是如何管理实现的, 这就依赖Conditional功能,基于条件的自动化配置。

2. Spring Boot 自动化配置UML图解

SpringBootApplication是我们所常用熟知的注解, 它是一个组合注解, 依赖多个注解,共同实现Spring Boot应用功能, 以下为所有依赖的UML图解,我们围绕这些注解深入研究,看下具体的实现。

3. Spring Boot 自动化配置核心注解分析

SpringBootApplication注解:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
		@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
@ConfigurationPropertiesScan
public @interface SpringBootApplication {
	/**
	 * 需要排除的自动化配置, 根据类名进行排除,  比如MongoAutoConfiguration, JpaRepositoriesAutoConfiguration等
	 */
	@AliasFor(annotation = EnableAutoConfiguration.class)
	Class<?>[] exclude() default {};
	/**
	 * 需要排除的自动化配置, 根据名称进行排除
	 */
	@AliasFor(annotation = EnableAutoConfiguration.class)
	String[] excludeName() default {};
	/**
	 * 指定需要扫描的包路径,参数填写包名
	 */
	@AliasFor(annotation = ComponentScan.class, attribute = "basePackages")
	String[] scanBasePackages() default {};
	/**
	 * 指定需要扫描的包路径
	 */
	@AliasFor(annotation = ComponentScan.class, attribute = "basePackageClasses")
	Class<?>[] scanBasePackageClasses() default {};
	/**
	 * Bean方法的动态代理配置, 如果没有采用工厂方法, 可以标记为false, 采用cglib代理。
	 */
	@AliasFor(annotation = Configuration.class)
	boolean proxyBeanMethods() default true;
}

3.1 @Inherited

java.lang.annotation.@Inherited 注解,从包名可以看出为JDK自带注解, 作用是让子类能够继承父类中引用Inherited的注解, 但需注意的是, 该注解作用范围只在类声明中有效; 如果是接口与接口的继承, 类与接口的继承, 是不会生效。

3.2 @SpringBootConfiguration

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration(proxyBeanMethods = false)
public @interface SpringBootConfiguration {
	/**
	 * Bean方法的动态代理配置
	 */
	@AliasFor(annotation = Configuration.class)
	boolean proxyBeanMethods() default true;
}

这是配置型处理注解, 可以看到内部源码引用了@Configuration注解,

自身没有太多的实现, 那为什么还需要再包装?官方给出的解释是对Spring的@Configuration的扩展,

用于实现SpringBoot的自动化配置。proxyBeanMethods属性默认为true, 作用是对bean的方法是否开启代理方式调用, 默认为true, 如果没有采用工厂方法,可以设为false, 通过cglib作动态代理。

3.3 @EnableAutoConfiguration

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
    // 设置注解支持重载的标识
	String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";
	/**
	 * 排除自动化配置的组件, 如MongoAutoConfiguration, JpaRepositoriesAutoConfiguration等
	 */
	Class<?>[] exclude() default {};
	/**
	 * 排除自动化配置的组件, 根据名称设置
	 */
	String[] excludeName() default {};
}

用于管理开启Spring Boot的各种自动化配置注解, 如datasource, mongodb, redis等,也是spring-boot-autoconfigure工程的核心注解。

AutoConfigurationPackage

它的主要作用是扫描主程序同级及下级的包路径所有Bean与组件注册到Spring Ioc容器中。

Import

它可以把没有声明配置的类注册到Spring Ioc容器中管理引用。 导入的AutoConfigurationImportSelector类实现BeanClassLoaderAware、ResourceLoaderAware、EnvironmentAware等接口, 管理类装载器, 资源装载器及环境配置等, 是一个负责处理自动化配置导入的选择管理器。在下面【@AutoConfigurationImportSelector剖析】进行详解。

3.4 @ComponentScan

这是我们在Spring下面常用的一个注解,它可以扫描Spring定义的注解, 如@Componment, @Service等, 常用的属性有basePackages扫描路径,includeFilters包含路径过滤器, excludeFilters排除路径过滤器,lazyInit是否懒加载等,能够非常灵活的扫描管理需要注册组件。

3.5 @ConfigurationPropertiesScan

作用是扫描指定包及子包路径下面的ConfigurationProperties注解,管理工程配置属性信息。主要属性为basePackages扫描路径, 支持多个路径,数组形式;basePackageClasses属性也可以具体到包下面的类,

支持多个配置。

3.6 @AutoConfigurationImportSelector

AutoConfigurationImportSelector 实现 DeferredImportSelector、BeanClassLoaderAware、ResourceLoaderAware、BeanFactoryAware、EnvironmentAware、Ordered 接口, 为自动化配置的核心处理类, 主要负责自动化配置规则的一系列处理逻辑:

/**
 * {@link DeferredImportSelector} to handle {@link EnableAutoConfiguration
 * auto-configuration}. This class can also be subclassed if a custom variant of
 * {@link EnableAutoConfiguration @EnableAutoConfiguration} is needed.
 *
 * @author Phillip Webb
 * @author Andy Wilkinson
 * @author Stephane Nicoll
 * @author Madhura Bhave
 * @since 1.3.0
 * @see EnableAutoConfiguration
 */
public class AutoConfigurationImportSelector implements DeferredImportSelector, BeanClassLoaderAware,
		ResourceLoaderAware, BeanFactoryAware, EnvironmentAware, Ordered {
            ...
        }
}

讲解几个技术点:

getCandidateConfigurations方法

protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
		List<String> configurations = SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(),
				getBeanClassLoader());
		Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you "
				+ "are using a custom packaging, make sure that file is correct.");
		return configurations;
	}

该方法是获取所有Spring Boot声明定义的自动化配置类。

看下具体有哪些信息:

这些实际是配置在Spring-boot-autoconfigure工程下的META-INF/spring.factories文件中:

看到这里, 我们应该可以明白,为什么AOP,RABBIT,DATASOURCE, REIDS等组件SPRING BOOT都能帮我们快速配置实现,其实它内部遵循SPI机制, 已经把自动化配置做好了封装。

AutoConfigurationGroup类

它是AutoConfigurationImportSelector的内部类,实现了DeferredImportSelector.Group、BeanClassLoaderAware、BeanFactoryAware、ResourceLoaderAware接口,是一个重要的核心类。主要作用是负责自动化配置条目信息的记录, 排序,元数据处理等。它通过getImportGroup方法获取返回,该方法实现DeferredImportSelector的接口。

private static class AutoConfigurationGroup
			implements DeferredImportSelector.Group, BeanClassLoaderAware, BeanFactoryAware, ResourceLoaderAware {
    	// 记录注解的元数据
		private final Map<String, AnnotationMetadata> entries = new LinkedHashMap<>();
		// 记录自动化配置条目,放入集合
		private final List<AutoConfigurationEntry> autoConfigurationEntries = new ArrayList<>();
        // 设置bean的类加载器
		private ClassLoader beanClassLoader;
        // 设置bean工厂信息
		private BeanFactory beanFactory;
        // 设置资源加载器信息
		private ResourceLoader resourceLoader;
        // 设置自动化配置的元数据记录
		private AutoConfigurationMetadata autoConfigurationMetadata;
		...
	}

属性主要定义了一些自动化配置类目信息、BEAN工厂、类和资源加载器信息。entries条目有22条, 具体内容如下:

里面是主要的自动化配置类的元数据信息,autoConfigurationEntries属性就是具体的自动化配置条目。这些主要自动化类配置是Spring boot帮助我们实现mvc的核心功能,如请求分发,文件上传,参数验证,编码转换等功能。还有一部分是定制条件自动化配置类,

autoConfigurationMetadata元数据内容较多, 包含各种组件, 根据环境配置和版本不同, 这里可以看到共有705个:

由于Spring Boot支持众多插件,功能丰富, 数量较多; 这里存在些疑问, 这里面的元数据和上面的entries条目都是AutoConfiguration自动化配置类, 那有什么区别? 其实这里面的, 都是基于条件的自动化配置。

我们就拿KafkaAutoConfiguration来看:

可以看到注解ConditionalOnClass,意思是KafkaAutoConfiguration生效的前提是基于KafkaTemplate类的初始化成功,这就是定制条件,也就是基于条件的自动化配置类,虽然有七百多个,但其实是根据工程实际用到的组件,才会触发加载对应的配置。 有关Conditional基于条件的自动化配置实现原理, 在下面我们再作深入研究。

继续看AutoConfigurationImportSelector内部类的selectImports方法:

@Override
public Iterable<Entry> selectImports() {
    if (this.autoConfigurationEntries.isEmpty()) {
        return Collections.emptyList();
    }
    // 将所有自动化条目根据配置的Exclusion条件作过滤, 并转换为SET集合
    Set<String> allExclusions = this.autoConfigurationEntries.stream()
        .map(AutoConfigurationEntry::getExclusions).flatMap(Collection::stream).collect(Collectors.toSet());
    // SET集合, 记录所有需要处理的自动化配置
    Set<String> processedConfigurations = this.autoConfigurationEntries.stream()
        .map(AutoConfigurationEntry::getConfigurations).flatMap(Collection::stream)
        .collect(Collectors.toCollection(LinkedHashSet::new));
    // 两个SET, 做交集过滤, 排除不需要的配置
    processedConfigurations.removeAll(allExclusions);
    // 最后进行排序处理
    return sortAutoConfigurations(processedConfigurations, getAutoConfigurationMetadata()).stream()
        .map((importClassName) -> new Entry(this.entries.get(importClassName), importClassName))
        .collect(Collectors.toList());
}

该方法是针对autoConfigurationEntries自动化配置条目做过滤,根据指定的排除规则处理;再根据设置的启动的优先级做排序整理。从代码中可以看到,先获取所有的allExclusions排除配置信息,再获取所有需要处理的processedConfigurations配置信息,然后做过滤处理,最后再调用sortAutoConfigurations方法,根据order顺序做排序整理。

AutoConfigurationImportSelector内部类的process方法:

@Override
public void process(AnnotationMetadata annotationMetadata, DeferredImportSelector deferredImportSelector) {
    Assert.state(deferredImportSelector instanceof AutoConfigurationImportSelector,
                 () -> String.format("Only %s implementations are supported, got %s",
                                     AutoConfigurationImportSelector.class.getSimpleName(),
                                     deferredImportSelector.getClass().getName()));
    // 获取自动化配置条目
    AutoConfigurationEntry autoConfigurationEntry = ((AutoConfigurationImportSelector) deferredImportSelector)
        .getAutoConfigurationEntry(getAutoConfigurationMetadata(), annotationMetadata);
    // 记录获取的条目
    this.autoConfigurationEntries.add(autoConfigurationEntry);
    for (String importClassName : autoConfigurationEntry.getConfigurations()) {
        // 放入成员变量entries中
        this.entries.putIfAbsent(importClassName, annotationMetadata);
    }
}

该方法是扫描获取autoConfigurationEntries自动化配置条目信息。

annotationMetadata参数:

为注解元数据,有也就是被@SpringBootApplication修饰的类信息,在这里就是我们的启动入口类信息。

deferredImportSelector参数:

通过@EnableAutoConfiguration注解定义的 @Import 的类,也就是AutoConfigurationImportSelector对象。根据配置,会加载指定的beanFactory、classLoader、resourceLoader和environment对象。

AutoConfigurationImportSelector内部类的getAutoConfigurationEntry方法:

protected AutoConfigurationEntry getAutoConfigurationEntry(AutoConfigurationMetadata autoConfigurationMetadata,
			AnnotationMetadata annotationMetadata) {
        // 1、判断是否开对应注解
		if (!isEnabled(annotationMetadata)) {
			return EMPTY_ENTRY;
		}
        // 2、获取注解定义的属性
		AnnotationAttributes attributes = getAttributes(annotationMetadata);
        // 3、获取符合规则的Spring Boot 内置的自动化配置类, 并做去重处理
		List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes);
		configurations = removeDuplicates(configurations);
        // 4、做排除规则匹配, 过滤处理
		Set<String> exclusions = getExclusions(annotationMetadata, attributes);
		checkExcludedClasses(configurations, exclusions);
		configurations.removeAll(exclusions);
		configurations = filter(configurations, autoConfigurationMetadata);
        // 5、触发自动导入处理完成事件
		fireAutoConfigurationImportEvents(configurations, exclusions);
		return new AutoConfigurationEntry(configurations, exclusions);
	}

该方法主要作用是获取Spring Boot 内置的自动化条目, 例AopAutoConfiguration等,该方法会调用上面讲解的getCandidateConfigurations方法。 主要步骤逻辑如下:

  • 判断是否开启元注解扫描, 对应属性为spring.boot.enableautoconfiguration,默认情况下, 是开启自动配置。
  • 获取定义的注解属性, 跟踪内部源码, 里面会返回exclude和excludeName等属性。
  • 获取符合规则的Spring Boot 内置的自动化配置, 并做去重处理,也就是我们上面讲解的getCandidateConfigurations方法, 从中我们就可以理解其中的关联关系。
  • 做排除规则检查与过滤处理, 根据上面第2个步骤获取的exclude等属性以及配置属性spring.autoconfigure.exclude做过滤处理。
  • 触发自动导入完成事件, 该方法内部逻辑正常处理完成才会触发,会调用AutoConfigurationImportListener监听器做通知处理。

3.7 @AutoConfigurationPackages

AutoConfigurationPackages是EnableAutoConfiguration上的另一个核心注解类, 官方解释为:

Indicates that the package containing the annotated class should be registered

意思是包含该注解的类,所在包下面的class, 都会注册到Spring Ioc容器中。对应源码:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Import(AutoConfigurationPackages.Registrar.class)
public @interface AutoConfigurationPackage {
...
}

Import注解, 导入AutoConfigurationPackages抽象类下面的内部静态类Registrar,研究Registrar实现原理:

Registrar实现 ImportBeanDefinitionRegistrar、DeterminableImports 接口,它负责存储从@AutoConfigurationPackage注解扫描到的信息。 源码如下:

static class Registrar implements ImportBeanDefinitionRegistrar, DeterminableImports {
        // 注册BEAN的定义信息
    	@Override
    	public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
    		register(registry, new PackageImport(metadata).getPackageName());
    	}
        // 决定是否导入注解中的配置内容
    	@Override
    	public Set<Object> determineImports(AnnotationMetadata metadata) {
    		return Collections.singleton(new PackageImport(metadata));
    	}
    }

这里面主要涉及到PackageImport类, 它是AutoConfigurationPackages的内部私有静态类,主要是记录导入的 报名信息, 源码如下:

    /**
	 * Wrapper for a package import.
	 */
	private static final class PackageImport {
		private final String packageName;
		// 构造方法, 记录注解内容
		PackageImport(AnnotationMetadata metadata) {
			this.packageName = ClassUtils.getPackageName(metadata.getClassName());
		}
		// 获取指定包名称
		public String getPackageName() {
			return this.packageName;
		}
	    // 重载父类比较逻辑, 根据包名判断
		@Override
		public boolean equals(Object obj) {
			if (obj == null || getClass() != obj.getClass()) {
				return false;
			}
			return this.packageName.equals(((PackageImport) obj).packageName);
		}
		// 重载hash标识, 以包名的HASH值为准
		@Override
		public int hashCode() {
			return this.packageName.hashCode();
		}
	    // 重载toString, 打印内容
		@Override
		public String toString() {
			return "Package Import " + this.packageName;
		}
	}

内部断点跟踪的话, 可以看到它记录的是我们启动类所在的包名。这也就是为什么不需要指定扫描包路径, 也会加载启动类所在包下面的JavaConfig配置信息。

回到上面Registrar的registerBeanDefinitions方法, 内部调用的是register方法:

它是处理记录AutoConfigurationPackages扫描包信息,源码如下:

public static void register(BeanDefinitionRegistry registry, String... packageNames) {
        // 判断是否包含BEAN定义信息, 如果包含, 更新packageNames信息
		if (registry.containsBeanDefinition(BEAN)) {
			BeanDefinition beanDefinition = registry.getBeanDefinition(BEAN);
			ConstructorArgumentValues constructorArguments = beanDefinition.getConstructorArgumentValues();
			constructorArguments.addIndexedArgumentValue(0, addBasePackages(constructorArguments, packageNames));
		}
        // 如果registry中不包含BEAN定义, 重新构造GenericBeanDefinition对象, 记录相关信息
		else {
			GenericBeanDefinition beanDefinition = new GenericBeanDefinition();
			beanDefinition.setBeanClass(BasePackages.class);
			beanDefinition.getConstructorArgumentValues().addIndexedArgumentValue(0, packageNames);
			beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
			registry.registerBeanDefinition(BEAN, beanDefinition);
		}
	}

先判断AutoConfigurationPackages注解, 记录对应的扫描包信息;如果不存在,则自行创建基于BasePackages的BEAN定义信息, 并进行注册。再看下addBasePackages方法:

private static String[] addBasePackages(ConstructorArgumentValues constructorArguments, String[] packageNames) {
        // 获取已经存在的Bean定义信息
		String[] existing = (String[]) constructorArguments.getIndexedArgumentValue(0, String[].class).getValue();
        // 创建合并集合, 过滤重复的Bean定义
		Set<String> merged = new LinkedHashSet<>();
        // 根据Set特性, 自动合并去重
		merged.addAll(Arrays.asList(existing));
		merged.addAll(Arrays.asList(packageNames));
		return StringUtils.toStringArray(merged);
	}

获取已经存在的定义信息,再和packageNames合并, 过滤重复的扫描包。

自动化配置到此就不再对其他代码进行深入跟踪分析,Spring Boot整个框架代码还是较多, 大家可以按这种思路, 逐个层级去剖析,深入挖掘更多技术点。

4. 总结

我们研究了Spring Boot的自动化配置原理,逐层研究剖析,从@SpringBootApplication启动注解开始,到下面的@SpringBootConfiguration, @ConfigurationPropertiesScan, @ComponentScan以及核心@EnableAutoConfiguration。我们对@EnableAutoConfiguration下面的@AutoConfigurationPackage和@Import(AutoConfigurationImportSelector.class)两个重要注解作了深入研究,从中可以看到Spring Boot针对自动化配置, 是分为两部分, 一部分是核心注解,来支撑服务的正常运行; 另一部分是非核心的各种自动化组件注解,做了大量封装,便于我们集成使用。

到此这篇关于Spring Boot示例分析讲解自动化装配机制核心注解的文章就介绍到这了,更多相关Spring Boot自动化装配机制内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Spring Boot中自动化配置的利弊以及解决方法

    本文主要给大家介绍了关于Spring Boot自动化配置的利弊及解决方法的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍: Spring Boot中的双刃剑:自动化配置 在之前的文章中,我们通过各种功能性示例体验了Spring Boot的自动化配置给我们所带来的超便利的新开发方式.但是,在一些情况下Spring Boot的自动化配置也会给我们惹来不少的麻烦,比如这些场景: 项目依赖复杂的情况下,由于依赖方的依赖组织不够严格,可能引入了一些实际我们不需要的依赖,从而导致我们

  • Spring Boot 深入分析AutoConfigurationImportFilter自动化条件配置源码

    目录 1. AutoConfigurationImportFilter的作用 2. AutoConfigurationImportFilter UML类图说明 3. FilteringSpringBootCondition抽象类 4. AutoConfigurationImportSelector类 5. 总结 1. AutoConfigurationImportFilter的作用 之前讲解了SpringBoot的Conditional的自动化条件配置,我们分析了内部是如何具体实现,在整个实现当

  • 阿里SpringBoot应用自动化部署实现IDEA版Jenkins

    目录 CloudToolkit简介 安装 使用 自动化部署 常用功能 总结 之前分享过一些使用Jenkins进行自动化部署的技巧 ,最近发现一款阿里出品的IDEA插件CloudToolkit,不仅支持直接打包应用部署到远程服务器上,而且还能当终端工具使用.试用了一把这个插件,非常不错,推荐给大家!装上这个插件,IDEA一站式开发又近了一步! SpringBoot实战电商项目mall(50k+star)地址:github.com/macrozheng/… CloudToolkit简介 CloudT

  • Jenkins自动化部署springboot代码实例

    一.linux按jar包名称部署 1.执行shell PID=$(ps -ef | grep app.jar | grep -v grep | awk '{ print $2 }') if [ -z "$PID" ] then echo Application is already stopped else echo kill $PID kill $PID fi 2.调用顶层maven目标 clean package -Dmaven.test.skip=true 3.执行shell c

  • 浅析SpringBoot自动化配置原理实现

    绪论 什么是SpringBoot? Spring Boot 是所有基于 Spring 开发的项目的起点.Spring Boot 的设计是为了让你尽可能快的跑起来 Spring 应用程序并且尽可能减少你的配置文件.简单来说就是SpringBoot其实不是什么新的框架,它默认配置了很多框架的使用方式,就像maven整合了所有的jar包,spring boot整合了所有的框架(不知道这样比喻是否合适). SpringBoot四个主要特性 SpringBoot Starter:他将常用的依赖分组进行了整

  • Spring Boot 详细分析Conditional自动化配置注解

    目录 1. Spring Boot Condition功能与作用 2. Conditional条件化系列注解介绍 3. Conditional条件化注解的实现原理 4. Conditional核心之matches匹配接口 5. Conditional核心之条件化注解具体实现 6. 总结 1. Spring Boot Condition功能与作用 @Conditional是基于条件的自动化配置注解, 由Spring 4框架推出的新特性. 在一个服务工程, 通常会存在多个配置环境, 比如常见的DEV

  • Spring Boot示例分析讲解自动化装配机制核心注解

    目录 1. 自动化装配介绍 2. Spring Boot 自动化配置UML图解 3. Spring Boot 自动化配置核心注解分析 3.1 @Inherited 3.2 @SpringBootConfiguration 3.3 @EnableAutoConfiguration 3.4 @ComponentScan 3.5 @ConfigurationPropertiesScan 3.6 @AutoConfigurationImportSelector 3.7 @AutoConfiguratio

  • Spring Boot超详细讲解请求处理流程机制

    目录 1. 背景 2. Spring Boot 的请求处理流程设计 3. Servlet服务模式请求流程分析 3.1 ServletWebServerApplicationContext分析 3.2 Servlet服务模式之请求流程具体分析 4. Reactive服务模式请求流程分析 4.1 ReactiveWebServerApplicationContext分析 4.2 webflux服务模式之请求流程具体分析 5. 总结 1. 背景 之前我们对Spring Boot做了研究讲解,我们知道怎

  • 通过Spring Security魔幻山谷讲解获取认证机制核心原理

    本文基于Springboot+Vue+Spring Security框架而写的原创学习笔记,demo代码参考<Spring Boot+Spring Cloud+Vue+Element项目实战:手把手教你开发权限管理系统>一书. 这是一个古老的传说. 在神秘的Web系统世界里,有一座名为SpringSecurity的山谷,它高耸入云,蔓延千里,鸟飞不过,兽攀不了.这座山谷只有一条逼仄的道路可通.然而,若要通过这条道路前往另一头的世界,就必须先拿到一块名为token的令牌,只有这样,道路上戍守关口

  • Maven 多模块父子工程的实现(含Spring Boot示例)

    一.为什么要用Maven多模块 假设有这样一个项目,很常见的Java Web应用.在这个应用中,我们分了几层: Dao Service Web 对应的,在一个项目中,我们会看到一些包名: org.xx.app.dao org.xx.app.service org.xx.app.web org.xx.app.util 但随着项目的进行,你可能会遇到如下问题: 这个应用可能需要有一个前台和一个后台管理端,你发现大部分dao,一些service,和大部分util是在两个应用中可. pom.xml中的依

  • Spring Boot示例代码整合Redis详解

    目录 Redis 简介 Redis 优势 Redis与其他key-value存储有什么不同 添加Redis依赖包 配置Redis数据库连接 编写Redis操作工具类 测试 Redis 简介 Redis 是完全开源的,遵守 BSD 协议,是一个高性能的 key-value 数据库. Redis 与其他 key - value 缓存产品有以下三个特点: Redis支持数据的持久化,可以将内存中的数据保存在磁盘中,重启的时候可以再次加载进行使用. Redis不仅仅支持简单的key-value类型的数据

  • C++ STL容器与函数谓词示例分析讲解

    目录 1.C++ vector向量 2.C++ stack 栈 3.C++ queue 队列 4.优先级队列 5.C++ list 6.c++ set 集合 7.C++ map函数 8.C++ multimap容器 9.C++ 谓词 10.C++内置预定义函数 C++ STL(Standard Template Library标准模板库),相当于java的集合模块, STL 有很多的容器. 1.C++ vector向量 (内部:封装动态大小数组作为容器,能够存放任意的动态数组) #include

  • Spring Boot自动配置的原理及@Conditional条件注解

    目录 1 @SpringBootApplication自动配置原理 2 @Conditional系列条件注解 1 @SpringBootApplication自动配置原理 @SpringBootApplication是一个组合注解,主要由@ComponentScan.@SpringBootConfiguration.@EnableAutoConfiguration这三个注解组成.@EnableAutoConfiguration是Spring Boot实现自动配置的关键注解. @Component

  • Spring Boot两种全局配置和两种注解的操作方法

    目录 零.学习目标 一.全局配置文件概述 二.Application.properties配置文件 1.配置tomcat端口号和web虚拟路径 2.对象类型的配置与使用 3.两种属性注解方式的对比 三.Application.yaml配置文件 四.两种配置文件的比较 五.课后作业 零.学习目标 1.掌握application.properties配置文件 2.掌握application.yaml配置文件 3.掌握使用@ConfigurationProperties注入属性 4.掌握使用@Valu

  • 史上最全面的Spring Boot配置文件深入讲解

    前言 Spring Boot在工作中是用到的越来越广泛了,简单方便,有了它,效率提高不知道多少倍.Spring Boot配置文件对Spring Boot来说就是入门和基础,经常会用到,所以写下做个总结以便日后查看. 下面话不多说了,来一起看看详细的介绍吧 1.配置文件 当我们构建完Spring Boot项目后,会在resources目录下给我们一个默认的全局配置文件 application.properties,这是一个空文件,因为Spring Boot在底层已经把配置都给我们自动配置好了,当在

随机推荐