JAVA技术开发规范Word格式文档下载.docx
《JAVA技术开发规范Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《JAVA技术开发规范Word格式文档下载.docx(22页珍藏版)》请在冰豆网上搜索。
Maven--3.6.1
1.1.3数据库
持久化数据库统一使用Mysql,必要时使用MongoDB。
Mysql--8.0.17
MongoDB--4.0.1
1.1.4缓存
缓存统一使用Redis,消息队列使用RabbitMq。
Redis--5.0.5
RabbitMq--3.7.17
1.1.5SpringBootSpringCloud开发插件
Mybatis--3.5.2
SpringBoot--2.1.8
SpringCloud各个组件后期再补充
1.2命名规范
1.2.1项目命名
我们统一使用maven构建项目,项目命名遵循业界规范或标准,
命名模板:
xxxx-project/xxxx-projects;
例如:
产品项目,production-project或production-projects,单数或复数取决于此项目下是否包含多个项目,如果只有一个项目,用单数,多个用复数;
1.2.2模块命名
模块是指maven模块,一个maven模块可能是一个项目的模块,也有可能是一个项目或工程,而且一个模块也有可作为一个单独的模块或项目存在.
命名模板:
项目名-模块名,例如:
产品项目的基础数据模块,production-basic,模块名也要注意单数复数。
1.2.3包命名
包命名:
com.hzins.项目.模块,例如:
基础服务平台邮件项目的数据库实体包com.hzins.bsp.mail.domain,统一用单数。
1.2.4接口、类、抽象类、常量类、枚举等命名
1.命名规则应该尽量使用业界常用或一致约定认同的名词,例如:
客户,业界一般使用Customer,但Client也有客户的意思,但大家不要使用Client,业务对Client往往有客户端的解释,若无法与业务相匹配,应该使用名词,遵循简单明了准确的原则;
2.普通业务接口、类、抽象类不要用框架类名称,尽量要简单直接的业务名称,例如:
UserService,CustomerFacade等;
3.什么是框架类名称,框架往往是解决是类问题,所以名称与业务无关,例如:
Request、Response、MethodInvoker、DataProcessor、ExecutorService、InsertWorker、MessageHandler、Message等,这接口或类名从业务角度看无法给人直面意思,但用于做框架设计时能直接的
4.业务性质项目的层次结构命名,往往以业务名称+层次为结尾,例如:
UserController、UserFacade、UserService、UserMapper、PaymentProvider等。
5.框架类或接口应该尽量粗,尽量与业务无法,除非此框架类只设计于某特定业务。
6.常量为应该与Constants为结尾,模板:
XXXXConstatns,例如:
MailConstants、UserConstants、SystemConstants;
常量类使用普通类,不要使用接口。
7.抽象类命名:
AbstractXXXX,例如:
AbstractFacade、AbstractService、AbstractInitializer;
1.2.5静态常量属性命名
静态常量属性命名,名称全部大写,多个名称之间用“_”分开,例如:
publicstaticfinalintTYPE_OF_USER=1;
publicstaticfinalintENABELED=1;
publicstaticfinalintNOT_ENABEL=2;
1.2.6方法命名
方法命名:
名称是动词或某个行为名称,例如:
getUser、setUset、execute、processValue、loadConfig等,都是一些动词和行为。
1.2.7文件命名
文件命名:
xxx.*或xxx-yyy.*例如:
cache-redis.xml、database.properties
名称.*,多个单词间用“-”分开。
1.2.8目录命名
目录命名:
直接名称,多个单词间用“-”分开,和文件命名一样,只是没有后缀,例如:
spring-config、config、init-data;
Properties属性命名规范
1.统一以”.”隔开多个单词
2.按类型分开,比如:
“jdbc.url”,”jdbc.user”
3.键值统一以“=”分开,不能“:
”
1.3业务性质项目层次划分
1.3.1provider层可选
如果使用了远程通讯,这层是远程通讯层,统一命名为provider层,因这此层是服务提供层,这层只关注通讯相关的业务,例如:
远程消息和本地消息的相互转换等,不关注具体业务,而Facade层是门面层,通讯层通过调用Facade层,由Facade层做具体业务。
1.provider层包命名:
com.hzins.xxx.xxx.provider
2.provider类或接口命名:
XXXXProvider
1.3.2facade层
1.facade层聚合service层;
2.为什么要有facade层;
A、当Service需要调用另一个Service层时,就会出现层次结构不清晰的情况。
B、当有某个业务需要调用多个Service层,并且有写操作时,会出现事务问题,抽象出Facade层就可以很好解决这个问题,将事务控制在facade层。
3.facade层包命名:
com.hzins.xxx.xxx.facade
4.fcade类或接口命名:
XXXXFacade
5.facade层方法命名与Service层不完全一致,大家要注意:
facade层聚合可聚合多个Service,属性比较上层,越是上层命名越靠近业务,例如:
UserFacade有一个方法是登录,userFacade.login(userName,password);
而Service层,不应该出现userService.login(.....)这样的方法,Service层的方法往往是getXXX、findXXX、loadXXX、queryXXX、deleteXX、updateXXX等这类方法。
6.远程调用统一在Facade层或Provider层
1.3.3service层
1.service层聚合persistence层或repository层,同时集成事务处理;
2.service层包命名:
com.hzins.xxx.xxx.service;
3.service类或接口命名:
XXXXService;
4.service层方法命名与persistence(MyBatis)层方法命名不应该完成一致,因为persistence层是面向jdbc操作,所以persistence层的方法往往是,insert,update,delete,select等这类方法,而Service层,不是面向jdbc操作。
1.3.4persistence层
1.Persistence层当使用MyBatis时,统一把持久层命名为persistence;
2.Repository层当使用JPA时,统一把持久层命名为repository;
3.Persistence/Repository层包命名:
com.hzins.xxx.xxx.persistence/repository
4.Persistence层注意方法命名,mybatis没有对jdbc做封装,只是做sql的映射,所以Persistence层是面向Jdbc操作,所以命名应面向jdbc,例如:
selectByPrimary、insertXXX、deleteXXX、updateXXX;
repository是JPA的叫法,JPA对JDBC做了封装,所以repository层的方法命名跟Service层比较类似,saveXXX、
findXXXByXXX、queryByXXXX等。
5.Persistence层类命名,名称+Mapper,例如:
UserMapper、CompanyMapper;
如果使用JPA,persistence层就是repository层,
Repository层类命名:
名称+Repository,例如:
UserRepository,CurdRepository等。
6.Mybatissql映射文件统一放resources下,按mapper所在包命名文件夹
1.3.5domain层
这层只能是实体类,不能有其他类;
1.所有数据库的实体类应该放在domain层;
2.domain层包命名:
com.hzins.xxx.xxx.domain;
3.实体为命名:
模拟+名称,例如:
UserInfo、UserDetail、CompanyInfo、CompanyDetail,这样就能一目了然,直接知道实体类属性某个模块,并且会自动排序。
1.4日常开发
1.4.1关键字使用
1.4.1.1protected
修改变量或方法时,一般是留给字类用的,也就是一般是在abstract时使用比较多,大家不要滥用protected,
1.4.1.2abstract
一般的abstract类命名规范:
Abstract开头+类名称,例如:
AbstractFacade,AbstractService等。
1.4.1.3static
一个类中不要同时有public的静态方法和非静态方法,例如:
publicclassUserService{
publicstaticvoidprocessValue(Objectvalue){
//todosomething.
}
publicUsergetUserById(LonguserId){
}
1.4.1.4Final
1.一般属性使用名词,例如:
privateintuserStatus;
privatebooleanisEnable;
privateUseruser;
2.不可变或不需要修改属性命名,例如:
privatefinalintage=120;
privatefinalbooleanisEnable=true;
privatefinalLoggerloger=LoggerFacatory.getLogger(XXXXX.class);
如果确定某个属性不再需要或不可改变,应该加上final,因为其他人维护你的代码时可能会修改原来的值,一旦修改,程序就会有隐患。
1.4.1.5Finally
在进行数据库操作,IO操作以及lock操作时,必须确保资源在使用完毕后得到释放,并且必须确保释放操作在finally中进行。
1.4.1.6synchronized
避免太多的使用synchronized关键字,使用synchronized的时候要判断是否适合集群环境
1.4.1.7Threadlocal
尽量避免使用threadlocal,控制不当容易引起内存泄露和线程池使用导致数据跨线程读取,
注意内存污染
1.4.1.8return
错误方式:
PublicStringprocessValue(){
Stringvalue=test();
returnvalue;
publicbooleanisXXX(){
intv1=test1();
intv2=test1();
returnv1>
v2;
正确方式:
returntest();
returntest1()>
test()2;
1.4.1.9while
1.4.2变量
1.4.2.1幽灵变量
一定不要使用幽灵变量,错误方式,例如:
doSomething(123)这段代码中123就是幽灵变量,没有人知道123是什么意思,正确方式,例如:
longid=123;
doSomething(id);
1.4.2.2字符串变量
字符串变量,就尽量使用常量,错误方式:
if(flag.equals(“exit”)){
//doSomething();
if(flag.equals(SystemConstants.EXIT_OF_FLAG)){
1.4.2.3有状态变量/集群
服务端开发人员在日常开发中,应该避免使用有状态的组件或工具类,因为在大多数情况下,服务端都是集群部署。
publicclassUserFacade{
privatebooleanisLogin;
publicvoidlogin(StringuserName,Stringpassword){
login=true;
大家要避免这种情况,因为这个isLogin是服务端公用的,只在一个实例中修改状态,其他实例无法知道,正确做法是使用缓存或服务共享方式(例如:
数据库等),除非你能确定你的状态无关集群多实例。
1.4.2.4成员变量
成员变量,绝大多数情况要加访问修饰,比如private,错误方式:
publicclassUserService{
UserMapperuserMapper;
publicvoidaddUser(Useruser){
userMapper.insert(user);
正确方式:
privateUserMapperuserMapper;
1.4.2.5静态常量类定义
1.常量定义:
public/protected/...Staticfinal[Type]XXX_AAA=value;
2.static在final前;
1.4.3事务
1.4.3.1Annotation方式事务
统一使用Annotation方式事务。
1.4.3.2事务原子性
如果某个业务需要调用到多个service,且有多个写操作,此时会有事务问题,解决办法:
1.增加facade层,在facade层调用多个Service,然后在facade方法使用事务(Annotation方式),2.使用TransactionBuilder工具类做多事务处理。
1.4.4集合对象
1.4.4.1命名
1.List/Set/Vector/数组等集合变量命名一定为复数
2.Map或其他Map接口,变量命名方式例如:
Map<
String,User>
usersMap,尽量用Map结尾,形成统一规范。
1.4.4.2非空
所有集合对象返回均不可为null,错误方式,例如:
publicList<
String>
getUserNames(intvar){
List<
userNames=null;
if(var>
ExampeConstants.IS_VALIDATA){
userNames=findByUserNames(var);
returnuserNames;
正确方式,例如:
userNames=Lists.newArrayList();
userNames.addAll(findByUserNames(var));
returnuserNames;
1.4.5工具以及框架
1.4.5.1Json
1.统一使用Jackson
2.目前Jackson是Json架构中最快最稳定的;
3.Jackson能轻松做Json和XML与Java对象相互转换;
4.Spring消息转换器默认使用Jackson;
5.不要在业务代码中直接使用Json
1.4.5.2Spring
在使用spring时,有些组件使用xml配置,有些使用annotation方式配置,在什么情况下使用xml试,什么情况下使用annotation要统一。
Xml方式配置
1.第三方框架集成
2.连接信息配置
3.变动频率高
4.浸入性强
5.高耦合
Annotation方式配置
除xml方式外的组件都使用annotation方式;
Annotation使用
@Service
Service层使用@Service方式注册;
例如:
@Service
@Component
一般组件使用@Component注册;
publicclassUserFacade{
@Resource
一般注入引用使用@Resource
privateUserServiceuserService;
@PostConstruct
Spring容器启动时初始化@PostConstruct
例如:
publicvoidinit(){
@PreDestroy
Spring容器关闭时销毁@PreDestroy
publicvoiddestroy(){
组件初始化及销毁说明
1.凡是spring组件在初始化或销毁时执行的方法一定要输出日志,是一种提醒,让人知道程序在启动或销毁是都做了些什么,是一个良好的编程习惯。
logger.info(“----------descriptioninitializecase----------------”)
logger.info(“----descriptiondestroycase----------”)
2.尽量使用统一的初始化组件或销毁组件,当然如果更适合在其他组件中也可以,不强制,但应该尽量统一在某个组件。
publicclassCompanyInitializer{
publicvoidinitialize1(){
logger.info(“----descriptioninitializecase----------”)
publicvoidinitialize2(){
logger.info(“-----descriptioninitializecase---------”)
publicclassCompanyDestructor{
publicvoiddestroy1(){
logger.info(“------descriptiondestroycase--------------”)
publicvoiddestroy2(){
logger.info(“----descriptiondestroycase------------”)
配置文件结构
Xml->
spring
非spring的xml另建一个包
conf:
配置文件统一目录
evn:
属性文件目录
default.properties
默认环境配置
develop.properties
开发环境配置
production.properties
生产环境配置
test.properties
测试环境配置
schema:
sql脚本目录
xml:
xml配置文件目录
all.xml:
程序引导文件
context.xml:
程序环境文件,包扫描,注解开启,properties扫描等
1.4.5.2日志
1.统一使用日志服务和sfl4j+logbak
2.关键业务建议使用日志服务的同时也用logback日志,双保险。
日志使用方式,
logger.info(“--------”+var1+”----+”ver2”+-------”+var3)
logger.info(“--------{}----+{}-------{}”,var1,var2,ver3)
日志文件名
XXX-YYYY.{date}.log
XXX:
系统或服务名称,例如:
mail-server.log,production-basic.log
YYYY:
服务端或客户端等,不强制,但命名是一定要准备,给人一目了然的感觉。
{date}:
日期,可配置