springboot2.x +redis使用和源码分析一(springboot自动装配源码分析)

springboot2.0.X使用spring security oauth2 最近收到一个任务使用spring security做一个oauth2的授权服务器和资源服务器,授权方式为Client_Credentials写一个demo,官方文档对这方面的描述比较少,官方项目中只有一个demo,是个spring项目,所有东西都存在了内存中,虽然他提供了Enable注解,因为我们要求的是client-id,client-secret等存入数据库把token存入redis,当然他官... 阅读详情

序言:

个人感觉springboot的源码是web应用开源框架中写的最好的,观看它的源码可以学习它的编码风格,代码设计思想,如何做到给予使用者最好的使用体验,隐藏连接各应用组件的实现细节,极大降低类开发者实力的要求。查看springboot对各组件的自动装配实现,可以很详细的了解到spring对于组件核心类的初始化过程,以及核心类的作用以及之间的依赖关系。

springboot提供的所有的自动装配类都在spring-boot-autoconfigure(直接查看源码)

 也可以通过官网来进行查看(选取要看的版本):

https://docs.spring.io/spring-boot/docs/2.2.3.BUILD-SNAPSHOT/reference/html/appendix-auto-configuration-classes.html#auto-configuration-classes-from-autoconfigure-module


如图所示是spring-boot-autoconfigure下对于redis提供类:

1:源码分析

1.1:RedisProperties

@ConfigurationProperties(prefix = "spring.redis")
public class RedisProperties {
    //使用redis database数 默认为0
    private int database = 0;
    //连接url 可包含用户和密码 例如 redis://user:password@example.com:6379
    private String url;
    //redis 端口号
    private String host = "localhost";
    //密码
    private String password;
    //端口号
    private int port = 6379;
    //是否开启SSL
    private boolean ssl;
    //超时时间
    private Duration timeout;
    //设置客户端名
    private String clientName;
    //支持哨兵机制
    private Sentinel sentinel;
    //支持集群配置
    private Cluster cluster;
    //Jedis客户端
    private final Jedis jedis = new Jedis();
    //Lettuce客户端
    private final Lettuce lettuce = new Lettuce();
    /**
     * 连接池一些属性
     */
    public static class Pool {
        //池中维护的最大空闲数 为负值代表
        private int maxIdle = 8;
        //池中要维护的最小空闲连接数 此值必须为正值
        private int minIdle = 0;
        //最大连接数 -数代表无限制
        private int maxActive = 8;
        //最大等待时间
        private Duration maxWait = Duration.ofMillis(-1);
        //
        private Duration timeBetweenEvictionRuns;

    }
    /**
     * 集群配置
     */
    public static class Cluster {
        //集群各节点地址host:port 多个以,隔开隔开
        private List<String> nodes;
        //集群中执行命令时重定向node的最大数量
        private Integer maxRedirects;
    }
    /**
     *Redis 哨兵参数属性
     */
    public static class Sentinel {
        //集群中master名
        private String master;
        //集群各节点地址host:port 多个以,隔开隔开
        private List<String> nodes;
    }
    /**
     * jedis客户端属性
     */
    public static class Jedis {
        //连接池一些配置
        private Pool pool;
    }
    /**
     *Lettuce客户端属性
     */
    public static class Lettuce {
        //停止超时时间
        private Duration shutdownTimeout = Duration.ofMillis(100);
       //连接池一些配置
        private Pool pool;
    }

}

1.2 RedisAutoConfiguration

RedisAutoConfiguration是springboot结合Redis配置核心类。

//禁止其它配置类使用该配置类的@Bean方法
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(RedisOperations.class)
@EnableConfigurationProperties(RedisProperties.class)
//初始化Redis连接工厂类 Import执行的初始化类是顺序执行,这里面会存在一个使用问题须谨慎(后续描述)
@Import({ LettuceConnectionConfiguration.class, JedisConnectionConfiguration.class })
public class RedisAutoConfiguration {

      //若系统中不存在默认的redisTemplateBean 进行初始化 依赖Redis连接工厂类
	@Bean
	@ConditionalOnMissingBean(name = "redisTemplate")
	public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory)
			throws UnknownHostException {
		RedisTemplate<Object, Object> template = new RedisTemplate<>();
		template.setConnectionFactory(redisConnectionFactory);
		return template;
	}

      //若系统中不存在StringRedisTemplate类的任何Bean 进行初始化 依赖Redis连接工厂类
      //StringRedisTemplate实际是RedisTemplate<String,String>子类用于简化操作数据为字符串类型(毕竟转换为json类型的string可以处理大部分的需求)
	@Bean
	@ConditionalOnMissingBean
	public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory)
			throws UnknownHostException {
		StringRedisTemplate template = new StringRedisTemplate();
		template.setConnectionFactory(redisConnectionFactory);
		return template;
	}

}

1.3:RedisConnectionConfiguration

此类是下述LettuceConnectionConfiguration与JedisConnectionConfiguration的父类,提供对一些基础类的管理。例如RedisProperties,RedisSentinelConfiguration,RedisClusterConfiguration类

1.4:LettuceConnectionConfiguration与JedisConnectionConfiguration

这里我将这两个类放在一块来解释,因为两者的功能都是一致为了创建初始化Redis连接工厂类

LettuceConnectionConfiguration:

//禁止其它配置类使用该配置类的@Bean方法
@Configuration(proxyBeanMethods = false)
//应用包含RedisClient 此类在io.lettuce.core包中
@ConditionalOnClass(RedisClient.class)
class LettuceConnectionConfiguration extends RedisConnectionConfiguration {

	LettuceConnectionConfiguration(RedisProperties properties,
			ObjectProvider<RedisSentinelConfiguration> sentinelConfigurationProvider,
			ObjectProvider<RedisClusterConfiguration> clusterConfigurationProvider) {
		super(properties, sentinelConfigurationProvider, clusterConfigurationProvider);
	}

	@Bean(destroyMethod = "shutdown")
	@ConditionalOnMissingBean(ClientResources.class)
	DefaultClientResources lettuceClientResources() {
		return DefaultClientResources.create();
	}

	@Bean
        //如果上下文不包含RedisConnectionFactory的bean初始化
	@ConditionalOnMissingBean(RedisConnectionFactory.class)
	LettuceConnectionFactory redisConnectionFactory(
                         //ObjectProvider 作用和@Autowired作用一致和Autowired不同在于对于实例对象为null的处理ObjectProvider只有当实例对象的确存在时才检索bean,而Autowired会报错 ObjectProvider可以支持多实例
			ObjectProvider<LettuceClientConfigurationBuilderCustomizer> builderCustomizers,
			ClientResources clientResources) throws UnknownHostException {
		LettuceClientConfiguration clientConfig = getLettuceClientConfiguration(builderCustomizers, clientResources,
				getProperties().getLettuce().getPool());
                //调用Lettuce API创建LettuceConnectionFactory 有兴趣可以自己看下
		return createLettuceConnectionFactory(clientConfig);
	}

	。。。。。

}

JedisConnectionConfiguration:

//禁止其它配置类使用该配置类的@Bean方法
@Configuration(proxyBeanMethods = false)
//上下文引入Jedis包
@ConditionalOnClass({ GenericObjectPool.class, JedisConnection.class, Jedis.class })
class JedisConnectionConfiguration extends RedisConnectionConfiguration {

	JedisConnectionConfiguration(RedisProperties properties,
			ObjectProvider<RedisSentinelConfiguration> sentinelConfiguration,
			ObjectProvider<RedisClusterConfiguration> clusterConfiguration) {
		super(properties, sentinelConfiguration, clusterConfiguration);
	}

	@Bean
        //如果上下文不包含RedisConnectionFactory的bean初始化
	@ConditionalOnMissingBean(RedisConnectionFactory.class)
	JedisConnectionFactory redisConnectionFactory(
                         //ObjectProvider 作用和@Autowired作用一致和Autowired不同在于对于实例对象为null的处理ObjectProvider只有当实例对象的确存在时才检索bean,而Autowired会报错 ObjectProvider可以支持多实例
			ObjectProvider<JedisClientConfigurationBuilderCustomizer> builderCusto    mizers) throws UnknownHostException {
                //调用Jedis API创建JedisConnectionFactory 有兴趣可以自己看下
		return createJedisConnectionFactory(builderCustomizers);
	}
    。。。。。

}

从上述代码可以看出在整个应用上下文只会存在一个RedisConnectionFactory的实例,如果LettuceConnectionConfiguration和JedisConnectionConfiguration都满足要求都会执行,那么springboot会按照Import中顺序执行初始化,也就是第一优先执行LettuceConnectionConfiguration来创建RedisConnectionFactory实例。例如如果我们使用spring-boot-starter-parent来作为应用的父工程,又想使用Jedis客户端,那么就会出现上述的问题,原因在于spring-boot-starter-data-redis(默认推荐的是基于Lettcue)中会存在Lettuce包的依赖,如果我们不注意这块就会出现不管怎么设置jedis pool的属性发现都毫无作用,因为创建的是LettuceConnectionFactory实例对象。

解决方案:

  1. 在应用中自己初始化RedisConnectionFactory
  2. 在pom引用中去除lettuce包会存在Lettuce包的依赖 如下所示:
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
    <exclusions>
        <exclusion>
            <groupId>io.lettuce</groupId>
            <artifactId>lettuce-core</artifactId>
        </exclusion>
    </exclusions>
</dependency>

1.5:LettuceClientConfigurationBuilderCustomizer和JedisClientConfigurationBuilderCustomizer

两者的功能作用一致,所以将两者放到一起描述 ,这里以JedisClientConfigurationBuilderCustomizer做为Demo来描述。

我们可以使用JedisClientConfigurationBuilderCustomizer来做一些定制化参数配置,也可以在多Redis下使不同客户端使用不同的定制化配置(后续会详细介绍)。

springboot执行定制操作代码:

class JedisConnectionConfiguration extends RedisConnectionConfiguration {

	
	private JedisClientConfiguration getJedisClientConfiguration(
			ObjectProvider<JedisClientConfigurationBuilderCustomizer> builderCustomizers) {
		。。。。。
           //执行应用中被注入到spring类JedisClientConfigurationBuilderCustomizer的Bean
		builderCustomizers.orderedStream().forEach((customizer) -> customizer.customize(builder));
		return builder.build();
	}

}

测试Demo:

@Configuration
class RedisCustomizerConfiguration {

    @Bean
    public MyJedisClientConfigurationBuilderCustomizer builderCustomizers(){

        return new MyJedisClientConfigurationBuilderCustomizer();
    }

    @Bean
    public MyJedisClientConfigurationBuilderCustomizerTwo builderCustomizersTow(){

        return new MyJedisClientConfigurationBuilderCustomizerTwo();
    }


    public class MyJedisClientConfigurationBuilderCustomizer implements JedisClientConfigurationBuilderCustomizer {

        @Override
        public void customize(JedisClientConfiguration.JedisClientConfigurationBuilder clientConfigurationBuilder) {


            JedisClientConfiguration jedisClientConfiguration =  clientConfigurationBuilder.build();

            //获取连接池信息 并做定制化设置
            GenericObjectPoolConfig genericObjectPoolConfig =  jedisClientConfiguration.getPoolConfig().get();

            if("test".equals(jedisClientConfiguration.getClientName().get())){

                //此两个参数在RedisProperties中统一为timeout 所以默认connectTimeout与readTimeout相同
                //可以通过JedisClientConfigurationBuilderCustomizer进行细致化配置
                clientConfigurationBuilder.connectTimeout(Duration.ofSeconds(10));
                clientConfigurationBuilder.readTimeout(Duration.ofSeconds(10));
                clientConfigurationBuilder.usePooling();
            }

        }
    }

    public class MyJedisClientConfigurationBuilderCustomizerTwo implements JedisClientConfigurationBuilderCustomizer {

        @Override
        public void customize(JedisClientConfiguration.JedisClientConfigurationBuilder clientConfigurationBuilder) {

            JedisClientConfiguration jedisClientConfiguration =  clientConfigurationBuilder.build();

            //获取连接池信息 并做定制化设置
            GenericObjectPoolConfig genericObjectPoolConfig =  jedisClientConfiguration.getPoolConfig().get();

            if("test1".equals(jedisClientConfiguration.getClientName().get())) {

                //此两个参数在RedisProperties中统一为timeout 所以默认connectTimeout与readTimeout相同
                //可以通过JedisClientConfigurationBuilderCustomizer进行细致化配置
                clientConfigurationBuilder.connectTimeout(Duration.ofSeconds(6));

                clientConfigurationBuilder.readTimeout(Duration.ofSeconds(6));

                clientConfigurationBuilder.usePooling();
            }
        }
    }
}

LettuceClientConfigurationBuilderCustomizer的使用方式和JedisClientConfigurationBuilderCustomizer是一致

1.6:RedisRepositoriesAutoConfiguration和RedisRepositoriesRegistrar

两类是为了简化spring Data中Repository对于redis的支持的一些列初始化的操作

//禁止其它配置类使用该配置类的@Bean方法
@Configuration(proxyBeanMethods = false)
//应用上下文必须包含 @EnableRedisRepositories注解类 EnableRedisRepositories中会Import RedisRepositoriesRegistrar类,会根据注解中的各参数进行各种初始化
@ConditionalOnClass(EnableRedisRepositories.class)
@ConditionalOnBean(RedisConnectionFactory.class)
//通过配置文件中spring.data.redis.repositories属性来配置是否执行RedisRepositoriesAutoConfiguration
@ConditionalOnProperty(prefix = "spring.data.redis.repositories", name = "enabled", havingValue = "true",
		matchIfMissing = true)
//必须包含RedisRepositoryFactoryBean类实例对象
@ConditionalOnMissingBean(RedisRepositoryFactoryBean.class)
//执行仓库注册类
@Import(RedisRepositoriesRegistrar.class)
//在RedisAutoConfiguration之后执行
@AutoConfigureAfter(RedisAutoConfiguration.class)
public class RedisRepositoriesAutoConfiguration {

}

//整体使用了模版方法设计模式(可以了解下24种设计模式)
//提供有关于Redis对于Repository模块基础参数
class RedisRepositoriesRegistrar extends AbstractRepositoryConfigurationSourceSupport {

	@Override
	protected Class<? extends Annotation> getAnnotation() {
		return EnableRedisRepositories.class;
	}

	@Override
	protected Class<?> getConfiguration() {
		return EnableRedisRepositoriesConfiguration.class;
	}

	@Override
	protected RepositoryConfigurationExtension getRepositoryConfigurationExtension() {
            //初始化Redis Repository配置扩展类 用于初始化注册一些基础Bean
		return new RedisRepositoryConfigurationExtension();
	}

        //启用spring Data中Repository 对Redis的支持
	@EnableRedisRepositories
	private static class EnableRedisRepositoriesConfiguration {

	}

}

//
public abstract class AbstractRepositoryConfigurationSourceSupport
        //实现该接口可以做到动态注册Bean 详细可以了解下ImportBeanDefinitionRegistrar接口的作用
		implements ImportBeanDefinitionRegistrar
        //初始化时可以BeanFactory写入类属性中
        ,BeanFactoryAware
        //初始化时可以ResourceLoader写入类属性中
        , ResourceLoaderAware
        //初始化时可以Environment写入类属性中
        , EnvironmentAware {

	private ResourceLoader resourceLoader;

	private BeanFactory beanFactory;

	private Environment environment;

        //结合注入类(RedisRepositoriesAutoConfiguration)的Metadata信息将需要初始化的Bean注入
	@Override
	public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry,
			BeanNameGenerator importBeanNameGenerator) {
        //RepositoryConfigurationDelegate Repository仓库代理类是spring-data对于Repository模块核心类,用于代理执行注册执行Bean
        //有兴趣可以查看下spring-data Repository源码 这里不详细介绍
		RepositoryConfigurationDelegate delegate = new RepositoryConfigurationDelegate(
				getConfigurationSource(registry, importBeanNameGenerator), this.resourceLoader, this.environment);
        //注册和Repository有关bean
		delegate.registerRepositoriesIn(registry, getRepositoryConfigurationExtension());
	}

    。。。。。

}

Spring Data中Repository对于Redis的支持可以查看此篇博客
 

1.7:RedisReactiveAutoConfiguration 

此类是redis对于响应式编程的支

@Configuration(proxyBeanMethods = false)
//Flux类 所属reactor包中 需要在maven依赖中添加
@ConditionalOnClass({ ReactiveRedisConnectionFactory.class, ReactiveRedisTemplate.class, Flux.class })
//在RedisAutoConfiguration启动之后执行
@AutoConfigureAfter(RedisAutoConfiguration.class)
public class RedisReactiveAutoConfiguration {

        //创建响应式编码类
	@Bean
	@ConditionalOnMissingBean(name = "reactiveRedisTemplate")
        //必须要求自定义创建ReactiveRedisConnectionFactory实例bean
	@ConditionalOnBean(ReactiveRedisConnectionFactory.class)
	public ReactiveRedisTemplate<Object, Object> reactiveRedisTemplate(
			ReactiveRedisConnectionFactory reactiveRedisConnectionFactory, ResourceLoader resourceLoader) {
		JdkSerializationRedisSerializer jdkSerializer = new JdkSerializationRedisSerializer(
				resourceLoader.getClassLoader());
		RedisSerializationContext<Object, Object> serializationContext = RedisSerializationContext
				.newSerializationContext().key(jdkSerializer).value(jdkSerializer).hashKey(jdkSerializer)
				.hashValue(jdkSerializer).build();
		return new ReactiveRedisTemplate<>(reactiveRedisConnectionFactory, serializationContext);
	}

	@Bean
	@ConditionalOnMissingBean(name = "reactiveStringRedisTemplate")
        //必须要求自定义创建ReactiveRedisConnectionFactory实例bean
	@ConditionalOnBean(ReactiveRedisConnectionFactory.class)
	public ReactiveStringRedisTemplate reactiveStringRedisTemplate(
			ReactiveRedisConnectionFactory reactiveRedisConnectionFactory) {
		return new ReactiveStringRedisTemplate(reactiveRedisConnectionFactory);
	}

}

Demo所在Git地址:https://github.com/fangyuan94/redisDemo

 

 

Redis教程四(Springboot集成Redis) Springboot操作数据:spring-data jpa jdbc mongodb redis Springdata也是和springboot齐名的项目 说明:在springboot2.X之后,原来使用的jedis被替换为lettuce Jedis:采用的直连,多个线程操作的话,是不安全的,如果响应避免不安全的,使用jedis pool连接池,更像BIO模式 Lettuce:采用netty,实例可以再多个线程中进行共享,不存在线程不安全的情况,可以减少线程数据,更像是NIO模式 1. 源码分析 阅读详情

相关推荐

spring boot 2.1学习笔记【九】SpringBoot 2 集成redis

springboot2.X 集成redis非常简单,只需要引入依赖包,配置数据源连接池,就可以直接使用redisTemplate了。 注意:springboot 2.X 版本使用lettuce连接池来替换jedis。Lettuce和Jedis都是连接Redis Server的客户端程序,Jedis在实现上是直连redis server,多线...

刘本龙的专栏 5354

day10 分布式缓存

Redis 如何判断某个 key 应该在哪个实例?将 16384 个插槽分配到不同的实例根据 key 的有效部分计算哈希值,然后对 16384 取余余数作为插槽,寻找插槽所在实例即可如何将同一类数据固定的保存在同一个 Redis 实例?将这一类数据使用相同的有效部分,例如 key 都以{typeId}为前缀。

JavaAlenboy 786

Golang实现企业级AI智能体安全合规自动化检测系统

需求:自动化解析欧盟AI法案、中国网络安全法、美国NIST框架等多国法规,提取具体合规要求并映射到企业技术实现。技术挑战法规文本非结构化,语义复杂,存在大量法律术语与技术术语交叉多语言支持(中文、英文、欧盟24种官方语言)法规动态更新(平均每季度更新2-3次)架构创新性:提出了"规则引擎+AI模型+实时监控"的混合架构,兼顾了合规要求的明确性与智能体行为的动态性。性能突破:通过Golang协程、多级缓存、数据库优化等技术,实现了12,800 req/s的高吞吐量和38ms的低延迟。准确性提升。

shao.bing的专栏 722

Redis进阶 - Redis哨兵

原文首更地址,阅读效果更佳!Redis进阶 - Redis哨兵 | CoderMast编程桅杆思考slave 节点宕机恢复以后可以找 master 节点同步数据,那么 master 节点宕机怎么办?

一个编程爱好者的博客 2965

【ESP32开发】——开发环境搭建(VSCode+PlatformIO)

本章内容主要介绍ESP32的开发环境搭建(基于VSCode+PlatformIO)的流程与相应的注意事项,避免开发ESP32止于环境搭建!在项目的维护过程中,可以更好地管理和更新代码、调试问题,并且能够快速适应和采用新的功能、库或硬件平台。:VSCode 的代码提示和自动补全功能,以及 PlatformIO 的管理工具,都能帮助你编写规范、格式良好且易于阅读的代码。:Arduino 框架是一种简单、易用的嵌入式开发框架,适用于快速原型开发和小型项目。需要选择对应自己开发的开发板型号。

m0_61934621的博客 8417

ARM 汇编指令:LSL(逻辑左移) 和 LSR(逻辑右移)

ARM 汇编中的 LSL(逻辑左移)和 LSR(逻辑右移)是基础移位指令,分别实现二进制位的左移和右移操作。LSL 低位补0,等效于乘以2^n;LSR 高位补0,等效于无符号除以2^n。这两个指令可以单独使用或与其他指令结合(如ADD、MOV等),利用ARM的"桶形移位器"硬件实现高效运算。关键特性包括:移位范围0-31(LSL)或1-32(LSR),可选更新标志位,以及与其他指令结合时的无额外开销优势。LSR与ASR(算术右移)的主要区别在于高位填充方式,分别适用于无符号和有符号数处理

guigenyi的专栏 1812

Springboot 中 Redis 自动配置源码分析

Springboot 中 Redis 自动配置源码分析

donkeyboy001的博客 2286

给IC设计新人的Tessent Scan入门指南:从RTL到ATPG的完整DFT流程解析

本文为IC设计新手提供Tessent Scan的完整DFT流程指南,从RTL代码检查到ATPG测试向量生成,详细解析扫描链配置、插入及验证的关键步骤。通过实战案例和工具命令示例,帮助工程师快速掌握Tessent工具链的应用技巧,提升芯片可测试性设计的效率和质量。

weixin_32541663的博客 451

Spring Boot整合Redis缓存(Lettuce)

* springBoot集成redis*

志豪的博客 1914

在VM虚拟机的MobaXterm下安装JDK17

本文介绍了在Linux系统下安装配置JDK17的完整步骤:1)从Oracle或OpenJDK官网下载Linux版JDK17压缩包;2)上传至/usr/local目录;3)解压安装包;4)通过编辑/etc/profile文件配置环境变量,添加JAVA_HOME和PATH路径;5)使用source命令使配置生效;6)通过javac -version验证安装是否成功。整个过程涵盖了从下载到环境配置的完整流程,确保Java开发环境正确设置。

qq_2937655951的博客 442

Tushare Day2——了解stock_basic数据并根据行业和地区进行统计

了解stock_basic数据 1  stock_basic基础信息2  导入包和stock_basic数据、查看基本信息3  根据行业列进行统计3.1  1.先把不同行业列举出来,看一下一共有多少种行业3.2  2.统计每个行业分别有多少家公司3.3  3.把行业从array的二维数组形式变成list形式3.4  4.把行业从list形式转换成文本形式3.5&nbsp

绒绒的Routine 2796

springboot整合redis集群

一、建立redis主从集群 启动多个redis,其他从属redis通过slaveof IP号 端口号绑定主redis,只有主redis可以写数据,其他从redis只能读取数据,同时自动会进行数据同步 二、搭建哨兵集群 1.复制多份redis,每一个redis新建一个sentinel.conf文件,并写入下面的代码 2.启动命令,这里使用的window搭建的 三、springboot整合redis哨兵集群 1.yml 这里的nodes是哨兵集群的IP地址 2.配置LettuceClientConfigurat

weixin_45390688的博客 8651

滑模控制理论(SMC)概述

滑模控制理论(SMC)概述一、背景二、数学理论三、高维拓展四、分析 一、背景 滑模控制理论(Sliding Mode Control, SMC)是一种建立在现代控制理论基础上的控制理论,主要数学核心为李雅普诺夫函数。 滑模控制的核心思想是建立一个滑模面,将被控系统拉取到滑模面上来,使系统沿着滑模面运动。滑模控制的一个优势是无视外部扰动和不确定参数,采用一种比较“暴力”的方式达到控制的目的。 其思想和反步法有些类似,但数学实现起来更加方便而不抽象。相比反步法,滑模控制没有复杂的数学计算,也不会出现“微分爆炸”

高能阿博特的博客 6万+

springboot集成redis实现原理分析

我们知道,在 springboot 1.5.x版本的默认的Redis客户端是 Jedis实现的,需要导入jedis依赖,springboot 2.x版本中默认客户端是用 lettuce实现的,需要导入spring-boot-starter-data-redis依赖。这两种方式使用的都是 TCP协议.Jedis使用直连方式连接Redis Server,在多线程环境下存在线程安全问题, 因此需要增加连接池来解决线程安全的问题,

blueheartstone的博客 3130

10年上位机开发踩过的20个坑:C#通信/线程/UI适配避坑指南

通信层:所有通信操作异步化、异常全覆盖,加断线重连+心跳检测,多设备隔离资源;线程层:UI更新必做跨线程判断,共享数据加锁,线程池限流,异常不静默;UI层:适配高分屏/DPI,用布局容器替代固定坐标,多屏场景绑定主屏幕。

这里只有干货:从 Modbus 通信到 MES 对接,从 YOLO 训练到工控机部署,带你搞定工业软件开发全流程。 904

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

2018最新SpringBoot2.X 系列讲解

本人闲暇中录制了一套SpringBoot2.X最新的。 有兴趣的可以去百度云下载观看,一共也就三四个小时吧,上手很容易 链接:https://pan.baidu.com/s/1mFSxtwkVRpKPlnta6jZxFw 密码:mv6k 如果大家有兴趣也可以进我的群:590583588,一起聊聊技术。 01、SpringBoot简介 02、HelloWorld 03、详细介绍HelloW...

2012年开始工作,全栈开发老兵,目前已是一个老师,分享这么多年的心得体会 4288

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

【Redis】SpringBoot整合Redis源码分析

一.Jedis被替换了 在SpringBoot2.x之后,原来使用的jedis被替换为了lettuce,从spring-boot-starter-data-redis-2.2.5.RELEASE.pom中可以看出来,为啥被替换了查阅资料是说 jedis:采用的直连,多个线程操作的话,是不安全的,如果想要避免不安全使用jedis pool连接池!更像BIO模式 lettuce:采用netty,实例可以再多个线程中进行共享,不存在线程不安全的情况,可以减少线程的数据,更像NIO模式。 二..

wistchen 1130

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

Jedis使用和SpringBoot与Redis整合

Jedis 我们要使用java 来操作redis 什么是Jedis: Jedis是Redis官方推荐的java连接开发工具,使用java操作Redis中间件。 1、导入jar包 <!--导入jedis的jar包--> <dependencies> <!-- https://mvnrepository.com/artifact/redis.clients/jedis --> <dependency>

qq_43430343的博客 627

SpringBoot整合Redis

springboot整合redis

奔走的王木木Sir的博客 2150

springboot2.x +redis使用和源码分析二(RedisTemplate)

目录 序言:本文讲述RedisTemplate对象如何构建以及该对象对于redis提供的功能的支持 1:定义RedisTemplate 2:基本使用Ddemo 3:RedisTemplate对Pipelined支持 4:RedisTemplate对事务支持 5:RedisTemplate对Lua语言支持 5.1:使用内置字符串形式 5.2:以文件的形式 5.3:使用Lua的一些应...

F_Hello_World的博客 1239

SpringBoot集成Redis

SpringBoot集成Redis 文章目录SpringBoot集成Redis1、概述2、测试Redis3、自定义redisTemplate 1、概述 Redis是什么? Redis(Remote Dictionary Server ),即远程字典服务。 是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。 与memcached一样,为了保证效率,数据都是缓存在内存中。区别的是redis会周期性的把更新的数据写入磁盘或者把修改操

... 1310

Springboot整合redis与缓存

文章目录Springboot整合源码分析整合测试自定义序列化Redis.conf讲解单位包含网络配置通用GENERAL快照SECURITY安全限制CLIENTSAPPEND ONLY 模式Redis持久化RDB触发机制如何恢复rdb文件优点:缺点:AOF(Append Only File)重写规则aof优点和缺点优点:缺点Redis发布订阅测试原理微信:使用场景:Redis主从复制**概念**环境配置复制原理链路模式哨兵模式(自动选举老大)概述:这里哨兵只有两个作用测试哨兵模式优缺点哨兵模式全部配置Redi

qq_52329552的博客 2961

SpringBoot(十九)集成Redis

如果有收获!!! 希望老铁们来个三连,点赞、收藏、转发。 创作不易,别忘点个赞,可以让更多的人看到这篇文章,顺便鼓励我写出更好的博客

星海IT学习之路 1435

Redis学习--SpringBoot整合Redis

SpringBoot整合Redis1. 导入依赖2. 配置application.propertie3. RedisAutoConfiguration 源码分析4. 自定义RedisConfig5. 简单测试一下6. 使用StringRedisTemplate7. 使用RedisTemplate8. 使用boundXXXOps()9. 封装Redis工具类 1. 导入依赖 SpringBoot2.x之后,原来使用的jedis被替换为了 lettuce <!--操作Redis-->

463

SpringBoot学习小结之Redis

Redis是一个持久化在磁盘上的内存数据库,支持多种数据类型Redis和Mencashed对比总而言之,Redis提供了非常丰富的功能,而且性能基本上与Memcached相差无几,这也是它最近这几年占领内存数据库鳌头的原因。在技术选型方面,如果你的业务需要各种数据结构给予支撑,同时要求数据的高可用保障,那么选择Redis是比较合适的,但是如果你的业务非常简单,只是简单的set/get,并且对于内存使用并不高,那么使用Memcached足够了。...

十十办文武的博客 1576

Springboot Redis客户端配置及初始化过程源码解读

spring boot集成redis,配置比较简单,网上存在不同的配置。为什么有不同的配置文件? spring boot是如何加载redis的呢? 为了搞清楚背后的机制,阅读源码一探究竟。 1: spring boot 集成redis 为什么存在不同的配置文件 在spring boot 1.x.x集成redis时,默认jedis作为连接客户端。由于jedis是直连模式,在...

wiseyl的专栏 4954
上一篇: 自定义Dockerfile安装Redis单点
下一篇: springboot2.x +redis使用和源码分析二(RedisTemplate)
F_Hello_World
博客等级 码龄11年 38粉丝 58原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值