一、引言
在企业级Java应用开发中,公共资源模块是基础设施的重要组成部分。它负责管理系统中共享的资源,如配置文件、日志、缓存、工具类等,为各业务模块提供统一的服务接口。本文将详细介绍一个完整的Java公共资源模块的设计思路、架构实现及核心代码。
二、系统架构设计
1. 模块架构
common-resource/
├── config/ # 配置管理
├── logging/ # 日志管理
├── cache/ # 缓存管理
├── utils/ # 工具类
├── exception/ # 异常处理
└── core/ # 核心组件
2. 技术选型
- 配置管理:使用Apache Commons Configuration
- 日志管理:SLF4J + Logback
- 缓存管理:Caffeine
- 工具类:Apache Commons Lang、Guava
- 依赖注入:Spring Framework
三、核心代码实现
1. 配置管理模块
java
// ConfigManager.java
package com.common.resource.config;
import org.apache.commons.configuration2.Configuration;
import org.apache.commons.configuration2.FileBasedConfiguration;
import org.apache.commons.configuration2.PropertiesConfiguration;
import org.apache.commons.configuration2.builder.FileBasedConfigurationBuilder;
import org.apache.commons.configuration2.builder.fluent.Parameters;
import org.apache.commons.configuration2.ex.ConfigurationException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
/**
* 配置文件管理类,支持加载和读取配置信息
*/
public class ConfigManager {
private static final Logger logger = LoggerFactory.getLogger(ConfigManager.class);
private static final String DEFAULT_CONFIG_FILE = "application.properties";
private Configuration config;
public ConfigManager() {
this(DEFAULT_CONFIG_FILE);
}
public ConfigManager(String configFilePath) {
try {
Parameters params = new Parameters();
FileBasedConfigurationBuilder<FileBasedConfiguration> builder =
new FileBasedConfigurationBuilder<FileBasedConfiguration>(PropertiesConfiguration.class)
.configure(params.properties()
.setFileName(configFilePath));
config = builder.getConfiguration();
logger.info("配置文件加载成功: {}", configFilePath);
} catch (ConfigurationException e) {
logger.error("配置文件加载失败: {}", configFilePath, e);
throw new RuntimeException("配置文件加载失败", e);
}
}
/**
* 获取字符串配置
*/
public String getString(String key) {
return config.getString(key);
}
/**
* 获取字符串配置,带默认值
*/
public String getString(String key, String defaultValue) {
return config.getString(key, defaultValue);
}
/**
* 获取整数配置
*/
public int getInt(String key) {
return config.getInt(key);
}
/**
* 获取整数配置,带默认值
*/
public int getInt(String key, int defaultValue) {
return config.getInt(key, defaultValue);
}
/**
* 获取布尔配置
*/
public boolean getBoolean(String key) {
return config.getBoolean(key);
}
/**
* 获取布尔配置,带默认值
*/
public boolean getBoolean(String key, boolean defaultValue) {
return config.getBoolean(key, defaultValue);
}
/**
* 检查配置是否存在
*/
public boolean containsKey(String key) {
return config.containsKey(key);
}
}
2. 日志管理模块
java
// LoggerUtil.java
package com.common.resource.logging;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* 日志工具类,提供统一的日志记录接口
*/
public class LoggerUtil {
/**
* 获取业务日志记录器
*/
public static Logger getBusinessLogger() {
return LoggerFactory.getLogger("business");
}
/**
* 获取系统日志记录器
*/
public static Logger getSystemLogger() {
return LoggerFactory.getLogger("system");
}
/**
* 获取数据库操作日志记录器
*/
public static Logger getDbLogger() {
return LoggerFactory.getLogger("database");
}
/**
* 获取性能监控日志记录器
*/
public static Logger getPerformanceLogger() {
return LoggerFactory.getLogger("performance");
}
/**
* 记录方法执行时间
*/
public static void logMethodTime(String className, String methodName, long startTime) {
long endTime = System.currentTimeMillis();
long duration = endTime - startTime;
getPerformanceLogger().info("方法执行时间: {}.{}() - {}ms", className, methodName, duration);
}
}
3. 缓存管理模块
java
// CacheManager.java
package com.common.resource.cache;
import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.concurrent.TimeUnit;
/**
* 缓存管理类,使用Caffeine实现本地缓存
*/
public class CacheManager {
private static final Logger logger = LoggerFactory.getLogger(CacheManager.class);
private static final int DEFAULT_MAX_SIZE = 1000;
private static final int DEFAULT_EXPIRE_TIME = 30; // 分钟
private Cache<String, Object> cache;
public CacheManager() {
this(DEFAULT_MAX_SIZE, DEFAULT_EXPIRE_TIME);
}
public CacheManager(int maxSize, int expireTime) {
cache = Caffeine.newBuilder()
.maximumSize(maxSize)
.expireAfterWrite(expireTime, TimeUnit.MINUTES)
.removalListener((key, value, cause) ->
logger.debug("缓存项被移除: key={}, cause={}", key, cause))
.build();
logger.info("缓存管理器初始化完成: maxSize={}, expireTime={}分钟", maxSize, expireTime);
}
/**
* 添加缓存项
*/
public void put(String key, Object value) {
cache.put(key, value);
logger.debug("添加缓存项: key={}", key);
}
/**
* 获取缓存项
*/
public <T> T get(String key) {
return (T) cache.getIfPresent(key);
}
/**
* 获取缓存项,不存在时通过loader加载
*/
public <T> T get(String key, CacheLoader<T> loader) {
return (T) cache.get(key, k -> {
try {
return loader.load();
} catch (Exception e) {
logger.error("加载缓存项失败: key={}", key, e);
return null;
}
});
}
/**
* 移除缓存项
*/
public void remove(String key) {
cache.invalidate(key);
logger.debug("移除缓存项: key={}", key);
}
/**
* 清空所有缓存
*/
public void clear() {
cache.invalidateAll();
logger.info("清空所有缓存");
}
/**
* 缓存加载接口
*/
public interface CacheLoader<T> {
T load() throws Exception;
}
}
4. 异常处理模块
java
// BaseException.java
package com.common.resource.exception;
/**
* 基础异常类,所有自定义异常都应继承此类
*/
public class BaseException extends RuntimeException {
private static final long serialVersionUID = 1L;
private String errorCode;
private Object[] args;
public BaseException(String errorCode, String message) {
super(message);
this.errorCode = errorCode;
}
public BaseException(String errorCode, String message, Throwable cause) {
super(message, cause);
this.errorCode = errorCode;
}
public BaseException(String errorCode, Object[] args, String message) {
super(message);
this.errorCode = errorCode;
this.args = args;
}
public BaseException(String errorCode, Object[] args, String message, Throwable cause) {
super(message, cause);
this.errorCode = errorCode;
this.args = args;
}
// Getters
public String getErrorCode() {
return errorCode;
}
public Object[] getArgs() {
return args;
}
}
// ExceptionHandler.java
package com.common.resource.exception;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;
/**
* 全局异常处理器
*/
@ControllerAdvice
public class ExceptionHandler {
private static final Logger logger = LoggerFactory.getLogger(ExceptionHandler.class);
@ExceptionHandler(value = BaseException.class)
@ResponseBody
public Map<String, Object> handleBaseException(HttpServletRequest req, BaseException e) {
logger.error("业务异常: {}", e.getMessage(), e);
Map<String, Object> result = new HashMap<>();
result.put("code", e.getErrorCode());
result.put("message", e.getMessage());
result.put("success", false);
return result;
}
@ExceptionHandler(value = Exception.class)
@ResponseBody
public Map<String, Object> handleGeneralException(HttpServletRequest req, Exception e) {
logger.error("系统异常: {}", e.getMessage(), e);
Map<String, Object> result = new HashMap<>();
result.put("code", "500");
result.put("message", "系统内部错误,请稍后再试");
result.put("success", false);
return result;
}
}
5. 工具类模块
java
// StringUtil.java
package com.common.resource.utils;
import org.apache.commons.lang3.StringUtils;
/**
* 字符串工具类
*/
public class StringUtil extends StringUtils {
/**
* 判断字符串是否为JSON格式
*/
public static boolean isJson(String str) {
if (isEmpty(str)) {
return false;
}
str = str.trim();
if (str.startsWith("{") && str.endsWith("}")) {
return true;
}
if (str.startsWith("[") && str.endsWith("]")) {
return true;
}
return false;
}
/**
* 生成随机字符串
*/
public static String generateRandomString(int length) {
String base = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
StringBuilder sb = new StringBuilder();
for (int i = 0; i < length; i++) {
int randomInt = (int) (Math.random() * base.length());
sb.append(base.charAt(randomInt));
}
return sb.toString();
}
/**
* 驼峰转下划线
*/
public static String camelToUnderline(String str) {
if (isEmpty(str)) {
return str;
}
StringBuilder sb = new StringBuilder();
for (int i = 0; i < str.length(); i++) {
char c = str.charAt(i);
if (Character.isUpperCase(c)) {
if (i > 0) {
sb.append("_");
}
sb.append(Character.toLowerCase(c));
} else {
sb.append(c);
}
}
return sb.toString();
}
}
// DateUtil.java
package com.common.resource.utils;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* 日期工具类
*/
public class DateUtil {
public static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd";
public static final String DEFAULT_DATETIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
/**
* 日期转字符串
*/
public static String formatDate(Date date) {
return formatDate(date, DEFAULT_DATE_FORMAT);
}
/**
* 日期时间转字符串
*/
public static String formatDateTime(Date date) {
return formatDate(date, DEFAULT_DATETIME_FORMAT);
}
/**
* 日期转字符串,自定义格式
*/
public static String formatDate(Date date, String format) {
if (date == null) {
return null;
}
SimpleDateFormat sdf = new SimpleDateFormat(format);
return sdf.format(date);
}
/**
* 字符串转日期
*/
public static Date parseDate(String dateStr) throws ParseException {
return parseDate(dateStr, DEFAULT_DATE_FORMAT);
}
/**
* 字符串转日期时间
*/
public static Date parseDateTime(String dateStr) throws ParseException {
return parseDate(dateStr, DEFAULT_DATETIME_FORMAT);
}
/**
* 字符串转日期,自定义格式
*/
public static Date parseDate(String dateStr, String format) throws ParseException {
if (dateStr == null || dateStr.isEmpty()) {
return null;
}
SimpleDateFormat sdf = new SimpleDateFormat(format);
return sdf.parse(dateStr);
}
/**
* 获取当前时间戳(毫秒)
*/
public static long currentTimeMillis() {
return System.currentTimeMillis();
}
/**
* 获取当前日期
*/
public static Date currentDate() {
return new Date();
}
}
四、模块集成与配置
1. Spring配置
java
// CommonResourceConfig.java
package com.common.resource.config;
import com.common.resource.cache.CacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* 公共资源模块Spring配置
*/
@Configuration
public class CommonResourceConfig {
/**
* 配置缓存管理器
*/
@Bean
public CacheManager cacheManager() {
return new CacheManager();
}
/**
* 配置配置管理器
*/
@Bean
public ConfigManager configManager() {
return new ConfigManager();
}
}
2. Logback配置
xml
<!-- logback.xml -->
<configuration>
<property name="LOG_DIR" value="logs"/>
<property name="APP_NAME" value="common-resource"/>
<!-- 控制台输出 -->
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<!-- 业务日志 -->
<appender name="BUSINESS" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_DIR}/${APP_NAME}-business.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${LOG_DIR}/archive/${APP_NAME}-business.%d{yyyy-MM-dd}.log.gz</fileNamePattern>
<maxHistory>30</maxHistory>
</rollingPolicy>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %msg%n</pattern>
</encoder>
</appender>
<!-- 系统日志 -->
<appender name="SYSTEM" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_DIR}/${APP_NAME}-system.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${LOG_DIR}/archive/${APP_NAME}-system.%d{yyyy-MM-dd}.log.gz</fileNamePattern>
<maxHistory>30</maxHistory>
</rollingPolicy>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<!-- 数据库日志 -->
<appender name="DATABASE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_DIR}/${APP_NAME}-database.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${LOG_DIR}/archive/${APP_NAME}-database.%d{yyyy-MM-dd}.log.gz</fileNamePattern>
<maxHistory>30</maxHistory>
</rollingPolicy>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %msg%n</pattern>
</encoder>
</appender>
<!-- 性能日志 -->
<appender name="PERFORMANCE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_DIR}/${APP_NAME}-performance.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${LOG_DIR}/archive/${APP_NAME}-performance.%d{yyyy-MM-dd}.log.gz</fileNamePattern>
<maxHistory>30</maxHistory>
</rollingPolicy>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %msg%n</pattern>
</encoder>
</appender>
<!-- 根日志 -->
<root level="INFO">
<appender-ref ref="CONSOLE"/>
</root>
<!-- 业务日志 -->
<logger name="business" level="INFO">
<appender-ref ref="BUSINESS"/>
</logger>
<!-- 系统日志 -->
<logger name="system" level="INFO">
<appender-ref ref="SYSTEM"/>
</logger>
<!-- 数据库日志 -->
<logger name="database" level="INFO">
<appender-ref ref="DATABASE"/>
</logger>
<!-- 性能日志 -->
<logger name="performance" level="INFO">
<appender-ref ref="PERFORMANCE"/>
</logger>
</configuration>
五、使用示例
1. 获取配置信息
java
ConfigManager configManager = new ConfigManager();
String dbUrl = configManager.getString("db.url");
int port = configManager.getInt("server.port", 8080);
2. 记录日志
java
LoggerUtil.getBusinessLogger().info("业务操作执行成功");
LoggerUtil.getSystemLogger().error("系统发生异常", exception);
3. 使用缓存
java
CacheManager cacheManager = new CacheManager();
// 添加缓存
cacheManager.put("user:1", user);
// 获取缓存
User cachedUser = cacheManager.get("user:1", User.class);
// 获取缓存,不存在时加载
User user = cacheManager.get("user:1", () -> userService.getUserById(1));
4. 字符串工具类
java
String jsonStr = "{\"name\":\"test\"}";
boolean isJson = StringUtil.isJson(jsonStr);
String randomStr = StringUtil.generateRandomString(10);
String underlineStr = StringUtil.camelToUnderline("userName");
5. 日期工具类
java
String dateStr = DateUtil.formatDate(new Date());
String datetimeStr = DateUtil.formatDateTime(new Date());
Date date = DateUtil.parseDate("2023-01-01");
Date datetime = DateUtil.parseDateTime("2023-01-01 12:00:00");
六、毕业设计文档框架
1. 引言
1.1 研究背景与意义
1.2 国内外研究现状
1.3 研究内容与方法
1.4 论文组织结构
2. 相关技术基础
2.1 Java语言特性
2.2 Spring框架
2.3 日志框架
2.4 缓存技术
3. 系统需求分析
3.1 功能需求
3.2 非功能需求
3.3 用例分析
4. 系统设计
4.1 总体架构设计
4.2 模块设计
4.3 数据结构设计
4.4 界面设计
5. 系统实现
5.1 开发环境搭建
5.2 核心模块实现
5.3 界面实现
5.4 资源管理
6. 系统测试
6.1 测试环境与方法
6.2 功能测试
6.3 性能测试
6.4 测试结果分析
7. 总结与展望
7.1 研究成果总结
7.2 不足之处与改进方向
7.3 研究展望
七、总结
本公共资源模块为Java应用提供了一套完整的基础设施,包括配置管理、日志管理、缓存管理、异常处理和常用工具类等功能。通过合理的架构设计和模块化实现,该模块具有良好的可扩展性和可维护性,可以作为企业级Java应用的基础组件。
在实际项目中,可以根据具体需求对模块进行扩展,例如增加分布式缓存支持、添加更多工具类、实现更复杂的配置管理等。通过不断完善和优化,公共资源模块可以为整个系统提供更加稳定和高效的支持。