Java学习指南
  • Java 编程的逻辑
  • Java进阶
  • Java FrameWorks
  • 了解 USB Type-A,B,C 三大标准接口
  • 深入浅出DDD
  • 重构:改善既有代码的设计
  • 面试大纲
  • 云原生
    • 什么是无服务器(what is serverless)?
  • 博客
    • 深入分析Log4j 漏洞
  • 博客
    • Serverless之快速搭建Spring Boot应用
  • 博客
    • 使用 Prometheus + Grafana + Spring Boot Actuator 监控应用
  • 博客
    • 使用 Prometheus + Grafana 监控 MySQL
  • 博客
    • 使用Github Actions + Docker 部署Spring Boot应用
  • 博客
    • Redis分布式锁之Redisson的原理和实践
  • 博客
    • 数据库中的树结构应该怎样去设计
  • 学习&成长
    • 如何成为技术大牛
  • 开发工具
    • Git Commit Message Guidelines
  • 开发工具
    • git命名大全
  • 开发工具
    • Gradle vs Maven Comparison
  • 开发工具
    • Swagger2常用注解及其说明
  • 开发工具
    • 简明 VIM 练级攻略
  • 微服务
    • 十大微服务设计模式和原则
  • 微服务
    • 微服务下的身份认证和令牌管理
  • 微服务
    • 微服务坏味道之循环依赖
  • 设计模式
    • 设计模式 - JDK中的设计模式
  • 设计模式
    • 设计模式 - Java三种代理模式
  • 设计模式
    • 设计模式 - 六大设计原则
  • 设计模式
    • 设计模式 - 单例模式
  • 设计模式
    • 设计模式 - 命名模式
  • 设计模式
    • 设计模式 - 备忘录模式
  • 设计模式
    • 设计模式 - 概览
  • 设计模式
    • 设计模式 - 没用的设计模式
  • 质量&效率
    • Homebrew 替换国内镜像源
  • 质量&效率
    • 工作中如何做好技术积累
  • Java FrameWorks
    • Logback
      • 自定义 logback 日志过滤器
  • Java FrameWorks
    • Mybatis
      • MyBatis(十三) - 整合Spring
  • Java FrameWorks
    • Mybatis
      • MyBatis(十二) - 一些API
  • Java FrameWorks
    • Mybatis
      • Mybatis(一) - 概述
  • Java FrameWorks
    • Mybatis
      • Mybatis(七) - 结果集的封装与映射
  • Java FrameWorks
    • Mybatis
      • Mybatis(三) - mapper.xml及其加载机制
  • Java FrameWorks
    • Mybatis
      • Mybatis(九) - 事务
  • Java FrameWorks
    • Mybatis
      • Mybatis(二) - 全局配置文件及其加载机制
  • Java FrameWorks
    • Mybatis
      • Mybatis(五) - SqlSession执行流程
  • Java FrameWorks
    • Mybatis
      • Mybatis(八) - 缓存
  • Java FrameWorks
    • Mybatis
      • Mybatis(六) - 动态SQL的参数绑定与执行
  • Java FrameWorks
    • Mybatis
      • Mybatis(十) - 插件
  • Java FrameWorks
    • Mybatis
      • Mybatis(十一) - 日志
  • Java FrameWorks
    • Mybatis
      • Mybatis(四) - Mapper接口解析
  • Java FrameWorks
    • Netty
      • Netty 可靠性分析
  • Java FrameWorks
    • Netty
      • Netty - Netty 线程模型
  • Java FrameWorks
    • Netty
      • Netty堆外内存泄露排查盛宴
  • Java FrameWorks
    • Netty
      • Netty高级 - 高性能之道
  • Java FrameWorks
    • Shiro
      • Shiro + JWT + Spring Boot Restful 简易教程
  • Java FrameWorks
    • Shiro
      • 非常详尽的 Shiro 架构解析!
  • Java FrameWorks
    • Spring
      • Spring AOP 使用介绍,从前世到今生
  • Java FrameWorks
    • Spring
      • Spring AOP 源码解析
  • Java FrameWorks
    • Spring
      • Spring Event 实现原理
  • Java FrameWorks
    • Spring
      • Spring Events
  • Java FrameWorks
    • Spring
      • Spring IOC容器源码分析
  • Java FrameWorks
    • Spring
      • Spring Integration简介
  • Java FrameWorks
    • Spring
      • Spring MVC 框架中拦截器 Interceptor 的使用方法
  • Java FrameWorks
    • Spring
      • Spring bean 解析、注册、实例化流程源码剖析
  • Java FrameWorks
    • Spring
      • Spring validation中@NotNull、@NotEmpty、@NotBlank的区别
  • Java FrameWorks
    • Spring
      • Spring 如何解决循环依赖?
  • Java FrameWorks
    • Spring
      • Spring 异步实现原理与实战分享
  • Java FrameWorks
    • Spring
      • Spring中的“for update”问题
  • Java FrameWorks
    • Spring
      • Spring中的设计模式
  • Java FrameWorks
    • Spring
      • Spring事务失效的 8 大原因
  • Java FrameWorks
    • Spring
      • Spring事务管理详解
  • Java FrameWorks
    • Spring
      • Spring计时器StopWatch使用
  • Java FrameWorks
    • Spring
      • 详述 Spring MVC 框架中拦截器 Interceptor 的使用方法
  • Java FrameWorks
    • Spring
      • 透彻的掌握 Spring 中@transactional 的使用
  • Java
    • Java IO&NIO&AIO
      • Java IO - BIO 详解
  • Java
    • Java IO&NIO&AIO
      • Java NIO - IO多路复用详解
  • Java
    • Java IO&NIO&AIO
      • Java N(A)IO - Netty
  • Java
    • Java IO&NIO&AIO
      • Java IO - Unix IO模型
  • Java
    • Java IO&NIO&AIO
      • Java IO - 分类
  • Java
    • Java IO&NIO&AIO
      • Java NIO - 基础详解
  • Java
    • Java IO&NIO&AIO
      • Java IO - 常见类使用
  • Java
    • Java IO&NIO&AIO
      • Java AIO - 异步IO详解
  • Java
    • Java IO&NIO&AIO
      • Java IO概述
  • Java
    • Java IO&NIO&AIO
      • Java IO - 设计模式
  • Java
    • Java IO&NIO&AIO
      • Java NIO - 零拷贝实现
  • Java
    • Java JVM
      • JVM 优化经验总结
  • Java
    • Java JVM
      • JVM 内存结构
  • Java
    • Java JVM
      • JVM参数设置
  • Java
    • Java JVM
      • Java 内存模型
  • Java
    • Java JVM
      • 从实际案例聊聊Java应用的GC优化
  • Java
    • Java JVM
      • Java 垃圾回收器G1详解
  • Java
    • Java JVM
      • 垃圾回收器Shenandoah GC详解
  • Java
    • Java JVM
      • 垃圾回收器ZGC详解
  • Java
    • Java JVM
      • 垃圾回收基础
  • Java
    • Java JVM
      • 如何优化Java GC
  • Java
    • Java JVM
      • 类加载机制
  • Java
    • Java JVM
      • 类字节码详解
  • Java
    • Java 基础
      • Java hashCode() 和 equals()
  • Java
    • Java 基础
      • Java 基础 - Java native方法以及JNI实践
  • Java
    • Java 基础
      • Java serialVersionUID 有什么作用?
  • Java
    • Java 基础
      • Java 泛型的类型擦除
  • Java
    • Java 基础
      • Java 基础 - Unsafe类解析
  • Java
    • Java 基础
      • Difference Between Statement and PreparedStatement
  • Java
    • Java 基础
      • Java 基础 - SPI机制详解
  • Java
    • Java 基础
      • Java 基础 - final
  • Java
    • Java 基础
      • Java中static关键字详解
  • Java
    • Java 基础
      • 为什么说Java中只有值传递?
  • Java
    • Java 基础
      • Java 基础 - 即时编译器原理解析及实践
  • Java
    • Java 基础
      • Java 基础 - 反射
  • Java
    • Java 基础
      • Java多态的面试题
  • Java
    • Java 基础
      • Java 基础 - 异常机制详解
  • Java
    • Java 基础
      • 为什么要有抽象类?
  • Java
    • Java 基础
      • 接口的本质
  • Java
    • Java 基础
      • Java 基础 - 枚举
  • Java
    • Java 基础
      • Java 基础 - 泛型机制详解
  • Java
    • Java 基础
      • Java 基础 - 注解机制详解
  • Java
    • Java 基础
      • 为什么 String hashCode 方法选择数字31作为乘子
  • Java
    • Java 并发
      • Java 并发 - 14个Java并发容器
  • Java
    • Java 并发
      • Java 并发 - AQS
  • Java
    • Java 并发
      • Java 并发 - BlockingQueue
  • Java
    • Java 并发
      • Java 并发 - CAS
  • Java
    • Java 并发
      • Java 并发 - Condition接口
  • Java
    • Java 并发
      • Java 并发 - CopyOnWriteArrayList
  • Java
    • Java 并发
      • Java 并发 - CountDownLatch、CyclicBarrier和Phaser对比
  • Java
    • Java 并发
      • Java 并发 - Fork&Join框架
  • Java
    • Java 并发
      • Java 并发 - Java CompletableFuture 详解
  • Java
    • Java 并发
      • Java 并发 - Java 线程池
  • Java
    • Java 并发
      • Java 并发 - Lock接口
  • Java
    • Java 并发
      • Java 并发 - ReentrantLock
  • Java
    • Java 并发
      • Java 并发 - ReentrantReadWriteLock
  • Java
    • Java 并发
      • Java 并发 - Synchronized
  • Java
    • Java 并发
      • Java 并发 - ThreadLocal 内存泄漏问题
  • Java
    • Java 并发
      • Java 并发 - ThreadLocal
  • Java
    • Java 并发
      • Java 并发 - Volatile
  • Java
    • Java 并发
      • Java 并发 - 从ReentrantLock的实现看AQS的原理及应用
  • Java
    • Java 并发
      • Java 并发 - 公平锁和非公平锁
  • Java
    • Java 并发
      • Java 并发 - 内存模型
  • Java
    • Java 并发
      • Java 并发 - 原子类
  • Java
    • Java 并发
      • Java 并发 - 如何确保三个线程顺序执行?
  • Java
    • Java 并发
      • Java 并发 - 锁
  • Java
    • Java 的新特性
      • Java 10 新特性概述
  • Java
    • Java 的新特性
      • Java 11 新特性概述
  • Java
    • Java 的新特性
      • Java 12 新特性概述
  • Java
    • Java 的新特性
      • Java 13 新特性概述
  • Java
    • Java 的新特性
      • Java 14 新特性概述
  • Java
    • Java 的新特性
      • Java 15 新特性概述
  • Java
    • Java 的新特性
      • Java 8的新特性
  • Java
    • Java 的新特性
      • Java 9 新特性概述
  • Java
    • Java 调试排错
      • 调试排错 - Java Debug Interface(JDI)详解
  • Java
    • Java 调试排错
      • 调试排错 - CPU 100% 排查优化实践
  • Java
    • Java 调试排错
      • 调试排错 - Java Heap Dump分析
  • Java
    • Java 调试排错
      • 调试排错 - Java Thread Dump分析
  • Java
    • Java 调试排错
      • 调试排错 - Java动态调试技术原理
  • Java
    • Java 调试排错
      • 调试排错 - Java应用在线调试Arthas
  • Java
    • Java 调试排错
      • 调试排错 - Java问题排查:工具单
  • Java
    • Java 调试排错
      • 调试排错 - 内存溢出与内存泄漏
  • Java
    • Java 调试排错
      • 调试排错 - 在线分析GC日志的网站GCeasy
  • Java
    • Java 调试排错
      • 调试排错 - 常见的GC问题分析与解决
  • Java
    • Java 集合
      • Java 集合 - ArrayList
  • Java
    • Java 集合
      • Java 集合 - HashMap 和 ConcurrentHashMap
  • Java
    • Java 集合
      • Java 集合 - HashMap的死循环问题
  • Java
    • Java 集合
      • Java 集合 - LinkedHashSet&Map
  • Java
    • Java 集合
      • Java 集合 - LinkedList
  • Java
    • Java 集合
      • Java 集合 - PriorityQueue
  • Java
    • Java 集合
      • Java 集合 - Stack & Queue
  • Java
    • Java 集合
      • Java 集合 - TreeSet & TreeMap
  • Java
    • Java 集合
      • Java 集合 - WeakHashMap
  • Java
    • Java 集合
      • Java 集合 - 为什么HashMap的容量是2的幂次方
  • Java
    • Java 集合
      • Java 集合 - 概览
  • Java
    • Java 集合
      • Java 集合 - 高性能队列Disruptor详解
  • 分布式
    • RPC
      • ⭐️RPC - Dubbo&hsf&Spring cloud的区别
  • 分布式
    • RPC
      • ⭐️RPC - Dubbo的架构原理
  • 分布式
    • RPC
      • ⭐️RPC - HSF的原理分析
  • 分布式
    • RPC
      • ⭐️RPC - 你应该知道的RPC原理
  • 分布式
    • RPC
      • ⭐️RPC - 动态代理
  • 分布式
    • RPC
      • 深入理解 RPC 之协议篇
  • 分布式
    • RPC
      • RPC - 序列化和反序列化
  • 分布式
    • RPC
      • ⭐️RPC - 服务注册与发现
  • 分布式
    • RPC
      • RPC - 核心原理
  • 分布式
    • RPC
      • ⭐️RPC - 框架对比
  • 分布式
    • RPC
      • ⭐️RPC - 网络通信
  • 分布式
    • 分布式事务
      • 分布式事务 Seata TCC 模式深度解析
  • 分布式
    • 分布式事务
      • 分布式事务的实现原理
  • 分布式
    • 分布式事务
      • 常用的分布式事务解决方案
  • 分布式
    • 分布式事务
      • 手写实现基于消息队列的分布式事务框架
  • 分布式
    • 分布式算法
      • CAP 定理的含义
  • 分布式
    • 分布式算法
      • Paxos和Raft比较
  • 分布式
    • 分布式算法
      • 分布式一致性与共识算法
  • 分布式
    • 分布式锁
      • ⭐️分布式锁的原理及实现方式
  • 分布式
    • 搜索引擎
      • ElasticSearch与SpringBoot的集成与JPA方法的使用
  • 分布式
    • 搜索引擎
      • 全文搜索引擎 Elasticsearch 入门教程
  • 分布式
    • 搜索引擎
      • 十分钟学会使用 Elasticsearch 优雅搭建自己的搜索系统
  • 分布式
    • 搜索引擎
      • 腾讯万亿级 Elasticsearch 技术解密
  • 分布式
    • 日志系统
      • Grafana Loki 简明教程
  • 分布式
    • 日志系统
      • 分布式系统中如何优雅地追踪日志
  • 分布式
    • 日志系统
      • 如何优雅地记录操作日志?
  • 分布式
    • 日志系统
      • 日志收集组件—Flume、Logstash、Filebeat对比
  • 分布式
    • 日志系统
      • 集中式日志系统 ELK 协议栈详解
  • 分布式
    • 消息队列
      • 消息队列 - Kafka
  • 分布式
    • 消息队列
      • 消息队列 - Kafka、RabbitMQ、RocketMQ等消息中间件的对比
  • 分布式
    • 消息队列
      • 消息队列之 RabbitMQ
  • 分布式
    • 消息队列
      • 消息队列 - 使用docker-compose构建kafka集群
  • 分布式
    • 消息队列
      • 消息队列 - 分布式系统与消息的投递
  • 分布式
    • 消息队列
      • 消息队列 - 如何保证消息的可靠性传输
  • 分布式
    • 消息队列
      • 消息队列 - 如何保证消息的顺序性
  • 分布式
    • 消息队列
      • 消息队列 - 如何保证消息队列的高可用
  • 分布式
    • 消息队列
      • 消息队列 - 消息队列设计精要
  • 分布式
    • 监控系统
      • 深度剖析开源分布式监控CAT
  • 大数据
    • Flink
      • Flink架构与核心组件
  • 微服务
    • Dubbo
      • 基于dubbo的分布式应用中的统一异常处理
  • 微服务
    • Dubbo
      • Vim快捷键
  • 微服务
    • Service Mesh
      • Istio 是什么?
  • 微服务
    • Service Mesh
      • OCTO 2.0:美团基于Service Mesh的服务治理系统详解
  • 微服务
    • Service Mesh
      • Service Mesh是什么?
  • 微服务
    • Service Mesh
      • Spring Cloud向Service Mesh迁移
  • 微服务
    • Service Mesh
      • 数据挖掘算法
  • 微服务
    • Service Mesh
      • Seata Saga 模式
  • 微服务
    • Spring Cloud
      • Seata TCC 模式
  • 微服务
    • Spring Cloud
      • Spring Cloud Config
  • 微服务
    • Spring Cloud
      • Seata AT 模式
  • 微服务
    • Spring Cloud
      • Spring Cloud Gateway
  • 微服务
    • Spring Cloud
      • Spring Cloud OpenFeign 的核心原理
  • 微服务
    • Spring Cloud
      • Seata XA 模式
  • 数据库
    • Database Version Control
      • Liquibase vs. Flyway
  • 数据库
    • Database Version Control
      • Six reasons to version control your database
  • 数据库
    • MySQL
      • How Sharding Works
  • 数据库
    • MySQL
      • MySQL InnoDB中各种SQL语句加锁分析
  • 数据库
    • MySQL
      • MySQL 事务隔离级别和锁
  • 数据库
    • MySQL
      • MySQL 索引性能分析概要
  • 数据库
    • MySQL
      • MySQL 索引设计概要
  • 数据库
    • MySQL
      • MySQL出现Waiting for table metadata lock的原因以及解决方法
  • 数据库
    • MySQL
      • MySQL的Limit性能问题
  • 数据库
    • MySQL
      • MySQL索引优化explain
  • 数据库
    • MySQL
      • MySQL索引背后的数据结构及算法原理
  • 数据库
    • MySQL
      • MySQL行转列、列转行问题
  • 数据库
    • MySQL
      • 一条SQL更新语句是如何执行的?
  • 数据库
    • MySQL
      • 一条SQL查询语句是如何执行的?
  • 数据库
    • MySQL
      • 为什么 MySQL 使用 B+ 树
  • 数据库
    • MySQL
      • 为什么 MySQL 的自增主键不单调也不连续
  • 数据库
    • MySQL
      • 为什么我的MySQL会“抖”一下?
  • 数据库
    • MySQL
      • 为什么数据库不应该使用外键
  • 数据库
    • MySQL
      • 为什么数据库会丢失数据
  • 数据库
    • MySQL
      • 事务的可重复读的能力是怎么实现的?
  • 数据库
    • MySQL
      • 大众点评订单系统分库分表实践
  • 数据库
    • MySQL
      • 如何保证缓存与数据库双写时的数据一致性?
  • 数据库
    • MySQL
      • 浅谈数据库并发控制 - 锁和 MVCC
  • 数据库
    • MySQL
      • 深入浅出MySQL 中事务的实现
  • 数据库
    • MySQL
      • 浅入浅出MySQL 和 InnoDB
  • 数据库
    • PostgreSQL
      • PostgreSQL upsert功能(insert on conflict do)的用法
  • 数据库
    • Redis
      • Redis GEO & 实现原理深度分析
  • 数据库
    • Redis
      • Redis 和 I/O 多路复用
  • 数据库
    • Redis
      • Redis分布式锁
  • 数据库
    • Redis
      • Redis实现分布式锁中的“坑”
  • 数据库
    • Redis
      • Redis总结
  • 数据库
    • Redis
      • 史上最全Redis高可用技术解决方案大全
  • 数据库
    • Redis
      • Redlock:Redis分布式锁最牛逼的实现
  • 数据库
    • Redis
      • 为什么 Redis 选择单线程模型
  • 数据库
    • TiDB
      • 新一代数据库TiDB在美团的实践
  • 数据库
    • 数据仓库
      • 实时数仓在有赞的实践
  • 数据库
    • 数据库原理
      • OLTP与OLAP的关系是什么?
  • 数据库
    • 数据库原理
      • 为什么 OLAP 需要列式存储
  • 系统设计
    • DDD
      • Domain Primitive
  • 系统设计
    • DDD
      • Repository模式
  • 系统设计
    • DDD
      • 应用架构
  • 系统设计
    • DDD
      • 聊聊如何避免写流水账代码
  • 系统设计
    • DDD
      • 领域层设计规范
  • 系统设计
    • DDD
      • 从三明治到六边形
  • 系统设计
    • DDD
      • 阿里盒马领域驱动设计实践
  • 系统设计
    • DDD
      • 领域驱动设计(DDD)编码实践
  • 系统设计
    • DDD
      • 领域驱动设计在互联网业务开发中的实践
  • 系统设计
    • 基础架构
      • 容错,高可用和灾备
  • 系统设计
    • 数据聚合
      • GraphQL及元数据驱动架构在后端BFF中的实践
  • 系统设计
    • 数据聚合
      • 高效研发-闲鱼在数据聚合上的探索与实践
  • 系统设计
    • 服务安全
      • JSON Web Token 入门教程
  • 系统设计
    • 服务安全
      • 你还在用JWT做身份认证嘛?
  • 系统设计
    • 服务安全
      • 凭证(Credentials)
  • 系统设计
    • 服务安全
      • 授权(Authorization)
  • 系统设计
    • 服务安全
      • 理解OAuth2.0
  • 系统设计
    • 服务安全
      • 认证(Authentication)
  • 系统设计
    • 架构案例
      • 微信 Android 客户端架构演进之路
  • 系统设计
    • 高可用架构
      • 业务高可用的保障:异地多活架构
  • 计算机基础
    • 字符编码
      • Base64原理解析
  • 计算机基础
    • 字符编码
      • 字符编码笔记:ASCII,Unicode 和 UTF-8
  • 计算机基础
    • 操作系统
      • 为什么 CPU 访问硬盘很慢
  • 计算机基础
    • 操作系统
      • 为什么 HTTPS 需要 7 次握手以及 9 倍时延
  • 计算机基础
    • 操作系统
      • 为什么 Linux 默认页大小是 4KB
  • 计算机基础
    • 操作系统
      • 磁盘IO那些事
  • 计算机基础
    • 操作系统
      • 虚拟机的3种网络模式
  • 计算机基础
    • 服务器
      • mac终端bash、zsh、oh-my-zsh最实用教程
  • 计算机基础
    • 服务器
      • Nginx强制跳转Https
  • 计算机基础
    • 服务器
      • curl 的用法指南
  • 计算机基础
    • 网络安全
      • 如何设计一个安全的对外接口?
  • 计算机基础
    • 网络安全
      • 浅谈常见的七种加密算法及实现
  • 计算机基础
    • 网络编程
      • MQTT - The Standard for IoT Messaging
  • 计算机基础
    • 网络编程
      • 两万字长文 50+ 张趣图带你领悟网络编程的内功心法
  • 计算机基础
    • 网络编程
      • 为什么 TCP 协议有 TIME_WAIT 状态
  • 计算机基础
    • 网络编程
      • 为什么 TCP 协议有性能问题
  • 计算机基础
    • 网络编程
      • 为什么 TCP 协议有粘包问题
  • 计算机基础
    • 网络编程
      • 为什么 TCP 建立连接需要三次握手
  • 计算机基础
    • 网络编程
      • 为什么 TCP/IP 协议会拆分数据
  • 计算机基础
    • 网络编程
      • 使用 OAuth 2 和 JWT 为微服务提供安全保障
  • 计算机基础
    • 网络编程
      • 四种常见的 POST 提交数据方式
  • 计算机基础
    • 网络编程
      • 有赞TCP网络编程最佳实践
  • 计算机基础
    • 网络编程
      • 看完这篇HTTP,跟面试官扯皮就没问题了
  • 计算机基础
    • 网络编程
      • 详细解析 HTTP 与 HTTPS 的区别
  • 质量&效率
    • 快捷键
      • Idea快捷键(Mac版)
  • 质量&效率
    • 快捷键
      • Shell快捷键
  • 质量&效率
    • 快捷键
      • conduit
  • 质量&效率
    • 敏捷开发
      • Scrum的3种角色
  • 质量&效率
    • 敏捷开发
      • Scrum的4种会议
  • 质量&效率
    • 敏捷开发
      • ThoughtWorks的敏捷开发
  • 质量&效率
    • 敏捷开发
      • 敏捷开发入门教程
  • 运维&测试
    • Docker
      • Docker (容器) 的原理
  • 运维&测试
    • Docker
      • Docker Compose:链接外部容器的几种方式
  • 运维&测试
    • Docker
      • Docker 入门教程
  • 运维&测试
    • Docker
      • Docker 核心技术与实现原理
  • 运维&测试
    • Docker
      • Dockerfile 最佳实践
  • 运维&测试
    • Docker
      • Docker开启Remote API 访问 2375端口
  • 运维&测试
    • Docker
      • Watchtower - 自动更新 Docker 镜像与容器
  • 运维&测试
    • Kubernetes
      • Kubernetes 介绍
  • 运维&测试
    • Kubernetes
      • Kubernetes 在有赞的实践
  • 运维&测试
    • Kubernetes
      • Kubernetes 学习路径
  • 运维&测试
    • Kubernetes
      • Kubernetes如何改变美团的云基础设施?
  • 运维&测试
    • Kubernetes
      • Kubernetes的三种外部访问方式:NodePort、LoadBalancer 和 Ingress
  • 运维&测试
    • Kubernetes
      • 谈 Kubernetes 的架构设计与实现原理
  • 运维&测试
    • 压测
      • 全链路压测平台(Quake)在美团中的实践
  • 运维&测试
    • 测试
      • Cpress - JavaScript End to End Testing Framework
  • 运维&测试
    • 测试
      • 代码覆盖率-JaCoCo
  • 运维&测试
    • 测试
      • 浅谈代码覆盖率
  • 运维&测试
    • 测试
      • 测试中 Fakes、Mocks 以及 Stubs 概念明晰
  • Java FrameWorks
    • Spring
      • Spring AOP
        • Spring AOP中的Bean是如何被AOP代理的
  • Java FrameWorks
    • Spring
      • Spring AOP
        • Spring AOP原生动态代理和Cglib动态代理
  • Java FrameWorks
    • Spring
      • Spring AOP
        • Spring AOP实现方式(xml&注解)
  • Java FrameWorks
    • Spring
      • Spring AOP
        • Spring AOP是如何收集切面类并封装的
  • Java FrameWorks
    • Spring
      • Spring AOP
        • Spring AOP概述
  • Java FrameWorks
    • Spring
      • Spring AOP
        • Spring AOP的底层核心后置处理器
  • Java FrameWorks
    • Spring
      • Spring AOP
        • Spring AOP的延伸知识
  • Java FrameWorks
    • Spring
      • Spring Boot
        • Spring Boot - IOC(一)
  • Java FrameWorks
    • Spring
      • Spring Boot
        • Spring Boot - IOC(三)
  • Java FrameWorks
    • Spring
      • Spring Boot
        • Spring Boot - IOC(二)
  • Java FrameWorks
    • Spring
      • Spring Boot
        • Spring Boot - IOC(五)
  • Java FrameWorks
    • Spring
      • Spring Boot
        • Spring Boot - IOC(四) - 循环依赖与解决方案
  • Java FrameWorks
    • Spring
      • Spring Boot
        • Spring Boot - 启动引导
  • Java FrameWorks
    • Spring
      • Spring Boot
        • Spring Boot JarLauncher
  • Java FrameWorks
    • Spring
      • Spring Boot
        • Spring Boot Web Mvc 自动装配
  • Java FrameWorks
    • Spring
      • Spring Boot
        • Spring Boot 使用ApplicationListener监听器
  • Java FrameWorks
    • Spring
      • Spring Boot
        • Spring Boot 声明式事务
  • Java FrameWorks
    • Spring
      • Spring Boot
        • Spring Boot 嵌入式容器
  • Java FrameWorks
    • Spring
      • Spring Boot
        • Spring Boot引起的“堆外内存泄漏”排查及经验总结
  • Java FrameWorks
    • Spring
      • Spring Boot
        • Spring Boot的启动流程
  • Java FrameWorks
    • Spring
      • Spring Boot
        • Spring Boot自动化配置源码分析
  • Java FrameWorks
    • Spring
      • Spring Boot
        • 如何自定义Spring Boot Starter?
  • Java FrameWorks
    • Spring
      • Spring IOC
        • IOC - 模块装配和条件装配
  • Java FrameWorks
    • Spring
      • Spring IOC
        • IOC - 配置源(xml,注解)
  • Java FrameWorks
    • Spring
      • Spring IOC
        • Spring Environment
  • Java FrameWorks
    • Spring
      • Spring IOC
        • Spring ApplicationContext
  • Java FrameWorks
    • Spring
      • Spring IOC
        • Spring BeanDefinition
  • Java FrameWorks
    • Spring
      • Spring IOC
        • Spring BeanFactory
  • Java FrameWorks
    • Spring
      • Spring IOC
        • Spring BeanFactoryPostProcessor
  • Java FrameWorks
    • Spring
      • Spring IOC
        • Spring BeanPostProcessor
  • Java FrameWorks
    • Spring
      • Spring IOC
        • Spring Bean的生命周期(一) - 概述
  • Java FrameWorks
    • Spring
      • Spring IOC
        • Spring Bean的生命周期(三) - 实例化阶段
  • Java FrameWorks
    • Spring
      • Spring IOC
        • Spring Bean的生命周期(二) - BeanDefinition
  • Java FrameWorks
    • Spring
      • Spring IOC
        • Spring Bean的生命周期(五) - 销毁阶段
  • Java FrameWorks
    • Spring
      • Spring IOC
        • Spring Bean的生命周期(四) - 初始化阶段
  • Java FrameWorks
    • Spring
      • Spring IOC
        • Spring ComponentScan
  • Java FrameWorks
    • Spring
      • Spring IOC
        • Spring Events
  • Java FrameWorks
    • Spring
      • Spring IOC
        • Spring IOC 基础篇
  • Java FrameWorks
    • Spring
      • Spring IOC
        • Spring IOC 总结
  • Java FrameWorks
    • Spring
      • Spring IOC
        • Spring IOC 进阶篇
  • Java FrameWorks
    • Spring
      • Spring IOC
        • Spring IOC容器的生命周期
  • Java FrameWorks
    • Spring
      • Spring IOC
        • Spring Resource
  • Java FrameWorks
    • Spring
      • Spring MVC
        • DispatcherServlet的初始化原理
  • Java FrameWorks
    • Spring
      • Spring MVC
        • DispatcherServlet的核心工作原理
  • Java FrameWorks
    • Spring
      • Spring MVC
        • WebMvc的架构设计与组件功能解析
  • Java FrameWorks
    • Spring
      • Spring Security
        • Spring Boot 2 + Spring Security 5 + JWT 的单页应用 Restful 解决方案
  • Java FrameWorks
    • Spring
      • Spring Security
        • Spring Security Oauth
  • Java FrameWorks
    • Spring
      • Spring Security
        • Spring Security
  • Java FrameWorks
    • Spring
      • Spring WebFlux
        • DispatcherHandler的工作原理(传统方式)
  • Java FrameWorks
    • Spring
      • Spring WebFlux
        • DispatcherHandler的工作原理(函数式端点)
  • Java FrameWorks
    • Spring
      • Spring WebFlux
        • WebFlux的自动装配
  • Java FrameWorks
    • Spring
      • Spring WebFlux
        • 快速了解响应式编程与Reactive
  • Java FrameWorks
    • Spring
      • Spring WebFlux
        • 快速使用WebFlux
  • 分布式
    • 协调服务
      • Zookeeper
        • Zookeeper - 客户端之 Curator
  • 分布式
    • 协调服务
      • Zookeeper
        • 详解分布式协调服务 ZooKeeper
  • 分布式
    • 协调服务
      • etcd
        • 高可用分布式存储 etcd 的实现原理
  • 数据库
    • Database Version Control
      • Flyway
        • Database Migrations with Flyway
  • 数据库
    • Database Version Control
      • Flyway
        • How Flyway works
  • 数据库
    • Database Version Control
      • Flyway
        • Rolling Back Migrations with Flyway
  • 数据库
    • Database Version Control
      • Flyway
        • The meaning of the concept of checksums
  • 数据库
    • Database Version Control
      • Liquibase
        • Introduction to Liquibase Rollback
  • 数据库
    • Database Version Control
      • Liquibase
        • LiquiBase中文学习指南
  • 数据库
    • Database Version Control
      • Liquibase
        • Use Liquibase to Safely Evolve Your Database Schema
  • 系统设计
    • 流量控制
      • RateLimiter
        • Guava Rate Limiter实现分析
  • 系统设计
    • 流量控制
      • Sentinel
        • Sentinel 与 Hystrix 的对比
  • 系统设计
    • 流量控制
      • Sentinel
        • Sentinel工作主流程
  • 系统设计
    • 流量控制
      • 算法
        • 分布式服务限流实战
  • 系统设计
    • 解决方案
      • 秒杀系统
        • 如何设计一个秒杀系统
  • 系统设计
    • 解决方案
      • 红包系统
        • 微信高并发资金交易系统设计方案--百亿红包背后的技术支撑
  • 计算机基础
    • 数据结构与算法
      • 其他相关
        • 什么是预排序遍历树算法(MPTT,Modified Preorder Tree Traversal)
  • 计算机基础
    • 数据结构与算法
      • 其他相关
        • 加密算法
  • 计算机基础
    • 数据结构与算法
      • 其他相关
        • 推荐系统算法
  • 计算机基础
    • 数据结构与算法
      • 其他相关
        • linkerd
  • 计算机基础
    • 数据结构与算法
      • 其他相关
        • 查找算法
  • 计算机基础
    • 数据结构与算法
      • 其他相关
        • 缓存淘汰算法中的LRU和LFU
  • 计算机基础
    • 数据结构与算法
      • 其他相关
        • 负载均衡算法
  • 计算机基础
    • 数据结构与算法
      • 分布式算法
        • 分布式算法 - Paxos算法
  • 计算机基础
    • 数据结构与算法
      • 分布式算法
        • 分布式算法 - Raft算法
  • 计算机基础
    • 数据结构与算法
      • 分布式算法
        • 分布式算法 - Snowflake算法
  • 计算机基础
    • 数据结构与算法
      • 分布式算法
        • 分布式算法 - ZAB算法
  • 计算机基础
    • 数据结构与算法
      • 分布式算法
        • 分布式算法 - 一致性Hash算法
  • 计算机基础
    • 数据结构与算法
      • 大数据处理
        • 大数据处理 - Bitmap & Bloom Filter
  • 计算机基础
    • 数据结构与算法
      • 大数据处理
        • 大数据处理 - Map & Reduce
  • 计算机基础
    • 数据结构与算法
      • 大数据处理
        • 大数据处理 - Trie树/数据库/倒排索引
  • 计算机基础
    • 数据结构与算法
      • 大数据处理
        • 大数据处理 - 分治/hash/排序
  • 计算机基础
    • 数据结构与算法
      • 大数据处理
        • 大数据处理 - 双层桶划分
  • 计算机基础
    • 数据结构与算法
      • 大数据处理
        • 大数据处理 - 外(磁盘文件)排序
  • 计算机基础
    • 数据结构与算法
      • 大数据处理
        • 大数据处理 - 布隆过滤器
  • 计算机基础
    • 数据结构与算法
      • 大数据处理
        • 大数据处理算法
  • 计算机基础
    • 数据结构与算法
      • 字符串匹配算法
        • 字符串匹配 - 文本预处理:后缀树(Suffix Tree)
  • 计算机基础
    • 数据结构与算法
      • 字符串匹配算法
        • 字符串匹配 - 模式预处理:BM 算法 (Boyer-Moore)
  • 计算机基础
    • 数据结构与算法
      • 字符串匹配算法
        • 字符串匹配 - 模式预处理:KMP 算法(Knuth-Morris-Pratt)
  • 计算机基础
    • 数据结构与算法
      • 字符串匹配算法
        • 字符串匹配 - 模式预处理:朴素算法(Naive)(暴力破解)
  • 计算机基础
    • 数据结构与算法
      • 字符串匹配算法
        • 字符串匹配
  • 计算机基础
    • 数据结构与算法
      • 常用算法
        • 分支限界算法
  • 计算机基础
    • 数据结构与算法
      • 常用算法
        • 分治算法
  • 计算机基础
    • 数据结构与算法
      • 常用算法
        • 动态规划算法
  • 计算机基础
    • 数据结构与算法
      • 常用算法
        • 回溯算法
  • 计算机基础
    • 数据结构与算法
      • 常用算法
        • 贪心算法
  • 计算机基础
    • 数据结构与算法
      • 排序算法
        • 十大排序算法
  • 计算机基础
    • 数据结构与算法
      • 排序算法
        • 图解排序算法(一)之3种简单排序(选择,冒泡,直接插入)
  • 计算机基础
    • 数据结构与算法
      • 排序算法
        • 图解排序算法(三)之堆排序
  • 计算机基础
    • 数据结构与算法
      • 排序算法
        • 图解排序算法(二)之希尔排序
  • 计算机基础
    • 数据结构与算法
      • 排序算法
        • 图解排序算法(四)之归并排序
  • 计算机基础
    • 数据结构与算法
      • 数据结构
        • 树的高度和深度
  • 计算机基础
    • 数据结构与算法
      • 数据结构
        • 红黑树深入剖析及Java实现
  • 计算机基础
    • 数据结构与算法
      • 数据结构
        • 线性结构 - Hash
  • 计算机基础
    • 数据结构与算法
      • 数据结构
        • 线性结构 - 数组、链表、栈、队列
  • 计算机基础
    • 数据结构与算法
      • 数据结构
        • 逻辑结构 - 树
  • 运维&测试
    • 测试
      • Spock
        • Groovy 简明教程
  • 运维&测试
    • 测试
      • Spock
        • Spock 官方文档
  • 运维&测试
    • 测试
      • Spock
        • Spock单元测试框架介绍以及在美团优选的实践
  • 运维&测试
    • 测试
      • TDD
        • TDD 实践 - FizzFuzzWhizz(一)
  • 运维&测试
    • 测试
      • TDD
        • TDD 实践 - FizzFuzzWhizz(三)
  • 运维&测试
    • 测试
      • TDD
        • TDD 实践 - FizzFuzzWhizz(二)
  • 运维&测试
    • 测试
      • TDD
        • 测试驱动开发(TDD)- 原理篇
  • 微服务
    • Spring Cloud
      • Spring Cloud Alibaba
        • Nacos
          • Nacos 服务注册的原理
  • 微服务
    • Spring Cloud
      • Spring Cloud Alibaba
        • Nacos
          • Nacos 配置中心原理分析
  • 微服务
    • Spring Cloud
      • Spring Cloud Alibaba
        • Seata
          • 服务调用过程
  • 微服务
    • Spring Cloud
      • Spring Cloud Alibaba
        • Seata
          • Spring Cloud Bus
  • 微服务
    • Spring Cloud
      • Spring Cloud Alibaba
        • Seata
          • Spring Cloud Consul
  • 微服务
    • Spring Cloud
      • Spring Cloud Alibaba
        • Seata
          • Spring Cloud Stream
  • 微服务
    • Spring Cloud
      • Spring Cloud Alibaba
        • Sentinel
          • Sentinel 与 Hystrix 的对比
  • 微服务
    • Spring Cloud
      • Spring Cloud Alibaba
        • Sentinel
          • Sentinel
  • 微服务
    • Spring Cloud
      • Spring Cloud Netflix
        • Hystrix
          • How Hystrix Works
  • 微服务
    • Spring Cloud
      • Spring Cloud Netflix
        • Hystrix
          • Hystrix
  • 微服务
    • Spring Cloud
      • Spring Cloud Netflix
        • Hystrix
          • Hystrix原理与实战
  • 微服务
    • Spring Cloud
      • Spring Cloud Netflix
        • Hystrix
          • Spring Cloud Hystrix基本原理
由 GitBook 提供支持
在本页
  • 1. BeanFactory
  • 1.1 BeanFactory和它的子接口们
  • 1.2 BeanFactory
  • 1.3 HierarchicalBeanFactory
  • 1.4 ListableBeanFactory
  • 1.5 AutowireCapableBeanFactory
  • 1.6 ConfigurableBeanFactory
  • 1.7 BeanFactory的实现类们
  • 1.8 AbstractBeanFactory
  • 1.9 AbstractAutowireCapableBeanFactory
  • 1.10 DefaultListableBeanFactory
  • 1.11 XmlBeanFactory
  • 2. ApplicationContext
  • 2.1 ApplicationContext和它的上下辈们
  • 2.2 ApplicationContext
  • 2.3 ConfigurableApplicationContext
  • 2.4 EnvironmentCapable
  • 2.5 MessageSource
  • 2.6 ApplicationEventPublisher
  • 2.7 ResourcePatternResolver
  • 2.8 ApplicationContext的实现类们

这有帮助吗?

  1. Java FrameWorks
  2. Spring
  3. Spring IOC

Spring IOC 进阶篇

上一页Spring IOC下一页Java FrameWorks

最后更新于2年前

这有帮助吗?

1. BeanFactory

1.1 BeanFactory和它的子接口们

img

1.2 BeanFactory

BeanFactory 作为 SpringFramework中最顶级的容器接口,它的作用一定是最简单、最核心的。

1.2.1 BeanFactory是根容器

The root interface for accessing a Spring bean container. This is the basic client view of a bean container; further interfaces such as ListableBeanFactory and org.springframework.beans.factory.config.ConfigurableBeanFactory are available for specific purposes.

用于访问 SpringFramework bean 容器的根接口。这是 bean 容器的基本客户端视图。诸如 ListableBeanFactory 和 org.springframework.beans.factory.config.ConfigurableBeanFactory 之类的扩展接口可用于特定的用途。为了实现某些额外的特性(层次性、可搜索性、可配置性等)。

1.2.2 BeanFactory中定义的作用域概念

默认情况下,BeanFactory 中的 Bean 只有单实例 Bean(singleton) 和原型 Bean(prototype) ,自打 SpringFramework2.0 开始,出现了 Web 系列的作用域 request 和 session ,后续的又出现了 global session 和 websocket 作用域。

Bean 的作用域类型取决于定义的 scope。

@Component
@Scope("prototype")
public class Cat { }

1.2.3 BeanFactory集成了环境配置

BeanFactory 它本身是所有 Bean 的注册中心,所有的 Bean 最终都在 BeanFactory 中创建和保存。另外 BeanFactory 中还集成了配置信息。通过加载外部的 properties 文件,借助 SpringFramework 的方式将配置文件的属性值设置到 Bean 对象中。

1.2.4 BeanFactory推荐使用DI而不是DL

SpringFramework 官方在 IOC 的两种实现上的权衡:推荐使用 **DI** ,尽可能不要使用 **DL** 。通常最好使用依赖注入(“推”的配置),通过setter方法或构造器注入的方式,配置应用程序对象,而不是使用任何形式的“拉”的配置(例如借助 BeanFactory 进行依赖查找)。 SpringFramework 的 Dependency Injection 功能是使用 BeanFactory 接口及其子接口实现的。

1.2.5 BeanFactory支持多种类型的配置源

通常情况下,BeanFactory 会加载存储在配置源(例如 XML 文档)中 bean 的定义,并使用 org.springframework.beans 包中的 API 来配置 bean 。然而,BeanFactory 的实现可以根据需要直接在 Java 代码中返回它创建的 Java 对象。bean 定义的存储方式没有任何限制,它可以是 LDAP (轻型文件目录访问协议),RDBMS(关系型数据库系统),XML,properties 文件等。鼓励实现以支持 Bean 之间的引用(依赖注入)。

虽然SpringFramework 可以支持的配置源类型有很多种,当然最常用的还是 xml 和注解驱动。

1.2.6 BeanFactory可实现层次性

与 ListableBeanFactory 中的方法相比,BeanFactory 中的所有操作还将检查父工厂(如果这是 HierarchicalBeanFactory )。如果在 BeanFactory 实例中没有找到指定的 bean ,则会向父工厂中搜索查找。BeanFactory 实例中的 Bean 应该覆盖任何父工厂中的同名 Bean 。

也就是说,BeanFactory 本身可以支持父子结构,这个父子结构的概念和实现由 HierarchicalBeanFactory 实现,在 BeanFactory 中它也只是提了一下。这部分咱放到下面的 HierarchicalBeanFactory 中解释。

1.2.7 BeanFactory中设有完整的生命周期控制机制

BeanFactory 接口实现了尽可能支持标准 Bean 的生命周期接口。

Bean 的生命周期是在 BeanFactory 中就有设计的,而且官方文档也提供了全套的初始化和销毁流程。

1.2.8 小结

总的来说, BeanFactory 提供了如下基础的特性:

  • 基础的根容器。

  • 定义了作用域(单例,原型)的概念。

  • 集成环境配置(properties)。

  • 支持多种类型的配置源(xml,注解)。

  • 层次性的设计

  • 完整的生命周期控制机制

1.3 HierarchicalBeanFactory

从类名上能很容易的理解,它是体现了层次性的 BeanFactory 。有了这个特性,BeanFactory 就有了父子结构。

HierarchicalBeanFactory是由 BeanFactory 实现的子接口,它可以理解为是层次结构的一部分。 可以在 ConfigurableBeanFactory 接口中找到用于 BeanFactory 的相应 setParentBeanFactory 方法,该方法允许以可配置的方式设置父对象。

也就是说,HierarchicalBeanFactory对应的接口方法定义中,就有这么一个方法:**getParentBeanFactory()** ,它就可以获取到父 BeanFactory 对象;接口中还有一个方法是 containsLocalBean(String name) ,它是检查当前本地的容器中是否有指定名称的 Bean ,而不会往上找父 BeanFactory 。

getBean 方法会从当前 BeanFactory 开始查找是否存在指定的 Bean ,如果当前找不到就依次向上找父 BeanFactory ,直到找到为止返回,或者都找不到最终抛出 NoSuchBeanDefinitionException。如果当前找不到就往上找,那如果找到了就不往上找了。

那么如果当前 BeanFactory 中有指定的 Bean 了,父 BeanFactory 中可能有吗?

那么怎么设置父 BeanFactory ,文档注释中也说了,要用 ConfigurableBeanFactory 的 setParentBeanFactory() 方法。

1.4 ListableBeanFactory

1.4.1 ListableBeanFactory可以列举出容器中的所有Bean

ListableBeanFactory是 BeanFactory 接口的扩展实现,它可以列举出所有 bean 实例,而不是按客户端调用的要求,按照名称一一进行 bean 的依赖查找。具有 “预加载其所有 bean 定义信息” 的 BeanFactory 实现(例如基于XML的 BeanFactory )可以实现此接口。

换句话说,ListableBeanFactory的扩展功能是能让咱在拿到 BeanFactory 时可以直接把容器中的所有 Bean 都拿出来(也就相当于提供了可迭代的特性),而不是一个一个的拿 name 去取(一个一个的取会很麻烦,而且很大程度上取不全)。后面提到了一个概念,叫“预加载所有 bean 的定义信息”,这个也是涉及到 BeanDefinition 的东西了,咱到后面讲解 BeanDefinition 时再详细介绍。

1.4.2 ListableBeanFactory只列举当前容器中的Bean

ListableBeanFactory 只会列举当前容器的 Bean ,因为咱上面也看了,BeanFactory 可以具有层次性,那这样再列举所有 Bean 的时候,就需要斟酌到底是获取包括父容器在内的所有 Bean ,还是只获取当前容器中的 Bean ,SpringFramework 在斟酌之后选择了只获取当前容器中的 Bean ,而如果真的想获取所有 Bean ,可以借助 BeanFactoryUtils 工具类来实现(工具类中有不少以 "IncludingAncestors" 结尾的方法,代表可以一起取父容器)。

1.4.3 ListableBeanFactory会有选择性的列举

ListableBeanFactory 中的方法将仅遵循当前工厂的 bean 定义,它们将忽略通过其他方式(例如 **ConfigurableBeanFactory** 的 **registerSingleton** 方法)注册的任何单实例 bean (但 **getBeanNamesForType** 和 **getBeansOfType** 除外),它们也会检查这种手动注册的单实例 Bean 。当然,BeanFactory 的 getBean 确实也允许透明访问此类特殊 bean 。在一般情况下,无论如何所有的 bean 都来自由外部的 bean 定义信息,因此大多数应用程序不必担心这种区别。

换句话说,作为一个“可迭代”的 BeanFactory ,按理来讲应该最起码得把当前容器中的所有 Bean 都列出来,但是有些 Bean(通过其他方式注册的bean) 会被忽略掉。因为通过ConfigurableBeanFactory 的 registerSingleton 方法注入的bean属于 SpringFramework 内部使用的,这样做的目的是 SpringFramework 不希望咱开发者直接操控他们,于是就使用了这种方式来隐藏它们。

1.4.4 ListableBeanFactory的大部分方法不适合频繁调用

除了 **getBeanDefinitionCount** 和 **containsBeanDefinition** 之外,此接口中的方法不适用于频繁调用,方法的实现可能执行速度会很慢。

1.5 AutowireCapableBeanFactory

AutowireCapableBeanFactory是支持自动注入的 BeanFactory 。

1.5.1 AutowireCapableBeanFactory可以支持外部Bean的自动装配

AutowireCapableBeanFactory 是 BeanFactory 接口的扩展实现,它可以实现自动装配,前提是开发者希望为现有的 bean 实例公开此功能。AutowireCapableBeanFactory 本身可以支持自动装配,而且还可以为现有的一些 Bean 也能支持自动装配。而这个“现有”的概念,实际上指的是那些不被 SpringFramework 管理的 Bean 。

1.5.2 AutowireCapableBeanFactory用于框架集成

AutowireCapableBeanFactory 这个子接口不能在常规的应用程序代码中使用:一般情况下,请坚持使用 BeanFactory 或 ListableBeanFactory 。 其他框架的集成代码可以利用此接口来连接和注入 SpringFramework 无法控制其生命周期的现有 bean 实例。例如,这对于 WebWork 操作和 Tapestry 页面对象特别有用。

也就是说这个 AutowireCapableBeanFactory 一般不要让咱自己用,而是在与其他框架进行集成时才使用。注意这里面它的描述:利用此接口来连接和注入 SpringFramework 无法控制其生命周期的现有 bean 实例,这其实已经把它的作用完整的描述出来了:你要是真想用它,那也是在跟其它框架集成时,如果其它框架的一些 Bean 实例无法让 SpringFramework 控制,但又需要注入一些由 SpringFramework 管理的对象,那就可以用它了。

举个例子:

你自己编写了一个 Servlet ,而这个 Servlet 里面需要引入 IOC 容器中的一个存在的 Service ,应该如何处理呢?

根据 IOC 的思路,很明显还是两种思路:DL 和 DI :

  • DL :由 Servlet 自己取到 IOC 容器,并直接从 IOC 容器中获取到对应的 Service 并保存至成员属性中【拉】

对于 DL 的实现,SpringFramework 有一种机制可以让 Servlet 取到 IOC 容器;而 DI 的实现,就需要这个 AutowireCapableBeanFactory 帮忙注入了。至于这部分怎么搞,咱放到后面介绍 Web 部分时再讲解。

1.5.3 AutowireCapableBeanFactory不由ApplicationContext实现但可获取

AutowireCapableBeanFactory 接口没有在 ApplicationContext 中实现,因为应用程序代码几乎从未使用过此接口。但是,它可以从应用程序上下文中获得:可以通过 ApplicationContext 的 getAutowireCapableBeanFactory()方法进行访问。

换句话说,这个扩展你们一般用不到,但我给你取的方式,你们需要的时候自己拿。

1.5.4 AutowireCapableBeanFactory可以借助BeanFactoryAware注入

另外,还可以实现 BeanFactoryAware 接口,该接口即使在 ApplicationContext 中运行时也公开内部 BeanFactory ,以访问 AutowireCapableBeanFactory :只需将传入的 BeanFactory 强制转换为 AutowireCapableBeanFactory 。

换句话说,其实通过 BeanFactoryAware 接口注入的 BeanFactory 也就是 AutowireCapableBeanFactory ,可以直接强转拿来用。这个说实话,提不提这个都行,注入 ApplicationContext 一样可以拿到它。

1.6 ConfigurableBeanFactory

1.6.1 可读&可写

回想一开始学习面向对象编程时,就知道一个类的属性设置为 private 后,提供 get 方法则意味着该属性可读,提供 set 方法则意味着该属性可写。同样的,在 SpringFramework 的这些 BeanFactory ,包括后面的 ApplicationContext 中,都会有这样的设计。普通的 BeanFactory 只有 get 相关的操作,而 Configurable 开头的 BeanFactory 或者 ApplicationContext 就具有了 set 的操作。

void setBeanClassLoader(@Nullable ClassLoader beanClassLoader);
void setTypeConverter(TypeConverter typeConverter);
void addBeanPostProcessor(BeanPostProcessor beanPostProcessor);

1.6.2 ConfigurableBeanFactory提供可配置的功能

大多数 BeanFactory 的实现类都会实现这个带配置的接口。除了 BeanFactory 接口中的基础获取方法之外,还提供了配置 BeanFactory 的功能。

ConfigurableBeanFactory 已经提供了带配置的功能,可以调用它里面定义的方法来对 BeanFactory 进行修改、扩展等。

1.6.3 ConfigurableBeanFactory不推荐给开发者使用

ConfigurableBeanFactory 接口并不希望开发者在应用程序代码中使用,而是坚持使用 BeanFactory 或 ListableBeanFactory 。此扩展接口仅用于允许在框架内部进行即插即用,并允许对 BeanFactory 中的配置方法的特殊访问。

换句话说,SpringFramework 不希望开发者用 ConfigurableBeanFactory ,而是老实的用最根本的 BeanFactory ,原因也很简单,程序在运行期间按理不应该对 **BeanFactory** 再进行频繁的变动,此时只应该有读的动作,而不应该出现写的动作。

到这里,有关 BeanFactory 和它扩展的重要接口也就了解的差不多了,下面咱看看有关 BeanFactory 的实现类,看看 SpringFramework 是如何有层次的划分 BeanFactory 的功能职责的。

1.7 BeanFactory的实现类们

1.8 AbstractBeanFactory

为什么一上来先说它,而不是它的父类 DefaultSingletonBeanRegistry 呢?很简单,咱介绍的是 BeanFactory 的实现类,DefaultSingletonBeanRegistry 并没有实现。

从类名上就知道,它是 BeanFactory 最基本的抽象实现,当然作为一个抽象类,一定是只具备了部分功能,不是完整的实现。

1.8.1 AbstractBeanFactory是最终BeanFactory的基础实现

AbstractBeanFactory是 BeanFactory 接口最基础的抽象实现类,提供 ConfigurableBeanFactory SPI 的全部功能。我们不假定有一个可迭代的 BeanFactory ,因此也可以用作 BeanFactory 实现的父类,该实现可以从某些后端资源(其中 bean 定义访问是一项昂贵的操作)获取 bean 的定义。

换句话说,AbstractBeanFactory 是作为 BeanFactory 接口下面的第一个抽象的实现类,它具有最基础的功能,并且它可以从配置源(之前看到的 xml 、LDAP 、RDBMS 等)获取 Bean 的定义信息,而这个 Bean 的定义信息就是 BeanDefinition 。

SPI 全称为 Service Provider Interface,是 jdk 内置的一种服务提供发现机制。说白了,它可以加载预先在特定位置下配置的一些类。

1.8.2 AbstractBeanFactory对Bean的支持

此类可以提供单实例 Bean 的缓存(通过其父类 DefaultSingletonBeanRegistry ),单例/原型 Bean 的决定,FactoryBean 处理,Bean 的别名,用于子 bean 定义的 bean 定义合并以及 bean 销毁( DisposableBean 接口,自定义 destroy 方法)。此外,它可以通过实现 HierarchicalBeanFactory 接口来管理 BeanFactory 层次结构(在未知 bean 的情况下委托给父工厂)。

从这部分的描述中,咱看到除了在之前 BeanFactory 中介绍的功能和特性之外,它还扩展了另外一些功能:别名的处理(来源于 AliasRegistry 接口)、Bean 定义的合并(涉及到 Bean 的继承,后续章节讲解)、Bean 的销毁动作支持( DisposableBean )等等,这些特性有一些咱已经见过了,有一些还没有接触,咱后面都会来展开介绍。

1.8.3 AbstractBeanFactory定义了模板方法

子类要实现的主要模板方法是 getBeanDefinition 和 createBean ,分别为给定的 bean 名称检索 bean 定义信息,并根据给定的 bean 定义信息创建 bean 的实例。这些操作的默认实现可以在 DefaultListableBeanFactory 和 AbstractAutowireCapableBeanFactory 中找到。

SpringFramework 中大量使用模板方法模式来设计核心组件,它的思路是:父类提供逻辑规范,子类提供具体步骤的实现。在文档注释中,咱看到 AbstractBeanFactory 中对 getBeanDefinition 和 createBean 两个方法进行了规范上的定义,分别代表获取 Bean 的定义信息,以及创建 Bean 的实例,这两个方法都会在 SpringFramework 的 IOC 容器初始化阶段起到至关重要的作用。

多说一句,createBean 是 SpringFramework 能管控的所有 Bean 的创建入口。

1.9 AbstractAutowireCapableBeanFactory

1.9.1 AbstractAutowireCapableBeanFactory提供Bean的创建逻辑实现

它是实现了默认 bean 创建逻辑的的抽象的 BeanFactory 实现类,它具有 RootBeanDefinition 类指定的全部功能。除了 AbstractBeanFactory 的 createBean 方法之外,还实现 AutowireCapableBeanFactory 接口。

这个 AbstractAutowireCapableBeanFactory 继承了 AbstractBeanFactory 抽象类,还额外实现了 AutowireCapableBeanFactory 接口,那实现了这个接口就代表着,它可以实现自动注入的功能了。除此之外,它还把 AbstractBeanFactory 的 createBean 方法给实现了,代表它还具有创建 Bean 的功能。

这个地方要多说一嘴,其实 **createBean** 方法也不是最终实现 Bean 的创建,而是有另外一个叫 **doCreateBean** 方法,它同样在 AbstractAutowireCapableBeanFactory 中定义,而且是 protected 方法,没有子类重写它,算是它独享的了。

1.9.2 AbstractAutowireCapableBeanFactory实现了属性赋值和组件注入

提供 Bean 的创建(具有构造方法的解析),属性填充,属性注入(包括自动装配)和初始化。处理运行时 Bean 的引用,解析托管集合,调用初始化方法等。支持自动装配构造函数,按名称的属性和按类型的属性。

这一段已经把 AbstractAutowireCapableBeanFactory 中实现的最最核心功能全部列出来了:Bean 的创建、属性填充和依赖的自动注入、Bean 的初始化。这部分是创建 Bean 最核心的三个步骤。

1.9.3 AbstractAutowireCapableBeanFactory保留了模板方法

子类要实现的主要模板方法是 resolveDependency(DependencyDescriptor, String, Set, TypeConverter) ,用于按类型自动装配。如果工厂能够搜索其 bean 定义,则通常将通过此类搜索来实现匹配的 bean 。对于其他工厂样式,可以实现简化的匹配算法。

跟 AbstractBeanFactory 不太一样,AbstractAutowireCapableBeanFactory 没有把全部模板方法都实现完,它保留了文档注释中提到的 resolveDependency 方法,这个方法的作用是解析 Bean 的成员中定义的属性依赖关系。

1.9.4 AbstractAutowireCapableBeanFactory不负责BeanDefinition的注册

请注意,此类不承担或实现 bean 定义注册的功能。有关 ListableBeanFactory 和 BeanDefinitionRegistry 接口的实现,请参见DefaultListableBeanFactory ,它们分别表示该工厂的 API 和 SPI 视图。

最后一段注释,它想表明的是,AbstractAutowireCapableBeanFactory 实现了对 Bean 的创建、赋值、注入、初始化的逻辑,但对于 Bean 的定义是如何进入 BeanFactory 的,它不负责。这里面涉及到两个流程:Bean 的创建、Bean 定义的进入,这个咱放到后面 BeanDefinition 和 Bean 的完整生命周期中再详细解释。

1.10 DefaultListableBeanFactory

这个类是唯一一个目前使用的 **BeanFactory** 的落地实现了。

1.10.1 DefaultListableBeanFactory是BeanFactory最终的默认实现

Spring 的 ConfigurableListableBeanFactory 和 BeanDefinitionRegistry 接口的默认实现,它时基于 Bean 的定义信息的的成熟的 BeanFactory 实现,它可通过后置处理器进行扩展。

1.10.2 DefaultListableBeanFactory会先注册Bean定义信息再创建Bean

典型的用法是在访问 bean 之前先注册所有 bean 定义信息(可能是从有 bean 定义的文件中读取)。因此,按名称查找 Bean 是对本地 Bean 定义表进行的合理操作,该操作对预先解析的 Bean 定义元数据对象进行操作。

由此可见,DefaultListableBeanFactory 在 AbstractAutowireCapableBeanFactory 的基础上,完成了注册 Bean 定义信息的动作,而这个动作就是通过上面的 **BeanDefinitionRegistry** 来实现的。所以咱就可以知道一点,完整的 BeanFactory 对 Bean 的管理,应该是先注册 Bean 的定义信息,再完成 Bean 的创建和初始化动作。这个流程,在后面讲解完整的 Bean 生命周期时会详细讲到。

1.10.3 DefaultListableBeanFactory不负责解析Bean定义文件

请注意,特定 bean 定义信息格式的解析器通常是单独实现的,而不是作为 BeanFactory 的子类实现的,有关这部分的内容参见 PropertiesBeanDefinitionReader 和 XmlBeanDefinitionReader 。

SpringFramework 对于组件的单一职责把控的非常好?BeanFactory 作为一个统一管理 Bean 组件的容器,它的核心工作就是控制 Bean 在创建阶段的生命周期,而对于 Bean 从哪里来,如何被创建,都有哪些依赖要被注入,这些统统与它无关,而是有专门的组件(比如XmlBeanDefinitionReader)来处理。

1.10.4 DefaultListableBeanFactory的替代实现

对于 ListableBeanFactory 接口的替代实现,请看一下 StaticListableBeanFactory ,它管理现有的 bean 实例,而不是根据 bean 定义创建新的 bean 实例。

这里它提了另一个实现 StaticListableBeanFactory ,它实现起来相对简单且功能也简单,因为它只能管理单实例 Bean ,而且没有跟 Bean 定义等相关的高级概念在里面,于是 SpringFramework 默认也不用它。

1.11 XmlBeanFactory

在 SpringFramework 3.1 之后,XmlBeanFactory 正式被标注为过时,代替的方案是使用 DefaultListableBeanFactory + XmlBeanDefinitionReader ,这种设计更符合组件的单一职责原则。

而且还有一点。自打 SpringFramework 3.0 之后出现了注解驱动的 IOC 容器,SpringFramework 就感觉这种 xml 驱动的方式不应该单独成为一种方案了,倒不如咱都各退一步,搞一个通用的容器,都组合它来用,这样就实现了配置源载体分离的目的了。

2. ApplicationContext

之前说过推荐使用 ApplicationContext 而不是 BeanFactory ,因为 ApplicationContext 相比较 BeanFactory 扩展的实在是太多了:

Feature

BeanFactory

ApplicationContext

Bean instantiation/wiring —— Bean的实例化和属性注入

Yes

Yes

Integrated lifecycle management —— 生命周期管理

No

Yes

Automatic BeanPostProcessor registration —— Bean后置处理器的支持

No

Yes

Automatic BeanFactoryPostProcessor registration —— BeanFactory后置处理器的支持

No

Yes

Convenient MessageSource access (for internalization) —— 消息转换服务(国际化)

No

Yes

Built-in ApplicationEvent publication mechanism —— 事件发布机制(事件驱动)

No

Yes

2.1 ApplicationContext和它的上下辈们

可以发现 ApplicationContext 不仅继承了 BeanFactory 的两个扩展接口,还继承了其它几个接口,咱都一并来讲解。

2.2 ApplicationContext

2.2.1 ApplicationContext是SpringFramework最核心接口

Central interface to provide configuration for an application. This is read-only while the application is running, but may be reloaded if the implementation supports this.

它是为应用程序提供配置的中央接口。在应用程序运行时,它是只读的,但是如果受支持的话,它可以重新加载。

很言简意赅,ApplicationContext 就是中央接口,它就是 SpringFramework 的最最核心,同时在运行时是只读的。但是,另外它多提了一个概念:重新加载,这个概念很关键,咱会在后面介绍 ApplicationContext 的抽象实现中着重介绍它。

2.2.2 ApplicationContext组合多个功能接口

An ApplicationContext provides:

  • Bean factory methods for accessing application components. Inherited from ListableBeanFactory.

  • The ability to load file resources in a generic fashion. Inherited from the ResourceLoader interface.

  • The ability to publish events to registered listeners. Inherited from the ApplicationEventPublisher interface.

  • The ability to resolve messages, supporting internationalization. Inherited from the MessageSource interface.

  • Inheritance from a parent context. Definitions in a descendant context will always take priority. This means, for example, that a single parent context can be used by an entire web application, while each servlet has its own child context that is independent of that of any other servlet.

ApplicationContext 提供:

  • 用于访问应用程序组件的 Bean 工厂方法。继承自 ListableBeanFactory 。

  • 以通用方式加载文件资源的能力。继承自 ResourceLoader 接口。

  • 能够将事件发布给注册的监听器。继承自 ApplicationEventPublisher 接口。

  • 解析消息的能力,支持国际化。继承自 MessageSource 接口。

  • 从父上下文继承。在子容器中的定义将始终优先。例如,这意味着整个 Web 应用程序都可以使用单个父上下文,而每个 servlet 都有其自己的子上下文,该子上下文独立于任何其他 servlet 的子上下文。

这里面有一点需要注意,ApplicationContext 也是支持层级结构的,但这里它的描述是父子上下文,这个概念要区分理解。上下文中包含容器,但又不仅仅是容器。容器只负责管理 Bean ,但上下文中还包括动态增强、资源加载、事件监听机制等多方面扩展功能。

2.2.3 ApplicationContext负责部分回调注入

In addition to standard BeanFactory lifecycle capabilities, ApplicationContext implementations detect and invoke ApplicationContextAware beans as well as ResourceLoaderAware , ApplicationEventPublisherAware and MessageSourceAware beans.

除了标准的 BeanFactory 生命周期功能外,ApplicationContext 实现还检测并调用 ApplicationContextAware bean 以及 ResourceLoaderAware bean, ApplicationEventPublisherAware 和 MessageSourceAware bean。

2.3 ConfigurableApplicationContext

与上一章的 ConfigurableBeanFactory 类似,它也给 ApplicationContext 提供了 “可写” 的功能,实现了该接口的实现类可以被客户端代码修改内部的某些配置。

2.3.1 ConfigurableApplicationContext提供了可配置的可能

SPI interface to be implemented by most if not all application contexts. Provides facilities to configure an application context in addition to the application context client methods in the ApplicationContext interface.

它是一个支持 SPI 的接口,它会被大多数(如果不是全部)应用程序上下文的落地实现。除了 ApplicationContext 接口中的应用程序上下文客户端方法外,还提供了用于配置应用程序上下文的功能。

这里又提到 SPI 了,咱回头讲到模块装配时再解释这个概念。后面它又提了,ConfigurableApplicationContext 给 ApplicationContext 添加了用于配置的功能,这个说法可以从接口方法中得以体现。ConfigurableApplicationContext 中扩展了 setParent 、setEnvironment 、addBeanFactoryPostProcessor 、addApplicationListener 等方法,都是可以改变 ApplicationContext 本身的方法。

2.3.2 ConfigurableApplicationContext 只希望被调用启动和关闭

Configuration and lifecycle methods are encapsulated here to avoid making them obvious to ApplicationContext client code. The present methods should only be used by startup and shutdown code.

配置和与生命周期相关的方法都封装在这里,以避免暴露给 ApplicationContext 的调用者。本接口的方法仅应由启动和关闭代码使用。

ConfigurableApplicationContext 本身扩展了一些方法,但是它一般情况下不希望让咱开发者调用,而是只调用启动(refresh)和关闭(close)方法。注意这个一般情况是在程序运行期间的业务代码中,但如果是为了定制化 ApplicationContext 或者对其进行扩展,ConfigurableApplicationContext 的扩展则会成为切入的主目标。

2.4 EnvironmentCapable

capable 本意为“有能力的”,在这里解释为 “携带/组合” 更为合适。

在 SpringFramework 中,以 Capable 结尾的接口,通常意味着可以通过这个接口的某个特定的方法(通常是 **getXXX()** )拿到特定的组件。

按照这个概念说法,这个 EnvironmentCapable 接口中就应该通过一个 getEnvironment() 方法拿到 **Environment** ,事实上也确实如此:

public interface EnvironmentCapable {
	Environment getEnvironment();
}

2.4.1 ApplicationContext都具有EnvironmentCapable的功能

Interface indicating a component that contains and exposes an Environment reference.

All Spring application contexts are EnvironmentCapable, and the interface is used primarily for performing instanceof checks in framework methods that accept BeanFactory instances that may or may not actually be ApplicationContext instances in order to interact with the environment if indeed it is available.

它是具有获取并公开 Environment 引用的接口。

所有 Spring 的 ApplicationContext 都具有 EnvironmentCapable 功能,并且该接口主要用于在接受 BeanFactory 实例的框架方法中执行 instanceof 检查,以便可以与环境进行交互(如果实际上是 ApplicationContext 实例)。

从这部分可以知道,ApplicationContext 都实现了这个 EnvironmentCapable 接口,也就代表着所有的 ApplicationContext 的实现类都可以取到 Environment 抽象。至于 Environment 是什么,咱后面 IOC 高级部分会解释,这里简单解释一下。

Environment 是 SpringFramework 中抽象出来的类似于运行环境的独立抽象,它内部存放着应用程序运行的一些配置。

现阶段小伙伴可以这么理解:基于 SpringFramework 的工程,在运行时包含两部分:应用程序本身、应用程序的运行时环境。

2.4.2 ConfigurableApplicationContext可以获取ConfigurableEnvironment

As mentioned, ApplicationContext extends EnvironmentCapable, and thus exposes a getEnvironment() method; however, ConfigurableApplicationContext redefines getEnvironment() and narrows the signature to return a ConfigurableEnvironment. The effect is that an Environment object is 'read-only' until it is being accessed from a ConfigurableApplicationContext, at which point it too may be configured.

如上面所述,ApplicationContext 扩展了 EnvironmentCapable ,因此公开了 getEnvironment() 方法;但是,ConfigurableApplicationContext 重新定义了 getEnvironment() 并缩小了签名范围,以返回 ConfigurableEnvironment 。结果是环境对象是 “只读的” ,直到从 ConfigurableApplicationContext 访问它为止,此时也可以对其进行配置。

这里又看到 Configurable 的概念了,对于可配置的 ApplicationContext ,就可以获取到可配置的 Environment 抽象,这个也不难理解吧。

2.5 MessageSource

Strategy interface for resolving messages, with support for the parameterization and internationalization of such messages. Spring provides two out-of-the-box implementations for production:

  • org.springframework.context.support.ResourceBundleMessageSource: built on top of the standard java.util.ResourceBundle, sharing its limitations.

  • org.springframework.context.support.ReloadableResourceBundleMessageSource: highly configurable, in particular with respect to reloading message definitions.

用于解析消息的策略接口,并支持消息的参数化和国际化。SpringFramework 为生产提供了两种现有的实现:

  • ResourceBundleMessageSource:建立在标准 java.util.ResourceBundle 之上,共享其局限性。

  • ReloadableResourceBundleMessageSource:高度可配置,尤其是在重新加载消息定义方面。

2.6 ApplicationEventPublisher

类名可以理解为,它是事件的发布器。SpringFramework 内部支持很强大的事件监听机制,而 ApplicationContext 作为容器的最顶级,自然也要实现观察者模式中广播器的角色。文档注释中对于它的描述也是异常的简单:

Interface that encapsulates event publication functionality. Serves as a super-interface for ApplicationContext.

封装事件发布功能的接口,它作为 ApplicationContext 的父接口。

所以它就是一个很简单的事件发布/广播器而已,后续在 IOC 进阶部分学习事件驱动机制时会讲解它。

2.7 ResourcePatternResolver

这个接口可能是这几个扩展里最复杂的一个,从类名理解可以解释为“资源模式解析器”,实际上它是根据特定的路径去解析资源文件的。从下面的文档注释中,咱就可以深刻的体会 ResourcePatternResolver 的作用和扩展。

2.7.1 ResourcePatternResolver是ResourceLoader的扩展

Strategy interface for resolving a location pattern (for example, an Ant-style path pattern) into Resource objects. This is an extension to the ResourceLoader interface. A passed-in ResourceLoader (for example, an org.springframework.context.ApplicationContext passed in via org.springframework.context.ResourceLoaderAware when running in a context) can be checked whether it implements this extended interface too.

它是一个策略接口,用于将位置模式(例如,Ant 样式的路径模式)解析为 Resource 对象。 这是 ResourceLoader 接口的扩展。可以检查传入的 ResourceLoader(例如,在上下文中运行时通过 ResourceLoaderAware 传入的 ApplicationContext )是否也实现了此扩展接口。

可以发现,它本身还是 ResourceLoader 的扩展,ResourceLoader 实现最基本的解析,ResourcePatternResolver 可以支持 Ant 形式的带星号 ( * ) 的路径解析( Ant 形式会在下面看到)。

2.7.2 ResourcePatternResolver的实现方式有多种

PathMatchingResourcePatternResolver is a standalone implementation that is usable outside an ApplicationContext, also used by ResourceArrayPropertyEditor for populating Resource array bean properties.

PathMatchingResourcePatternResolver 是一个独立的实现,可在 ApplicationContext 外部使用,ResourceArrayPropertyEditor 使用它来填充 Resource 数组中 Bean 属性。

这一段列出了一种 ResourcePatternResolver 的独立实现:基于路径匹配的解析器,这种扩展实现的特点是会根据特殊的路径来返回多个匹配到的资源文件。

2.7.3 ResourcePatternResolver支持的Ant路径模式匹配

Can be used with any sort of location pattern (e.g. "/WEB-INF/*-context.xml"): Input patterns have to match the strategy implementation. This interface just specifies the conversion method rather than a specific pattern format.

可以与任何类型的位置模式一起使用(例如 "/WEB-INF/*-context.xml" ):输入模式必须与策略实现相匹配。该接口仅指定转换方法,而不是特定的模式格式。

根据前面的文档注释也知道,它支持的是 Ant 风格的匹配模式,这种模式可以有如下写法:

  • /WEB-INF/*.xml :匹配 /WEB-INF 目录下的任意 xml 文件

  • /WEB-INF/**/beans-*.xml :匹配 /WEB-INF 下面任意层级目录的 beans- 开头的 xml 文件

  • /**/*.xml :匹配任意 xml 文件

可以发现这种写法还是蛮灵活的,小伙伴们可以从网上搜索学习更多关于 Ant 风格的写法,不过常用的写法大概就上面几种,掌握写法即可。

2.7.4 ResourcePatternResolver可以匹配类路径下的文件

This interface also suggests a new resource prefix "classpath*:" for all matching resources from the class path. Note that the resource location is expected to be a path without placeholders in this case (e.g. "/beans.xml"); JAR files or classes directories can contain multiple files of the same name.

此接口还为类路径中的所有匹配资源建议一个新的资源前缀 "classpath*: "。请注意,在这种情况下,资源位置应该是没有占位符的路径(例如 "/beans.xml" ); jar 文件或类目录可以包含多个相同名称的文件。

文档注释中又提到了 ResourcePatternResolver 还可以匹配类路径下的资源文件,方式是在资源路径中加一个 classpath*: 的前缀。由此咱也可以知道,ResourcePatternResolver 不仅可以匹配 Web 工程中 webapps 的文件,也可以匹配 classpath 下的文件了。

2.8 ApplicationContext的实现类们

无论是声明单实例 Bean ,还是原型 Bean ,都是用 @Scope 注解标注;在配置类中用 @Bean 注册组件,如果要显式声明作用域,也是用 注解。由此就可以解释这句话了: 产生单实例 Bean 和原型 Bean 所用的 API 是相同的,都是用 注解来声明,然后由 **BeanFactory** 来创建。

答案是有,因为即便存在父子关系,但他们本质上是不同的容器,所以有可能找到多个相同的 Bean 。换句话说,中声明的 Singleton 只是在一个容器中是单实例的,但有了层次性结构后,对于整体的多个容器来看,就不是单实例的了(不太理解) 。

DI :给需要注入的 Service 上标注 等自动注入的注解,并且让 IOC 容器识别这个 Servlet ,完成自动注入【推】

img
img
img
@Scope
@Scope
@Scope
@Autowired