您可以捐助,支持我们的公益事业。

1元 10元 50元





认证码:  验证码,看不清楚?请点击刷新验证码 必填



  求知 文章 文库 Lib 视频 iPerson 课程 认证 咨询 工具 讲座 Model Center   Code  
会员   
   
 
     
   
 
 订阅
Java应用结构规范
 
作者: 阿卓
   次浏览      
 2022-5-9
 
编辑推荐:
在Java程序设计和应用程序开发中,是一个参考模型的同类型设计,提供“轻量级”的应用层级结构、代码明细、细节关系、各层规范和通用工具展开描述。 希望对您的学习有所帮助。
本文来自于微信公众号阿里开发者,由火龙果软件Linda编辑、推荐。

序言

在Java程序设计和应用程序开发中,是一个参考模型的同类型设计,提供“轻量级”的应用层级结构。 、代码明细、细节关系、各层规范和通用工具展开描述。

一三结构

web(前端请求层)

biz(业务层)

dal(数据层)

客户端(请求外部层)

common(公共外部层)

立面(外观层)

 

start(启动类)

qtest(测试类)

三、关系关系

注意点:

服务和服务可以直接相互调用;

服务可以调用多个域的域能力;

域能力是封装好的颗粒度的能力,不可相互调用;

查询服务调用管理器,不调用直接域能力;

四 各层规范

web(前端请求层)

定义统一的异常处理切面:处理业务异常和其他运行时异常;

biz(业务层)

内部服务不做异常处理和返回结果封装类,异常都给web层和facade层处理。

服务和其他服务区分开,单独一个查询包中;

唯一的一个领域,并且塑造出极小的颗粒度的能力。

外部服务要在远程中做好异常处理和封装;

公共业务层中的普通类只是在应用内部使用的类;

dal(数据层)

mapper要按不同类型的数据源存放,如adb和xdb。

common(公共外部层)

常见的只暴露给外部的行为、性质和枚举;

暴露给外部的 d 以只保留外部的必要字段,其他字段如功能等不可存在。

立面(外观层)

定义统一的异常处理切面:处理业务异常和其他运行时异常;

门面的hsf类只做的参数化和业务层化,不要写简单的实现逻辑。

五通用代码和工具

web(前端请求层)

统一异常处理切面

@RestControllerAdvice
public class RestExceptionHandler {


@ResponseStatus(HttpStatus.OK)
@ExceptionHandler(Exception.class)
public Result system(HttpServletRequest req, Exception e) {
AllLoggers.EXCEPTION.error("
RestExceptionHandler.system|
servlet:{}|method:{}|code:{}|msg:{}",
req.getServletPath(),req.getMethod(), e.getMessage(), e);
return Result.error(ResultCode.BASE.SYSTEM_ERROR);
}

@ResponseStatus(HttpStatus.OK)
@ExceptionHandler(BusinessException.class)
public Result business(HttpServletRequest req,
BusinessException e) {
AllLoggers.EXCEPTION.error("RestExceptionHandler.
business|servlet:{}|method:{}|code:{}|msg:{}",
req.getServletPath(),req.getMethod(), e.getMessage(), e);
return Result.error(e.getErrorCode(), e.getErrorMessage());

biz(业务层)

统一日志打印工具类


import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public interface AllLoggers {

/**
* 应用日志
*/
Logger APPLICATION = LoggerFactory.getLogger("APPLICATION");

/**
* 异常日志
*/
Logger EXCEPTION = LoggerFactory.getLogger("EXCEPTION");

/**
* 业务日志
*/
Logger BIZ = LoggerFactory.getLogger("BIZ");

/**
* hsf日志
*/
Logger HSF = LoggerFactory.getLogger("HSF");

/**
* 入口日志
*/
Logger MTOP = LoggerFactory.getLogger("MTOP");

}

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!-- https://github.com/spring-projects/ spring-boot/
blob/v1.5.13.RELEASE/spring-boot/src/main/resources/org
/springframework/ boot/logging/logback/defaults.xml -->
<include resource="
;org/springframework/boot/ logging/logback/defaults.xml" />

<property resource="application.
properties"></property>
<property name="APP_NAME"
value="toms" />
<property name="LOG_PATH"
value="${user.home}/${APP_NAME}/logs" />
<property name="LOG_FILE"
value="${LOG_PATH}/toms-root.log" />
<appender name="APPLICATION"
class="ch.qos.logback.core.
rolling.RollingFileAppender">
<file>${LOG_FILE}/toms-root.log</file>
<encoder>
<pattern><![CDATA[%d{yyyy-MM-dd
HH:mm:ss.SSS} [%thread] [%level] [traceId:%X{EAGLEEYE_TRACE_ID}]
[%class:%line]

- %m %n ]]> </pattern>
<charset>UTF-8</charset>
</encoder>
<rollingPolicy
class="ch.qos.logback.core.rolling
.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${LOG_PATH}/logs_saved/toms-root.
%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<maxHistory>5</maxHistory>
<maxFileSize>1GB</maxFileSize>
<totalSizeCap>20GB</totalSizeCap>
</rollingPolicy>
</appender>
<appender name="CONSOLE"
class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>${CONSOLE_LOG_PATTERN}</pattern>
<charset>utf8</charset>
</encoder>
</appender>
<!--业务日志-->
<appender name="TOMS-BIZ-APPENDER"
class="ch.qos.logback.core.rolling.
RollingFileAppender">
<File>${LOG_PATH}/toms-biz.log</File>
<rollingPolicy class="ch.qos.
logback.core.rolling.
SizeAndTimeBasedRollingPolicy">
<FileNamePattern>
${LOG_PATH}/logs_saved/toms-biz.
%d{yyyy-MM-dd}.%i.log</FileNamePattern>
<maxHistory>5</maxHistory>
<maxFileSize>2GB</maxFileSize>
<totalSizeCap>20GB</totalSizeCap>
</rollingPolicy>
<encoder>
<pattern><![CDATA[%d{yyyy-MM-dd HH:mm:ss.SSS}
[%thread] [%level] [traceId:%X{EAGLEEYE_TRACE_ID}]
[%class:%line] - %m %n ]]> </pattern>
<charset>UTF-8</charset>
</encoder>
</appender>
<!--hsf日志-->
<appender name="TOMS-HSF-APPENDER"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<File>${LOG_PATH}/toms-hsf.log</File>
<rollingPolicy class="ch.qos.logback.core.rolling.
SizeAndTimeBasedRollingPolicy">
<FileNamePattern>${LOG_PATH}/logs_saved/toms-hsf.
% d{yyyy-MM-dd}.%i.log</FileNamePattern>
<maxHistory>5</maxHistory>
<maxFileSize>2GB</maxFileSize>
<totalSizeCap>20GB</totalSizeCap>
</rollingPolicy>
<encoder>
<pattern><![CDATA[%d{yyyy-MM-dd HH:mm:ss.SSS}
[%thread] [%level] [traceId:%X{EAGLEEYE_TRACE_ID}]
[%class:%line] - %m %n ]]> </pattern>
<charset>UTF-8</charset>
</encoder>
</appender>

<!-- 通用错误日志 -->
<appender name="TOMS-ERROR-APPENDER"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<File>${LOG_PATH}/toms-error.log</File>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>ERROR</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
<rollingPolicy class="ch.qos.logback.core.rolling.
SizeAndTimeBasedRollingPolicy">
<FileNamePattern>${LOG_PATH}/logs_saved/toms-error.
%d{yyyy-MM-dd}.%i.log</FileNamePattern>
<maxHistory>5</maxHistory>
<maxFileSize>2GB</maxFileSize>
<totalSizeCap>10GB</totalSizeCap>
</rollingPolicy>
<encoder>
<pattern><![CDATA[%d{yyyy-MM-dd HH:mm:ss.SSS}
[%thread] [%level] [traceId:%X{EAGLEEYE_TRACE_ID}] [%class:%line]
- %m %n ]]> </pattern>
<charset>UTF-8</charset>
</encoder>
</appender>

<!-- 异常日志 -->
<appender name="TOMS-EXCEPTION-APPENDER"
class="ch.qos.logback.core.
rolling.RollingFileAppender">
<File>${LOG_PATH}/toms-exception.log</File>
<rollingPolicy class="ch.qos.logback.core.rolling.
TimeBasedRollingPolicy">
<FileNamePattern>${LOG_PATH}/logs_saved/toms-
exception.%d{yyyy-MM-dd}.log</FileNamePattern>
<maxHistory>5</maxHistory>
</rollingPolicy>
<encoder>
<pattern><![CDATA[%d
{yyyy-MM-dd HH:mm:ss.SSS} [%thread] [%level]
[traceId:%X{EAGLEEYE_TRACE_ID}] [%class:%line] - %m %n ]]> </pattern>
<charset>UTF-8</charset>
</encoder>
</appender>

<logger name="HSF"
level="${logback.info .level}" additivity="false">
<appender-ref ref="TOMS-HSF-APPENDER"/>
</logger>

<logger name="BIZ"
level="${logback.info .level}" additivity="false">
<appender-ref ref="TOMS-BIZ-APPENDER"/>
<appender-ref ref="TOMS-ERROR-APPENDER"/>
</logger>

<logger name="EXCEPTION"
level="${logback.info. level}" additivity="false">
<appender-ref ref="TOMS-EXCEPTION-APPENDER"/>
<appender-ref ref="TOMS-ERROR-APPENDER"/>
</logger>

<root level="INFO">
<appender-ref ref="CONSOLE" />
</root>
</configuration>

单位转换工具类

public class UnitConvertUtils {

/**
* 米和千米的进率
*/
public static final double RATE_OF_METRE_AND_KILOMETRE = 1000d;
public static final int INT_RATE_OF_METRE_AND_KILOMETRE = 1000;

/**
* 分和元的进率
*/
public static final double RATE_OF_FEN_AND_YUAN = 100d;

/**
* 立方厘米和立方米的进率
*/
public static final double INT_RATE_OF_CM3_AND_M3 = 1000000d;

/**
* 米转千米
*
* @param toConvert
* @return 异常返回null
*/
public static Double convertMetre2Kilometre(Long toConvert) {
if (toConvert == null) {
return null;
}
return toConvert / RATE_OF_METRE_AND_KILOMETRE;
}

/**
* 千米转米
*
* @param toConvert
* @return 异常返回null
*/
public static Long convertKilometre2Metre(Double toConvert) {
if (toConvert == null) {
return null;
}

BigDecimal bigDecimal = BigDecimal.valueOf(toConvert);
BigDecimal factorBigDecimal = BigDecimal.valueOf (RATE_OF_METRE_AND_KILOMETRE);

return bigDecimal.multiply(factorBigDecimal).longValue();
}

/**
* 元转分
*
* @param toConvert
* @return 异常返回null
*/
public static Long convertYuan2Fen(Double toConvert) {
if (toConvert == null) {
return null;
}

BigDecimal bigDecimal = BigDecimal.valueOf(toConvert);
BigDecimal factorBigDecimal = BigDecimal . valueOf(RATE_OF_FEN_AND_YUAN);

return bigDecimal.multiply(factorBigDecimal).longValue();
}

/**
* 元转分
*
* @param toConvert
* @return 异常返回null
*/
public static Long convertYuan2Fen(String toConvert) {
if (toConvert == null) {
return null;
}

BigDecimal bigDecimal = BigDecimal.valueOf (ConvertUtils.convertString 2Double(toConvert));
BigDecimal factorBigDecimal = BigDecimal. valueOf(RATE_OF_FEN_AND_YUAN);

return bigDecimal.multiply(factorBigDecimal).longValue();
}

/**
* 分转元
*
* @param price
* @return
*/
public static String convertFen2Yuan(Long price) {
if (price == null) {
return null;
}

return BigDecimal.valueOf(price).divide(new BigDecimal(RATE_OF_FEN_AND_YUAN)).toString();
}

/**
* 里程米转换为千米
*
* @param distance
* @return
*/
public static Double meter2Kilometer(Long distance) {
if (distance == null) {
return null;
}

BigDecimal meter = BigDecimal.valueOf(distance);
BigDecimal kilometer = meter.divide(new BigDecimal

(INT_RATE_OF_METRE_AND_KILOMETRE));
return kilometer.doubleValue();
}

/**
* 立方厘米转立方米
*
* @param volume
* @return
*/
public static String convertCm32M3(Long volume) {
if (volume == null) {
return null;
}

return BigDecimal.valueOf(volume).divide(new BigDecimal(INT_RATE_OF_CM3_AND_M3)).toString();
}

}

 

 

 
   
次浏览       
相关文章

Java微服务新生代之Nacos
深入理解Java中的容器
Java容器详解
Java代码质量检查工具及使用案例
相关文档

Java性能优化
Spring框架
SSM框架简单简绍
从零开始学java编程经典
相关课程

高性能Java编程与系统性能优化
JavaEE架构、 设计模式及性能调优
Java编程基础到应用开发
JAVA虚拟机原理剖析

最新活动计划
MBSE(基于模型的系统工程)4-18[北京]
自然语言处理(NLP) 4-25[北京]
基于 UML 和EA进行分析设计 4-29[北京]
以用户为中心的软件界面设计 5-16[北京]
DoDAF规范、模型与实例 5-23[北京]
信息架构建模(基于UML+EA)5-29[北京]
 
 
最新文章
Java虚拟机架构
JVM——Java虚拟机架构
Java容器详解
Java进阶--深入理解ArrayList实现原理
Java并发容器,底层原理深入分析
最新课程
java编程基础到应用开发
JavaEE架构、 设计模式及性能调优
高性能Java编程与系统性能优化
SpringBoot&Cloud、JavaSSM框架
Spring Boot 培训
更多...   
成功案例
国内知名银行 Spring+SpringBoot+Cloud+MVC
北京 Java编程基础与网页开发基础
北京 Struts+Spring
华夏基金 ActiveMQ 原理
某民航公 Java基础编程到应用开发
更多...