Spring 项目 Java 访问修饰符 + 非访问修饰符全景梳理详解

Spring 项目 Java 访问修饰符 + 非访问修饰符全景梳理详解

前言

Java 修饰符分为两大体系:访问权限修饰符(控制类 / 成员可见范围)非访问修饰符(定义特性、生命周期、Spring 框架专属语义)。 SpringBoot/Spring 开发中,修饰符贯穿 Controller、Service、Mapper、实体类、工具类、配置类全场景,不同修饰符搭配注解会产生截然不同的 Bean 生命周期、依赖注入、序列化、继承效果。 本文以多表格拆分 + 场景适配 + Spring 工程实操规范完整梳理。

一、第一大类:访问权限修饰符(4 个,控制可见范围)

核心作用:限定类、成员变量、成员方法、构造器可被调用的范围,作用域从小到大排序:private < 默认(包私有) < protected < public

表 1:四大访问修饰符作用域对照表

修饰符

中文名称

本类内部

同一个包下其他类

子类(不同包)

任意包所有类

Spring 项目常规使用场景

private

私有

✅ 可见

❌ 不可见

❌ 不可见

❌ 不可见

1.Service 注入的 Mapper 成员变量 2. 实体类 PO/DO 所有属性字段 3. 工具类内部私有工具方法 4. 常量私有成员

(无修饰符) default

包私有 / 默认

✅ 可见

✅ 可见

❌ 不可见

❌ 不可见

Spring 极少主动使用;仅同一包内协作工具类临时方法

protected

受保护

✅ 可见

✅ 可见

✅ 可见

❌ 不可见

1. 父类公共基础 PO 审计字段(createTime/updateTime) 2. 抽象父 Service 通用业务模板方法

public

公共

✅ 可见

✅ 可见

✅ 可见

✅ 可见

1.Controller 所有接口方法 2.Service 接口定义、实现类对外业务方法 3.Mapper 接口 4. 对外暴露的工具类静态方法

表 2:访问修饰符使用硬性规范(Spring 工程最佳实践)

代码元素

推荐修饰符

禁止使用

原因说明

实体类 PO/DTO/Form 属性字段

private

public

封装特性,通过 get/set 访问;Jackson 序列化默认适配私有字段

Service 层注入 Mapper 对象

private

public/protected

依赖注入无需对外暴露,保证封装

Controller 接口请求方法

public

其他

SpringMVC 需要外部反射调用接口方法,必须 public

业务接口(XXXService)

public

default

跨包调用实现类,必须公共

工具类内部工具方法

private

public

仅类内调用,无需对外开放

抽象父类模板方法

protected

private

供子类重写拓展,外部不可调用

二、第二大类:基础非访问修饰符(Java 原生核心修饰符,Spring 高频搭配注解使用)

模块 1:static 静态修饰符

表 3:static 修饰不同元素效果 + Spring 场景

修饰对象

核心特性

Spring 开发适用场景

禁忌场景

static 变量(静态变量)

属于类本身,不属于实例;全局唯一一份内存,所有对象共享

1. 全局常量(public static final) 2. 工具类全局配置参数

不能修饰 @Autowired 注入成员(静态变量无法被 Spring 自动注入)

static 方法(静态方法)

无需 new 实例,类名。方法名 () 直接调用;内部只能访问静态资源

通用工具类:日期转换、Bean 拷贝、加解密工具方法

不能调用非静态成员;不能加 @Transactional 事务注解(事务依赖实例代理)

static 代码块

类加载时执行一次,仅初始化静态资源

工具类加载初始化配置、加载证书文件

业务层几乎不用

static 内部类

脱离外部类可独立实例化

复杂 DTO 嵌套内部枚举 / 子对象

极少使用

模块 2:final 最终修饰符(不可修改)

表 4:final 修饰不同元素规则对照表

修饰对象

语义约束

Spring 项目使用场景

final 变量

赋值一次后永久不可修改

1. 全局常量:public static final String REDIS_PREFIX = "user:";2. 方法入参(禁止方法内篡改入参对象引用)

final 方法

子类无法重写该方法

父类固定模板方法,不允许子类篡改核心逻辑

final 类

类不能被继承(无子类)

1. 通用工具类(BeanUtil、DateUtil) 2. 枚举类默认都是 final

模块 3:abstract 抽象修饰符(面向接口编程核心,Spring 架构基石)

表 5:abstract 使用规则 & 业务场景

修饰对象

约束规则

Spring 架构场景

abstract 抽象类

不能 new 实例;可包含抽象方法 + 普通成员变量 / 普通方法

通用父 BaseService、BaseController,封装分页、异常统一处理

abstract 抽象方法

无方法体,必须被子类实现重写

模板方法模式,定义业务标准流程,子类差异化实现

关键:接口 interface 默认所有方法都是 public abstract

模块 4:synchronized /volatile/transient 并发序列化修饰符

表 6:并发 & 序列化修饰符场景明细

修饰符

核心作用

Spring 使用场景

synchronized

同步锁,保证多线程原子性、可见性

定时任务多线程并发争抢资源、库存扣减简易加锁(分布式推荐 Redisson)

volatile

保证变量内存可见性,禁止指令重排

多线程全局开关标记(定时任务启停标记)

transient

序列化忽略字段

PO 实体中不需要存入 Redis / 序列化的临时字段

三、第三大类:Spring 生态专属语义修饰(结合注解生效,Java 原生修饰符 + Spring 注解联动)

Spring 不会新增语法修饰符,但通过原生修饰符 + 框架注解赋予特殊生命周期、依赖注入、代理特性,是业务开发最常用组合。

表 7:@Autowired 注入场景修饰符搭配规范

成员变量修饰符

搭配 @Autowired 效果

推荐度

private

Spring 反射无视私有权限,可正常注入;封装性最好

⭐⭐⭐⭐⭐ 标准写法

protected

子类可直接访问注入对象,适合父子 Service 继承场景

⭐⭐⭐⭐

public

外部可随意修改注入 Bean,破坏容器单例,不推荐

final

搭配构造注入推荐写法:private final UserMapper userMapper;构造器注入不可变 Bean

⭐⭐⭐⭐⭐ Spring 官方推荐

表 8:Bean 作用域 + 修饰符联动(单例 / 多例)

修饰符组合

Bean 生命周期特性

使用场景

private static + @Autowired

禁止使用!静态变量只会注入一次,单例容器下会出现注入失效

❌ 严禁

private final + 构造注入

Bean 创建完成后无法被修改,线程安全,无循环依赖隐患

✅ 生产首选

四、第四大类:方法专属修饰符汇总(接口 / 实现类方法全覆盖)

表 9:方法所有修饰符组合含义对照表

修饰符组合

适用位置

核心作用

public void

Controller 接口方法

接收前端 http 请求,SpringMVC 反射调用

public + @Override

Service 实现类重写接口方法

实现业务规范,编译器校验方法签名

protected abstract

抽象父类模板方法

预留拓展点,子类必须实现

private static

工具类内部静态工具方法

全局调用,无状态线程安全

public static final

常量工具方法

逻辑永久固定,不可重写

private synchronized

类内多线程同步方法

本地锁保证线程安全

五、综合总表:Spring 分层代码全层级修饰符标准配置

表 10:项目各层代码统一修饰符规范(企业级开发标准)

代码分层

代码元素

标准修饰符

补充说明

控制层 Controller

public

交给 SpringMVC 扫描注册 Bean

请求接口方法

public

必须公共才能被外部访问

业务层 Service

业务接口

public

跨包调用

接口实现类(@Service)

public

IOC 容器托管

注入 Mapper 成员变量

private final

构造器注入官方最优方案

业务实现方法

public

供上层调用

数据访问层 Mapper

Mapper 接口

public

MyBatis 扫描生成代理对象

实体层 PO/DTO/Form

实体类

public

序列化反射需要

所有属性字段

private

封装,get/set 访问

get/set 方法

public

Jackson 序列化依赖公共 getter

通用工具类

工具类

public final

禁止继承

工具方法

public static

类名直接调用

全局常量

public static final

统一配置常量

配置类 Configuration

配置类

public

Spring 扫描配置 Bean

@Bean 生成对象方法

public

容器注册第三方组件

六、高频易错坑点总结

❌ 静态变量不能使用 @Autowired:static 属于类加载阶段,早于 Spring 容器初始化,注入一定会失效;

❌ private 方法不能加 @Transactional:Spring 事务基于 JDK/CGLIB 动态代理,私有方法无法被代理拦截,事务不生效;

✅ final 成员变量推荐构造器注入:杜绝字段注入循环依赖问题,线程安全性更高;

✅ 实体属性一律 private:遵循 Java 封装原则,适配 JSON 序列化、MyBatis 字段映射;

❌ 接口内变量默认 public static final,方法默认 public abstract,无需手动书写。