详细聊聊Spring核心思想( 三 )


基于这些扩展点就能实现很多功能,例如 Bean 的选择性加载、占位符的替换、代理类(事务等)的生成 。
好比 SpringBoot redis 客户端的选择,默认会导入 lettuce 和 jedis两个客户端配置

详细聊聊Spring核心思想

文章插图
 
基于配置的先后顺序会优先导入 lettuce,然后再导入 jedis 。
如果扫描发现有 lettuce 那么就用 lettuce 的 RedisConnectionFactory,而后面再加载 jedis 时,会基于@ConditionalOnMissingBean(RedisConnectionFactory.class) 来保证 jedis不会被注入,反之就会被注入 。
详细聊聊Spring核心思想

文章插图
 
ps:@ConditionalOnMissingBean(xx.class) 如果当前没有xx.class才能生成被这个注解修饰的bean
就上面这个特性就是基于 Spring 提供的扩展点来实现的 。
很灵活地让我们替换所需的 redis 客户端,不用改任何使用的代码,只需要改个依赖,比如要从默认的 lettuce 变成 jedis,只需要改个 maven 配置,去除 lettuce 依赖,引入 jedis:
<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><dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId></dependency>说这么多其实就是想表达:Spring 全家桶提供的这些扩展和封装可以灵活地满足我们的诸多需求,而这些灵活都是基于 Spring 的核心 IOC 和 AOP 而来的 。
最后最后我用一段话来简单描述下 Spring 的原理:
Spring 根据我们提供的配置类和XML配置文件,解析其中的内容,得到它需要管理的 Bean 的信息以及之间的关联,并且 Spring 暴露出很多扩展点供我们定制,如 BeanFactoryPostProcessor、BeanPostProcessor,我们只需要实现这个接口就可以进行一些定制化的操作 。
Spring 得到 Bean 的信息后会根据反射来创建 Bean 实例,组装 Bean 之间的依赖关系,其中就会穿插进原生的或我们定义的相关PostProcessor来改造Bean,替换一些属性或代理原先的 Bean 逻辑 。
最终创建完所有配置要求的Bean,将单例的 Bean 存储在 map 中,提供 BeanFactory 供我们获取使用 Bean 。
使得我们编码过程无需再关注 Bean 具体是如何创建的,也节省了很多重复性地编码动作,这些都由我们创建的机器——Spring帮我们代劳 。
大概就说这么多了,我自己读了几遍也不知道到底有没有把我想表达的东西说明白,其实我本来从源码层面来聊这个核心的,但是怕更难说清 。

【详细聊聊Spring核心思想】


推荐阅读