1)传统ssm整合redis的时候 需要在xml的配置文件中 进行大量的配置Bean

我们在这里使用springboot来代替ssm的整合,只是通过xml的形式来整合redis

第一步:加入配置

<dependency><groupId>org.springframework.data</groupId><artifactId>spring-data-redis</artifactId><version>2.0.9.RELEASE</version>
</dependency><dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId><version>2.9.0</version>
</dependency>

第二步: 配置xml的bean的配置

    //配置连接池<bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig"><property name="minIdle" value="10"></property><property name="maxTotal" value="20"></property></bean>//配置连接工厂<bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"><property name="hostName" value="47.104.128.12"></property><property name="password" value="123456"></property><property name="database" value="0"></property><property name="poolConfig" ref="poolConfig"></property></bean>//配置 redisTemplate 模版类<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate"><property name="connectionFactory"  ref="jedisConnectionFactory"/><!--如果不配置Serializer,那么存储的时候缺省使用String,如果用User类型存储,那么会提示错误User can't cast to String!!  --><property name="keySerializer"><bean class="org.springframework.data.redis.serializer.StringRedisSerializer"/></property><property name="valueSerializer"><bean class="org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer"/></property><property name="hashKeySerializer"><bean class="org.springframework.data.redis.serializer.StringRedisSerializer"/></property><property name="hashValueSerializer"><bean class="org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer"/></property></bean>

第三步:导入配置

@ImportResource(locations = "classpath:beans.xml") 可以导入xml的配置文件

@SpringBootApplication
@ImportResource(locations = "classpath:beans.xml")
@RestController
public class TulingOpenAutoconfigPrincipleApplication {@Autowiredprivate RedisTemplate redisTemplate;public static void main(String[] args) {SpringApplication.run(TulingOpenAutoconfigPrincipleApplication.class, args);}@RequestMapping("/testRedis")public String testRedis() {redisTemplate.opsForValue().set("smlz","smlz");return "OK";}
}

2)综上所述 我们发现,若整合redis的时候通过传统的整合,进行了大量的配置,那么我们来看下通过springboot自动装配整合的对比

导入依赖:

     <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency>

修改yml配置文件

spring.redis.host=47.104.128.12
spring.redis.port=6379
spring.redis.password=123456

直接使用(下述代码可以不要配置,为了解决保存使用jdk的序列方式才配置的)

  @Beanpublic RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory)  {RedisTemplate<Object, Object> template = new RedisTemplate<>();template.setDefaultSerializer(new Jackson2JsonRedisSerializer<Object>(Object.class));template.setConnectionFactory(redisConnectionFactory);return template;}​

3)传统整合和springboot自动装配 优劣势分析。。。。。。。。。。。。

4)自动装配原理前的不得不说的几个注解

4.1)通过@Import注解来导入ImportSelector组件

①:写一个配置类在配置类上标注一个@Import的注解,

@Configuration
@Import(value = {TulingSelector.class})
public class TulingConfig {
}​

②:在@Import注解的value值 写自己需要导入的组件

在selectImports方法中 就是你需要导入组件的全类名

public class TulingSelector implements ImportSelector {@Overridepublic String[] selectImports(AnnotationMetadata annotationMetadata) {return new String[]{"com.tuling.service.TulingServiceImpl"};}
}

核心代码:

@RestController
public class TulingController {//自动注入 tulingServiceImpl@Autowiredprivate TulingServiceImpl tulingServiceImpl;@RequestMapping("testTuling")public String testTuling() {tulingServiceImpl.testService();return "tulingOk";}
}这里是没有标注其他注解提供给spring包扫描的
public class TulingServiceImpl {public void testService() {System.out.println("我是通过importSelector导入进来的service");}
}

1.2)通过@Import导入ImportBeanDefinitionRegistrar 从而进来导入组件

核心代码:

public class TulingImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {@Overridepublic void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanDefinitionRegistry beanDefinitionRegistry) {//定义一个BeanDefinitionRootBeanDefinition rootBeanDefinition = new RootBeanDefinition(TulingDao.class);//把自定义的bean定义导入到容器中beanDefinitionRegistry.registerBeanDefinition("tulingDao",rootBeanDefinition);}
}​通过ImportSelector功能导入进来的
public class TulingServiceImpl {@Autowiredprivate TulingDao tulingDao;public void testService() {tulingDao.testTulingDao();System.out.println("我是通过importSelector导入进来的service");}
}通过ImportBeanDefinitionRegistar导入进来的
public class TulingDao {public void testTulingDao() {System.out.println("我是通过ImportBeanDefinitionRegistrar导入进来tulingDao组件");}
}

测试结果:

1.3)spring底层条件装配的原理@Conditional

应用要求:比如我有二个组件,一个是TulingLog 一个是TulingAspect

而TulingLog 是依赖TulingAspect的 只有容器中有TulingAspect组件才会加载TulingLog

tulingLog组件  依赖TulingAspect组件
public class TulingLog {
}tulingAspect组件
public class TulingAspect {
}

①:自定义条件组件条件

public class TulingConditional implements Condition {@Overridepublic boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {//容器中包含tulingAspect组件才返回Tureif(conditionContext.getBeanFactory().containsBean("tulingAspect")){return true;}else{return false;}}
}-------------------------------------该情况下会加载二个组件-------------------------------------------------@Beanpublic TulingAspect tulingAspect() {System.out.println("TulingAspect组件自动装配到容器中");return new TulingAspect();}@Bean@Conditional(value = TulingConditional.class)public TulingLog tulingLog() {System.out.println("TulingLog组件自动装配到容器中");return new TulingLog();}-------------------------------------二个组件都不会被加载----------------------------------------/*@Bean**/public TulingAspect tulingAspect() {System.out.println("TulingAspect组件自动装配到容器中");return new TulingAspect();}@Bean@Conditional(value = TulingConditional.class)public TulingLog tulingLog() {System.out.println("TulingLog组件自动装配到容器中");return new TulingLog();}

自动装配原理分析 从@SpringbootApplication入手分析

那我们仔细分析

org.springframework.boot.autoconfigure.AutoConfigurationImportSelector#selectImports

public class AutoConfigurationImportSelectorimplements DeferredImportSelector, BeanClassLoaderAware, ResourceLoaderAware,BeanFactoryAware, EnvironmentAware, Ordered {@Overridepublic String[] selectImports(AnnotationMetadata annotationMetadata) {if (!isEnabled(annotationMetadata)) {return NO_IMPORTS;}AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader.loadMetadata(this.beanClassLoader);AnnotationAttributes attributes = getAttributes(annotationMetadata);//去mata-info/spring.factories文件中 查询 EnableAutoConfiguration对于值List<String> configurations = getCandidateConfigurations(annotationMetadata,attributes);//去除重复的配置类,若我们自己写的starter 可能存主重复的configurations = removeDuplicates(configurations);Set<String> exclusions = getExclusions(annotationMetadata, attributes);checkExcludedClasses(configurations, exclusions);configurations.removeAll(exclusions);//根据maven 导入的启动器过滤出 需要导入的配置类configurations = filter(configurations, autoConfigurationMetadata);fireAutoConfigurationImportEvents(configurations, exclusions);return StringUtils.toStringArray(configurations);}
}   //去spring.factories 中去查询EnableAutoConfirution类private static Map<String, List<String>> loadSpringFactories(@Nullable ClassLoader classLoader) {MultiValueMap<String, String> result = cache.get(classLoader);if (result != null) {return result;}try {Enumeration<URL> urls = (classLoader != null ?classLoader.getResources(FACTORIES_RESOURCE_LOCATION) :ClassLoader.getSystemResources(FACTORIES_RESOURCE_LOCATION));result = new LinkedMultiValueMap<>();while (urls.hasMoreElements()) {URL url = urls.nextElement();UrlResource resource = new UrlResource(url);Properties properties = PropertiesLoaderUtils.loadProperties(resource);for (Map.Entry<?, ?> entry : properties.entrySet()) {List<String> factoryClassNames = Arrays.asList(StringUtils.commaDelimitedListToStringArray((String) entry.getValue()));result.addAll((String) entry.getKey(), factoryClassNames);}}cache.put(classLoader, result);return result;}catch (IOException ex) {throw new IllegalArgumentException("Unable to load factories from location [" +FACTORIES_RESOURCE_LOCATION + "]", ex);}}

然后我们分析RedisAutoConfiguration类

导入了三个组件 RedisTemplate StringRedisTemplate JedisConnectionConfiguration

@Configuration
@ConditionalOnClass(RedisOperations.class)
@EnableConfigurationProperties(RedisProperties.class)
@Import({ LettuceConnectionConfiguration.class, JedisConnectionConfiguration.class })
public class RedisAutoConfiguration {//导入redisTemplate @Bean@ConditionalOnMissingBean(name = "redisTemplate")public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) throws UnknownHostException {RedisTemplate<Object, Object> template = new RedisTemplate<>();template.setConnectionFactory(redisConnectionFactory);return template;}@Bean@ConditionalOnMissingBeanpublic StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory) throws UnknownHostException {StringRedisTemplate template = new StringRedisTemplate();template.setConnectionFactory(redisConnectionFactory);return template;}}=====================================JedisConnectionConfiguration==========================================@Configuration
@ConditionalOnClass({ GenericObjectPool.class, JedisConnection.class, Jedis.class })
class JedisConnectionConfiguration extends RedisConnectionConfiguration {private final RedisProperties properties;private final List<JedisClientConfigurationBuilderCustomizer> builderCustomizers;JedisConnectionConfiguration(RedisProperties properties,ObjectProvider<RedisSentinelConfiguration> sentinelConfiguration,ObjectProvider<RedisClusterConfiguration> clusterConfiguration,ObjectProvider<List<JedisClientConfigurationBuilderCustomizer>> builderCustomizers) {super(properties, sentinelConfiguration, clusterConfiguration);this.properties = properties;this.builderCustomizers = builderCustomizers.getIfAvailable(Collections::emptyList);}@Bean@ConditionalOnMissingBean(RedisConnectionFactory.class)public JedisConnectionFactory redisConnectionFactory() throws UnknownHostException {return createJedisConnectionFactory();}private JedisConnectionFactory createJedisConnectionFactory() {JedisClientConfiguration clientConfiguration = getJedisClientConfiguration();if (getSentinelConfig() != null) {return new JedisConnectionFactory(getSentinelConfig(), clientConfiguration);}if (getClusterConfiguration() != null) {return new JedisConnectionFactory(getClusterConfiguration(),clientConfiguration);}return new JedisConnectionFactory(getStandaloneConfig(), clientConfiguration);}private JedisClientConfiguration getJedisClientConfiguration() {JedisClientConfigurationBuilder builder = applyProperties(JedisClientConfiguration.builder());RedisProperties.Pool pool = this.properties.getJedis().getPool();if (pool != null) {applyPooling(pool, builder);}if (StringUtils.hasText(this.properties.getUrl())) {customizeConfigurationFromUrl(builder);}customize(builder);return builder.build();}private JedisClientConfigurationBuilder applyProperties(JedisClientConfigurationBuilder builder) {if (this.properties.isSsl()) {builder.useSsl();}if (this.properties.getTimeout() != null) {Duration timeout = this.properties.getTimeout();builder.readTimeout(timeout).connectTimeout(timeout);}return builder;}private void applyPooling(RedisProperties.Pool pool,JedisClientConfiguration.JedisClientConfigurationBuilder builder) {builder.usePooling().poolConfig(jedisPoolConfig(pool));}private JedisPoolConfig jedisPoolConfig(RedisProperties.Pool pool) {JedisPoolConfig config = new JedisPoolConfig();config.setMaxTotal(pool.getMaxActive());config.setMaxIdle(pool.getMaxIdle());config.setMinIdle(pool.getMinIdle());if (pool.getMaxWait() != null) {config.setMaxWaitMillis(pool.getMaxWait().toMillis());}return config;}
}   

springboot 整合redis_springboot自动装配原理详解相关推荐

  1. Spring Boot自动装配原理详解

    目录 1.环境和依赖 1.1.spring boot版本 1.2.依赖管理 2.自动装配 2.1.流程概述 2.2.三大步前的准备工作 2.2.1.注解入口 2.2.2.获取所有配置类 2.3.获取过 ...

  2. 雷神SpringBoot入门和自动装配原理

    SpringBoot-helloWord! 首先让当前的工程作为Springboot的子工程 <parent><groupId>org.springframework.boot ...

  3. SpringBoot--自动装配原理详解及应用之Conditional注解

    SpringBoot作为当今开发的主流框架,作为一名java开发是不可能的不了解的,这个东西是典型的用起来很简单,但是了解到原理之后就会不自觉地感叹,真TMNB! 本文主要讲解其自动装配的原理,以及我 ...

  4. Spring框架中 自动装配的详解 属性值的详解

    手动装配实现属性注入 <bean id="studentDao" class="com.xz.dao.impl.StudentDaoImpl">&l ...

  5. Spring自动装配机制详解

    一.什么是自动装配? 自动装配就是会通过Spring的上下文为你找出相应依赖项的类,通俗的说就是Spring会在上下文中自动查找,并自动给Bean装配与其相关的属性! spring中实现自动装配的方式 ...

  6. 万字长文,图文并茂的给你讲清SpringBoot注解,自动装配原理!

    你知道的越多,不知道的就越多,业余的像一棵小草! 你来,我们一起精进!你不来,我和你的竞争对手一起精进! 编辑:业余草 cnblogs.com/jing99/p/11504113.html 推荐:ht ...

  7. SpringBoot自动装配原理浅析

    Springboot自动装配原理 SpringBoot是当下J2EE最为流行的框架,它有着轻量,快捷等特点,让程序员们可以专注在业务逻辑的编写上,而不用花太多的力气在一些环境的配置,整合组件的配置上面 ...

  8. Spring Boot底层原理详解及整合

    Spring Boot框架 通过Spring Boot 可以构建一个基于Spring框架的Java Application,简化配置,自动装配,开箱即用 JavaConfiguration用Java类 ...

  9. 【SpringBoot】自动装配原理

    [SpringBoot]自动装配原理 文章目录 [SpringBoot]自动装配原理 一.pom.xml 1.spring-boot-dependencies 2.spring-boot-starte ...

最新文章

  1. 聊聊高并发(十六)实现一个简单的可重入锁
  2. 安卓虚拟机启动后报错: 类似 SDK Manager] Error: Error parsing .....devices.xml 解决方案
  3. Windows 10 系统版本更新历史
  4. Linux 下 VuePress 的安装使用
  5. UOJ #585. 新年和多米诺
  6. 《软件工艺师:专业、务实、自豪》一2.8 小结
  7. java中launch方法,Java AppUtils.launchApp方法代码示例
  8. 解决eclipse中jsp没有代码提示问题
  9. 微信喊你来找工作:上千家企业将提供超10万个就业岗位
  10. keil5——常见报错【cannot load flash device description】
  11. php 异步执行脚本,PHP语言实现脚本异步执行_PHP教程
  12. dell自带的测试软件,Dell System Detect
  13. c# 开发ActiveX控件
  14. 搭建ELK-流水账-只记思路
  15. PCWorld:流量日趋集中 大公司影响整个互联网
  16. 香港科大【526清水湾思享会@杭州】暨香港科大EMBA第四届校友会【浙江分会】启动仪式成功举行...
  17. html时区时间显示,JS显示多个国家时区当前时间代码
  18. 最新 2022 年云原生Kubernetes 高级面试题大全(持续更新中)
  19. 【DeepMind】新算法MuZero在Atari基准上取得了新SOTA效果,成果问鼎Nature
  20. 【C#进阶二】C#中的正则表达式知识总结(字符转义/字符类/ 定位点/ 分组构造 /数量词/反向引用构造/替换构造/替代/正则表达式选项)(理论篇)

热门文章

  1. spring boot 整合 mybatis
  2. Atlas 配置高可用
  3. 7.4 流水线的冒险
  4. uva 11178(几何)
  5. HDU 1827 Summer Holiday 图论scc
  6. java锁的膨胀过程和优化
  7. Visual Studio 11 九大新特性:图文详解【转】
  8. (转) shiro权限框架详解06-shiro与web项目整合(上)
  9. (转)postgis常用函数介绍(一)
  10. SSH2整合需要jar包解释