当前位置: 首页 > news >正文

Spring 框架介绍

一、Spring 框架介绍

1. 框架概述

Spring 是 2003 年兴起的轻量级 Java 开源框架,由 Rod Johnson 创建,核心为控制反转(IOC)和面向切面(AOP),用于解决企业应用开发复杂性,是分层的 JavaSE/EE 全栈框架。

2. 框架优点

  • 解耦简化开发,IOC 管理对象创建和依赖关系。
  • 支持 AOP 编程,实现权限拦截、运行监控等功能。
  • 提供声明式事务管理,无需手动编程。
  • 方便程序测试,支持 Junit4 注解测试。
  • 可集成 Struts2、Hibernate 等优秀框架。
  • 封装 JavaEE 难用 API,降低使用难度。

二、Spring 的 IOC 核心技术

1. IOC 概念

IOC 即控制反转,将对象创建权力交给 Spring 框架,用于降低代码耦合度,由 Spring 工厂读取配置文件管理对象。

2. IOC 程序入门

  • 导入 spring-context、commons-logging 等依赖坐标。
  • 编写接口及实现类,定义业务方法。
  • 创建 Spring 配置文件 applicationContext.xml,配置 Bean 标签管理对象。
  • 编写测试类,通过 ApplicationContext 加载配置文件获取 Bean 对象并调用方法。

3. IOC 技术总结

  • ApplicationContext 为工厂接口,实现类有 ClassPathXmlApplicationContext(加载类路径配置文件)和 FileSystemXmlApplicationContext(加载本地磁盘配置文件)。

4. Bean 管理的配置文件方式

  • id 属性唯一标识 Bean,class 属性指定 Bean 全路径。
  • scope 属性定义作用范围,包括 singleton(单例,默认)、prototype(多例)、request、session。
  • init-method 和 destroy-method 属性配置 Bean 初始化和销毁方法,单例 Bean 随容器关闭销毁,多例 Bean 由垃圾回收机制回收。

5. 实例化 Bean 的三种方式

  • 无参数构造方法(默认方式):直接配置 Bean 标签。
  • 静态工厂实例化:配置 Bean 标签指定工厂类和静态工厂方法。
  • 实例工厂实例化:先配置工厂 Bean,再配置目标 Bean 指定工厂 Bean 和实例方法。

一、单例模式的核心定义

单例模式(Singleton Pattern) 是一种创建型设计模式,其核心目标是确保一个类在整个应用程序中仅有一个实例对象,并提供一个全局唯一的访问点来获取该实例。

简单来说,就是让某个类 “一生只能 new 一次”,无论在程序的哪个位置调用,拿到的都是同一个对象实例。

二、单例模式的核心特点

  1. 唯一性:类的实例在全局范围内唯一,避免重复创建多个对象造成资源浪费。
  1. 全局访问性:提供统一的静态方法(如getInstance()),方便程序任何位置获取实例。
  1. 私有构造器:通过私有化构造方法(private 构造方法名()),禁止外部通过new关键字创建实例。
  1. 延迟初始化或饿汉式初始化:实例的创建时机分为 “需要时再创建”(延迟)和 “程序启动时就创建”(饿汉)。

三、单例模式的适用场景

  1. 资源密集型对象:创建成本高、消耗资源多的对象,如数据库连接池、线程池、日志工厂。
  1. 全局共享状态:需要统一管理全局状态的场景,如配置信息类、计数器。
  1. 工具类:无状态的工具类,如日志工具、日期工具,避免重复创建浪费资源。
  1. 系统核心组件:整个系统依赖的核心组件,如缓存管理器、会话管理器,确保数据一致性。

四、单例模式的常见实现方式

(一)饿汉式(立即加载)
1. 实现原理

程序启动时(类加载阶段)就创建实例,无论后续是否使用该实例。

2. 代码示例

public class HungrySingleton {

// 类加载时直接创建实例(线程安全,类加载机制保证唯一)

private static final HungrySingleton INSTANCE = new HungrySingleton();

// 私有构造器,禁止外部new

private HungrySingleton() {}

// 全局访问点

public static HungrySingleton getInstance() {

return INSTANCE;

}

}

3. 优缺点
  • 优点:实现简单,天然线程安全(类加载由 JVM 保证,仅执行一次),获取实例速度快。
  • 缺点:资源浪费,若实例长时间未使用,提前创建会占用内存;无法实现延迟加载。
(二)懒汉式(延迟加载)
1. 基础版(非线程安全)
(1)实现原理

仅在第一次调用getInstance()时创建实例,后续调用直接返回已创建的实例。

(2)代码示例

public class LazySingleton {

// 初始为null,延迟创建

private static LazySingleton instance;

private LazySingleton() {}

public static LazySingleton getInstance() {

// 第一次调用时创建实例

if (instance == null) {

instance = new LazySingleton();

}

return instance;

}

}

(3)优缺点
  • 优点:延迟加载,节省内存,仅在需要时创建实例。
  • 缺点:线程不安全,多线程环境下可能创建多个实例(如两个线程同时进入if (instance == null)判断)。
2. 线程安全版(加锁同步)
(1)实现原理

在getInstance()方法上添加synchronized关键字,保证多线程环境下仅一个线程能进入方法创建实例。

(2)代码示例

public class SafeLazySingleton {

private static SafeLazySingleton instance;

private SafeLazySingleton() {}

// 方法加锁,保证线程安全

public static synchronized SafeLazySingleton getInstance() {

if (instance == null) {

instance = new SafeLazySingleton();

}

return instance;

}

}

(3)优缺点
  • 优点:线程安全,实现延迟加载。
  • 缺点:性能低下,每次调用getInstance()都需要加锁解锁,即使实例已创建(锁竞争导致效率低)。
3. 双重检查锁定(DCL,Double-Check Locking)
(1)实现原理

优化线程安全版的性能问题,通过 “双重判断 + volatile 关键字”,仅在实例未创建时加锁,后续直接返回实例。

(2)代码示例

public class DclSingleton {

// volatile关键字防止指令重排

private static volatile DclSingleton instance;

private DclSingleton() {}

public static DclSingleton getInstance() {

// 第一次检查:避免已创建实例时的锁竞争

if (instance == null) {

// 加锁,保证同一时刻仅一个线程进入

synchronized (DclSingleton.class) {

// 第二次检查:防止多个线程等待锁时重复创建

if (instance == null) {

instance = new DclSingleton();

}

}

}

return instance;

}

}

(3)关键说明
  • volatile 关键字:instance必须用volatile修饰,否则可能出现 “指令重排” 导致的线程安全问题。

原因:instance = new DclSingleton()可拆解为 3 步:①分配内存;②初始化对象;③将instance指向内存地址。JVM 可能重排为①→③→②,若线程 A 执行完①→③,线程 B 第一次检查instance != null,直接返回未初始化的对象,导致空指针异常。

(4)优缺点
  • 优点:线程安全,延迟加载,性能高效(仅第一次创建实例时加锁)。
  • 缺点:实现较复杂,需注意volatile关键字的使用。
(三)静态内部类式(推荐)
1. 实现原理

利用 Java 静态内部类的特性:静态内部类不会随外部类加载而初始化,仅在第一次被调用时初始化,且初始化过程由 JVM 保证线程安全。

2. 代码示例

public class StaticInnerClassSingleton {

// 私有构造器

private StaticInnerClassSingleton() {}

// 静态内部类,存储单例实例

private static class SingletonHolder {

private static final StaticInnerClassSingleton INSTANCE = new StaticInnerClassSingleton();

}

// 全局访问点,调用时触发内部类初始化

public static StaticInnerClassSingleton getInstance() {

return SingletonHolder.INSTANCE;

}

}

3. 优缺点
  • 优点:线程安全(JVM 保证内部类初始化唯一),延迟加载(内部类按需初始化),性能高效(无锁竞争),实现简洁。
  • 缺点:无法通过反射破坏单例(反射可调用私有构造器,需额外处理)。
(四)枚举式(最优,防反射、防序列化)
1. 实现原理

利用 Java 枚举的特性:枚举类的实例是天然的单例,由 JVM 保证唯一,且默认防止反射创建实例、防止序列化破坏单例。

2. 代码示例

public enum EnumSingleton {

// 唯一实例(枚举常量)

INSTANCE;

// 枚举类可添加自定义方法

public void doSomething() {

System.out.println("枚举单例执行操作");

}

}

3. 使用方式

// 获取实例

EnumSingleton singleton = EnumSingleton.INSTANCE;

// 调用方法

singleton.doSomething();

4. 核心优势
  • 天然线程安全:枚举类的实例在类加载时创建,JVM 保证唯一。
  • 防反射破坏:Java 反射机制明确禁止反射创建枚举实例,避免通过Constructor.newInstance()创建多个实例。
  • 防序列化破坏:枚举类默认重写readResolve()方法,序列化后反序列化仍返回原实例(普通单例需手动重写readResolve())。
  • 实现极简:无需手动处理构造器、锁、volatile 等,代码简洁高效。

五、单例模式的常见问题与解决方案

(一)反射破坏单例
1. 问题描述

对于非枚举单例(如饿汉式、懒汉式),可通过 Java 反射调用私有构造器创建新实例,破坏单例唯一性。

2. 解决方案

在私有构造器中添加判断,若实例已存在则抛出异常:

public class HungrySingleton {

private static final HungrySingleton INSTANCE = new HungrySingleton();

private HungrySingleton() {

// 防止反射创建实例

if (INSTANCE != null) {

throw new IllegalStateException("单例实例已存在,禁止重复创建");

}

}

public static HungrySingleton getInstance() {

return INSTANCE;

}

}

(二)序列化破坏单例
1. 问题描述

普通单例类实现Serializable接口后,序列化存储实例,反序列化时会创建新实例,破坏单例。

2. 解决方案

重写readResolve()方法,反序列化时返回已有的单例实例:

import java.io.Serializable;

public class SerializableSingleton implements Serializable {

private static final long serialVersionUID = 1L;

private static volatile SerializableSingleton instance;

private SerializableSingleton() {}

public static SerializableSingleton getInstance() {

if (instance == null) {

synchronized (SerializableSingleton.class) {

if (instance == null) {

instance = new SerializableSingleton();

}

}

}

return instance;

}

// 反序列化时返回原实例

private Object readResolve() {

return getInstance();

}

}

六、单例模式的总结

实现方式

线程安全

延迟加载

防反射

防序列化

性能

推荐度

饿汉式

★★★☆☆

懒汉式(基础版)

★☆☆☆☆

懒汉式(加锁)

★★☆☆☆

双重检查锁定

★★★★☆

静态内部类式

★★★★★

枚举式

★★★★★

推荐选择
  • 若需延迟加载:优先静态内部类式
  • 若需绝对安全(防反射、防序列化):优先枚举式
  • 若无需延迟加载且实现简单:可选择饿汉式
http://www.dtcms.com/a/565916.html

相关文章:

  • 物联网设备物理环境自适应监控与运维策略优化
  • Redis 简介与安装指南
  • 营销网站建设专业服务公司精准大数据营销公司
  • 同性做视频网站wordpress 制作支付页
  • 公司内部网站建设方案最简单的网站建设
  • Linux 系统的内存分布结构及其之间的关系(持续更新)
  • DeviceNet转ProfiNet边缘计算网关赋能:西门子 1200PLC 与库卡机器人通讯配置完整案例
  • 网络卡顿运维排查方案:从客户端到服务器的全链路处理
  • 成都网站seo公司网站优化报告
  • 聊城网站制作价格做名片的网站
  • 辽宁网站建设招标网站如何做百度推广方案
  • ECharts 实战:`connectNulls` 的妙用——绘制连续折线图并跳过 0 值节点
  • Mysql引擎
  • 报表类系统后端API设计思路
  • 谷歌的技术栈是什么?
  • Token 存储与安全防护
  • HAProxy 简介及配置
  • 电商系统网站建设网站客户端制作教程
  • 只会后端不会前端如何做网站免费wordpress页面编辑器
  • BIRGMA验厂要求
  • 铝电解电容器用阳极箔:市场格局、技术演进与未来趋势
  • linux服务-vsftpd搭建
  • SAP PP生产报废单功能分享
  • 汇川H5U+HMI仿真运行追飞剪程序
  • 服装设计网站免费临桂住房和城乡建设局网站
  • 原子性与原子操作
  • Java使用okhttp发送get、post请求
  • 两种上传图片的方式——91张先生
  • web3品牌RWA资产自主发行设计方案
  • 网站公司是做什么的长沙做网站备案