- CPU密集型任务:线程数 ≈ CPU核心数 + 1
- IO密集型任务:线程数 ≈ CPU核心数 * (1 + IO等待时间/CPU计算时间)
- 通用建议:Runtime.getRuntime().availableProcessors()获取CPU核心数作为参考
- CPU使用率:保持在70%-90%之间较理想
- 任务队列长度:队列不应持续增长
- 响应时间:应在可接受范围内
- 吞吐量:达到最优值后不再随线程数增加而提升
- 系统资源:内存、文件描述符等是否充足
- execute(Runnable command):执行无返回值的任务
- submit(Callable task):提交有返回值的任务,返回Future对象
- submit(Runnable task):提交Runnable任务,返回Future
- submit(Runnable task, T result):提交Runnable任务并指定返回结果
- Java对象头中的Mark Word
- 每个Java对象都有一个对象头,其中包含Mark Word
- Mark Word存储了对象的哈希码、GC分代年龄、锁状态等信息
- 锁信息就存储在Mark Word中
- 锁的升级过程(偏向锁->轻量级锁->重量级锁)
- 无锁状态:对象刚创建时的状态
- 偏向锁:只有一个线程访问时,在Mark Word中记录线程ID
- 轻量级锁:多个线程交替访问,通过CAS操作竞争锁
- 重量级锁:多线程竞争激烈时,升级为操作系统层面的互斥锁
- 同步实现
- monitorenter和monitorexit字节码指令
- 每个对象都有一个监视器锁(monitor)
- 进入同步块时执行monitorenter,退出时执行monitorexit
- AQS (AbstractQueuedSynchronizer)
- Java并发包中锁的基础框架
- 使用一个volatile int state表示锁状态
- 通过CAS操作实现锁的获取和释放
- 维护一个FIFO队列管理等待线程
- CAS (Compare And Swap)
- 原子操作,比较并交换
- 现代CPU提供的指令级原子操作
- 是乐观锁的实现基础
- 防止网络过载:通过动态调整发送速率,避免过多数据同时涌入网络导致路由器缓冲区溢出和丢包
- 公平性:确保多个TCP连接能公平共享网络带宽资源
- 提高网络利用率:在不过载的前提下尽可能充分利用可用带宽
- 慢启动(Slow Start)
- 连接开始时,拥塞窗口(cwnd)从1个MSS开始
- 每收到一个ACK,cwnd增加1个MSS(指数增长)
- 直到达到慢启动阈值(ssthresh)或发生拥塞
- 拥塞避免(Congestion Avoidance)
- 当cwnd >= ssthresh时,进入线性增长阶段
- 每RTT时间cwnd增加1个MSS
- 快速重传(Fast Retransmit)
- 收到3个重复ACK时,立即重传丢失的报文段
- 而不必等待超时
- 快速恢复(Fast Recovery)
- 发生快速重传后,调整ssthresh和cwnd
- 避免像超时那样完全从慢启动开始
特性 | String | StringBuffer | StringBuilder |
可变性 | 不可变 | 可变 | 可变 |
线程安全 | 不可变故线程安全 | 线程安全(synchronized方法) | 非线程安全 |
性能 | 高(因不可变) | 较低(同步开销) | 最高 |
使用场景 | 常量字符串 | 多线程环境字符串操作 | 单线程环境字符串操作 |
继承关系 | Object | AbstractStringBuilder | AbstractStringBuilder |
- 通用字段(General Header Fields)
- Cache-Control:控制缓存行为
- Connection:控制连接状态(如keep-alive)
- Date:消息产生的日期时间
- 请求字段(Request Header Fields)
- Host:请求的目标主机和端口号
- User-Agent:客户端信息
- Accept:可接受的响应内容类型
- Authorization:认证信息
- 响应字段(Response Header Fields)
- Server:服务器信息
- Set-Cookie:设置Cookie
- Content-Type:响应体的MIME类型
- Content-Length:响应体长度
- 实体字段(Entity Header Fields)
- Content-Encoding:内容编码方式
- Expires:内容过期时间
- Last-Modified:最后修改时间
- 父类静态变量和静态块
- 子类静态变量和静态块
- 父类实例变量和实例块
- 父类构造方法
- 子类实例变量和实例块
- 子类构造方法
- 定义:
- 负责管理应用中Bean的生命周期
- 提供Bean的创建、配置、组装和管理服务
- 核心功能:
- 依赖注入
- 生命周期管理
- 作用域管理
- AOP代理创建
- 定义:
- 控制反转(Inversion of Control)容器
- 实现依赖注入(DI)模式的核心组件
- 主要实现:
- BeanFactory:基础IOC容器
- ApplicationContext:扩展了更多企业级功能
- 相同点:
- 都负责管理Bean对象
- 都实现依赖注入功能
- 不同点:
特性 | Spring Bean容器 | Spring IOC容器 |
功能范围 | 专注于Bean生命周期管理 | 更广泛,包括资源访问、事件等 |
实现级别 | 概念层面 | 具体接口和实现类 |
使用场景 | 泛指Bean管理功能 | 特指依赖注入实现机制 |
典型代表 | - | BeanFactory, ApplicationContext |
- 两者在大多数情况下可以互换使用
- 严格来说,IOC容器是实现Bean容器功能的机制
- ApplicationContext是功能最完整的IOC容器实现
- IOC(Inversion of Control):控制反转
- 将对象的创建、依赖管理交给容器而非程序员
- 实现原理:
- 通过反射机制动态创建和管理对象
- 维护Bean之间的依赖关系
- 在适当时候注入依赖
- 核心价值:
- 解耦:减少组件间的直接依赖
- 可维护性:集中管理对象生命周期
- 可测试性:便于模拟依赖进行测试
- 灵活性:配置变更不影响代码
- 工作流程:
- 读取配置(注解/XML)
- 创建Bean定义
- 实例化Bean
- 注入依赖
- 初始化Bean
- 提供服务
- 销毁Bean
- 主要接口:
- BeanFactory:基础IOC容器
- ApplicationContext:扩展接口,添加更多企业功能
- BeanDefinition:描述Bean的元数据
- 依赖注入,IOC的具体实现技术
- 容器将依赖关系自动注入到组件中
- 实现方式:
- 构造器注入:通过构造方法注入
- Setter注入:通过setter方法注入
- 字段注入:直接注入字段(反射实现)
- 注入类型:
- 按类型注入:@Autowired(默认按类型)
- 按名称注入:@Qualifier指定名称
- 强制依赖:使用required=true
- 可选依赖:使用required=false
- 优势:
- 减少样板代码
- 提高可测试性
- 降低耦合度
- 配置灵活
- 相关注解:
- @Autowired:自动装配
- @Resource:JSR-250标准注解
- @Inject:JSR-330标准注解
- @Value:注入简单值
- 作用域类型:
- 单例(Singleton):默认,每个容器一个实例
- 原型(Prototype):每次请求创建新实例
- 请求(Request):每个HTTP请求一个实例
- 会话(Session):每个HTTP会话一个实例
- 全局会话(Global Session):Portlet应用专用
- 配置方式:
- 延迟加载(Lazy Initialization):
- 只有第一次使用时才创建实例
- 减少应用启动时间
- 适用于不立即需要的Bean
- 配置方式:
- 组合使用示例:
- 注意事项:
- 延迟加载的Bean在第一次访问时会有轻微性能开销
- 原型作用域的Bean通常需要配合延迟加载
- 某些Bean(如基础设施Bean)不适合延迟加载
- 反射机制:
- Class.forName()加载类
- Constructor.newInstance()创建实例
- Field.set()注入属性
- 动态代理:
- JDK动态代理(基于接口)
- CGLIB代理(基于子类)
- 工厂模式:
- BeanFactory接口定义获取Bean的方法
- 各种实现类提供具体创建逻辑
- 生命周期管理:
- InstantiationAwareBeanPostProcessor
- BeanPostProcessor
- InitializingBean/DisposableBean接口
- 防止资源泄漏:
- 关闭数据库连接
- 释放文件句柄
- 清理网络连接
- 避免内存泄漏:
- 移除缓存引用
- 清理监听器
- 断开对象引用链
- 优雅关闭:
- 保存状态
- 完成未完成的操作
- 记录日志
- 概念:
- 对象不再被使用但无法被GC回收
- 导致内存占用持续增长
- Spring中常见原因:
- 未正确实现DisposableBean
- 静态集合持有Bean引用
- 监听器未正确注销
- 线程池未关闭
- 检测方法:
- 内存分析工具(VisualVM, MAT)
- 监控内存使用情况
- 分析GC日志
- 用户请求-DispatcherServlet
- HandlerMapping找到处理器
- 调用处理器返回ModelAndView
- 视图解析器解析视图
- 渲染视图返回响应
- 清晰的职责分离:
- 各组件分工明确
- 易于维护和扩展
- 灵活配置:
- 支持注解驱动
- 多种视图技术集成
- 强大的数据绑定:
- 自动请求参数绑定
- 支持表单验证
- 国际化支持:
- 本地化解析
- 主题支持
- 测试友好:
- 易于单元测试
- 支持Mock测试
- 集成能力:
- 与其他Spring项目无缝集成
- 支持RESTful开发
- 扩展性强:
- 可自定义各组件实现
- 拦截器机制灵活
- 编程式事务:
- 使用TransactionTemplate
- 通过代码显式控制事务边界
- 精确控制事务范围
- 灵活处理复杂逻辑
- 代码侵入性强
- 容易遗漏提交/回滚
- 声明式事务:
- 使用@Transactional注解
- 基于AOP实现
- 非侵入式
- 配置简单
- 减少样板代码
- 粒度较粗(方法级别)
- 异常处理需注意
传播行为类型 | 说明 |
REQUIRED(默认) | 当前有事务则加入,没有则新建 |
REQUIRES_NEW | 新建事务,挂起当前事务 |
SUPPORTS | 当前有事务则加入,没有则以非事务执行 |
NOT_SUPPORTED | 以非事务执行,挂起当前事务 |
MANDATORY | 必须在事务中运行,否则抛出异常 |
NEVER | 必须在非事务中运行,否则抛出异常 |
NESTED | 嵌套事务执行 |
隔离级别 | 说明 |
DEFAULT | 使用数据库默认级别 |
READ_UNCOMMITTED | 读未提交,可能脏读 |
READ_COMMITTED | 读已提交,避免脏读 |
REPEATABLE_READ | 可重复读,避免脏读和不可重复读 |
SERIALIZABLE | 串行化,最高隔离级别 |
特性 | #{} | ${} |
处理方式 | 预编译处理(占位符?) | 字符串替换(直接拼接SQL) |
安全性 | 防止SQL注入 | 有SQL注入风险 |
参数类型 | 自动识别并转换 | 原样输出 |
适用场景 | 参数值 | 表名、列名等非参数部分 |
日期处理 | 自动格式化为数据库兼容格式 | 需要手动处理 |
空值处理 | 自动处理null | 可能引发语法错误 |
- 优先使用#{},防止SQL注入
- ${}仅用于动态表名、列名等非参数部分
- 使用${}时要确保参数值可信或经过校验
- 复杂SQL可混合使用两者
- 条件不确定的查询:
- 根据不同条件拼接不同SQL
- 避免写多个相似的SQL语句
- 灵活的表操作:
- 动态选择表名、列名
- 适应表结构变化
- 批量操作:
- 动态生成批量插入/更新语句
- 简化批量数据处理
- 避免SQL拼接风险:
- 提供安全的动态SQL构建方式
- 减少手动拼接错误
- if:条件判断
- choose/when/otherwise:多选一
- trim/where/set:处理SQL片段
- foreach:循环处理
- bind:创建变量
- 主体提交认证信息:
- 委托Authenticator认证:
- 调用Realm的doGetAuthenticationInfo方法
- 获取认证信息(AuthenticationInfo)
- 凭证匹配:
- 使用CredentialsMatcher比较提交的和存储的凭证
- 匹配成功完成认证
- 创建已认证主体:
- 绑定主体到当前线程
- 设置认证标志
- 权限检查触发:
- 委托Authorizer授权:
- 调用Realm的doGetAuthorizationInfo方法
- 获取授权信息(AuthorizationInfo)
- 权限验证:
- 检查角色/权限是否匹配
- 不匹配抛出UnauthorizedException
- 访问控制:
- 验证通过允许访问
- 否则拒绝访问
- Subject:当前操作用户
- SecurityManager:安全管理者
- Authenticator:认证器
- Authorizer:授权器
- Realm:安全数据源
- SessionManager:会话管理
特性 | BeanFactory | ApplicationContext |
功能定位 | 基础IOC容器 | 企业级扩展容器 |
加载时机 | 延迟加载(按需初始化) | 启动时预加载所有单例Bean |
国际化支持 | 不支持 | 支持(MessageSource) |
事件发布 | 不支持 | 支持(ApplicationEventPublisher) |
AOP支持 | 需要额外配置 | 内置支持 |
资源访问 | 基本支持 | 更丰富的资源访问方式(ResourceLoader) |
自动注册 | 不支持BeanPostProcessor自动注册 | 支持 |
典型实现 | DefaultListableBeanFactory | ClassPathXmlApplicationContext, AnnotationConfigApplicationContext |
性能 | 启动快,运行时慢 | 启动慢,运行时快 |
使用场景 | 资源受限环境 | 大多数企业应用 |
作用域 | 说明 | 适用场景 | 线程安全要求 |
singleton(默认) | 每个容器一个实例 | 无状态服务,配置类 | 必须线程安全 |
prototype | 每次请求创建新实例 | 有状态Bean | 通常不需要 |
request | 每个HTTP请求一个实例 | Web请求相关数据 | 不需要 |
session | 每个HTTP会话一个实例 | 用户会话数据 | 不需要 |
application | 每个ServletContext一个实例 | Web应用全局数据 | 必须线程安全 |
websocket | 每个WebSocket会话一个实例 | WebSocket通信 | 不需要 |
- 轻量级:
- 非侵入式设计
- 最小化应用代码对框架的依赖
- IOC/DI:
- 松耦合
- 易于测试和维护
- AOP支持:
- 分离横切关注点
- 声明式服务(事务、安全等)
- 集成能力:
- 与各种技术栈无缝集成
- 一站式解决方案
- 模块化设计:
- 按需选择模块
- 灵活组合
- 简化开发:
- 减少样板代码
- 提高开发效率
- 强大的生态:
- Spring Boot
- Spring Cloud
- Spring Data等
- Spring中常见的设计模式:
- 工厂模式:
- BeanFactory
- ApplicationContext
- 单例模式:
- 默认Bean作用域
- 应用上下文
- 代理模式:
- AOP实现
- @Transactional
- 模板方法:
- JdbcTemplate
- RestTemplate
- 观察者模式:
- 事件发布/监听机制
- 适配器模式:
- HandlerAdapter
- AdvisorAdapter
- 装饰者模式:
- Wrapper类
- 动态代理
- 策略模式:
- 资源访问策略
- 事务管理策略
- 默认行为:
- Controller默认是单例
- 必须设计为无状态(避免实例变量)
- 安全实践:
- 使用局部变量而非实例变量
- 使用ThreadLocal保存请求相关状态
- 将共享状态声明为原型作用域
- 并发工具:
- 使用并发集合
- 同步关键代码块
- 作用域选择:
- 对有状态需求使用request/session作用域
- 注解支持:
- @Scope("prototype")使Controller成为原型
- XML配置:
<bean id="collectionBean" class="com.example.CollectionBean"> <property name="list"> <list> <value>Java</value> <ref bean="otherBean"/> </list> </property> <property name="set"> <set> <value>Spring</value></set> </property> <property name="map"> <map> <entry key="key1" value="value1"/> <entry key="key2" ref="otherBean"/> </map> </property>
</bean>
- 注解配置:
@Component
public class CollectionBean { @Autowired private List<MyInterface> implementations; @Resource(name = "myMap") private Map<String, Object> map;
} @Configuration
public class AppConfig { @Bean public List<String> stringList() { return Arrays.asList("A", "B");
}
@Bean public Map<String, Integer> myMap() {Map<String, Integer> map = new HashMap<>(); map.put("key1", 100); return map; }
}
- Java Util类注入:
@Autowired private ResourceLoader resourceLoader;
- 编程式事务:
- 使用TransactionTemplate
- 使用PlatformTransactionManager直接管理
- 声明式事务:
- XML配置:
- 注解驱动:@Transactional
- 基于AOP代理
- 基于字节码生成(ASPECTJ)
- REQUIRED, REQUIRES_NEW, NESTED等
- DEFAULT, READ_UNCOMMITTED等
- 一致性API:
- 统一不同持久化技术的事务API
- 切换持久化技术不影响业务代码
- 声明式支持:
- 通过配置管理事务
- 减少样板代码
- 编程式选择:
- 灵活控制事务边界
- 集成测试:
- 易于模拟和测试
- 多种实现:
- JDBC, JPA, Hibernate等支持
- AOP支持:
- 非侵入式事务管理
- DispatcherServlet:前端控制器
- HandlerMapping:请求到处理器的映射
- Controller:处理业务逻辑
- ModelAndView:封装模型和视图
- ViewResolver:视图名称解析
- HandlerInterceptor:拦截器
- HandlerAdapter:适配不同处理器
- MultipartResolver:文件上传
- LocaleResolver:国际化
- ThemeResolver:主题解析
- 返回JSON:
@RestController
public class AjaxController {@GetMapping("/user") public User getUser() { return new User("John", 30); }
}
- @ResponseBody:
@Controller
public class AjaxController { @RequestMapping("/data")@ResponseBody public String getData() { return "AJAX response"; }
}
- Jackson支持:
<dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId>
</dependency>
- 前端调用:
特性 | Spring MVC | Struts2 |
设计理念 | 基于方法 | 基于类 |
性能 | 更高 | 较低 |
线程安全 | 方法局部变量 | 成员变量需注意 |
拦截器 | HandlerInterceptor | 独立拦截器栈 |
视图技术 | 更灵活 | 主要JSP |
集成 | 与Spring生态无缝 | 需要额外集成 |
REST支持 | 优秀 | 较弱 |
配置 | 注解为主 | XML配置为主 |
- 加载配置:mybatis-config.xml + Mapper XML
- 创建SqlSessionFactory
- 创建SqlSession
- 执行SQL:
- 获取Mapper接口代理
- 解析SQL/参数
- 执行数据库操作
- 返回结果:结果映射
- 关闭会话
- 类型安全
- 避免硬编码
- IDE支持更好
- MyBatis开发步骤:
- 添加依赖:mybatis.jar + 数据库驱动
- 创建全局配置文件:mybatis-config.xml
- 创建实体类
- 创建Mapper接口
- 创建SQL映射文件(XML或注解)
- 获取SqlSessionFactory
- 获取SqlSession
- 获取Mapper接口实例
- 执行数据库操作
- 提交事务/关闭会话
JDBC不足 | MyBatis解决方案 |
大量样板代码 | 自动生成/简化代码 |
手动处理连接/异常 | 自动管理资源 |
SQL与Java代码混合 | SQL与代码分离 |
硬编码参数/结果映射 | 自动参数绑定/结果映射 |
手动处理事务 | 声明式事务支持 |
缓存支持弱 | 提供一/二级缓存 |
不同数据库差异处理复杂 | 方言支持 |
批量操作繁琐 | 提供批量执行器 |
- SQL控制灵活
- 学习曲线平缓
- 轻量级
- 动态SQL强大
- 与Spring集成好
- 性能接近JDBC
- SQL工作量大
- 移植性较差
- 缓存机制较简单
- 复杂映射配置较多