编程习惯之配置规范

  • A+
所属分类:Java

工作中少不了要制定各种各样的配置文件,这里和大家分享一下工作中我是如何制定配置文件的,这是个人习惯,结合强大的spring,效果很不错。

=============================需求==========================

如我们现在有一个这样的配置需求,顶层是Server,有port和shutdown2个属性,包含一个service集合,service对象有name一个属性,并包含一个connector集合,connector对象有port和protocol2个属性。

我一上来不会去考虑是用xml还是json还是数据库配置,我会第一步写好对应的配置bean。如上面的需求,就写3个bean。bean和bean之间的包含关系要体现出来。(使用了lombok)

  1. @Data
  2. public class ServerCfg {
  3.   private int port = 8005;
  4.   private String shutDown = "SHUTDOWN";
  5.   private List<ServiceCfg> services;
  6. }
  7. @Data
  8. public class ServiceCfg {
  9.   private String name;
  10.   private List<ConnectorCfg> connectors;
  11. }
  12. @Data
  13. public class ConnectorCfg {
  14.   private int port = 8080;
  15.   private String protocol = "HTTP/1.1";
  16. }

然后找一个地方先用代码产生这个bean:

  1. @Configuration
  2. public class Configs {
  3.   @Bean
  4.   public ServerCfg createTestBean() {
  5.     ServerCfg server = new ServerCfg();
  6.     // 
  7.     List<ServiceCfg> services = new ArrayList<ServiceCfg>();
  8.     server.setServices(services);
  9.     // 
  10.     ServiceCfg service = new ServiceCfg();
  11.     services.add(service);
  12.     service.setName("Kitty");
  13.     // 
  14.     List<ConnectorCfg> connectors = new ArrayList<ConnectorCfg>();
  15.     service.setConnectors(connectors);
  16.     //
  17.     ConnectorCfg connectorhttp11 = new ConnectorCfg();
  18.     connectorhttp11.setPort(8088);
  19.     connectorhttp11.setProtocol("HTTP/1.1");
  20.     connectors.add(connectorhttp11);
  21.     //
  22.     ConnectorCfg connectorAJP = new ConnectorCfg();
  23.     connectorAJP.setPort(8089);
  24.     connectorAJP.setProtocol("AJP");
  25.     connectors.add(connectorAJP);
  26.     return server;
  27.   }
  28. }

然后先测试,看看是否ok。为了演示,我就直接在controller里面调用一下

  1. @Autowired
  2. ServerCfg cfg;
  3. @GetMapping(value = "/configTest")
  4. @ResponseBody
  5. public ResultBean<ServerCfg> configTest() {
  6.   return new ResultBean<ServerCfg>(cfg);
  7. }

测试一下,工作正常

编程习惯之配置规范

然后进行业务代码编写,等到所有功能测试完毕,就是【开发后期】,再来定义配置文件。中途当然少不了修改格式,字段等各种修改,对于我们来说只是修改bean定义,so easy。

都ok了,再决定使用哪种配置文件。如果是json,我们这样:

==============================JSON

===========================

把上面接口调用的json复制下来,报存到配置文件。

编程习惯之配置规范

json内容

  1. {
  2.   "port"8005,
  3.   "shutDown""SHUTDOWN",
  4.   "services": [
  5.     {
  6.       "name""Kitty",
  7.       "connectors": [
  8.         {
  9.           "port"8088,
  10.           "protocol""HTTP/1.1",
  11.           "executor":
  12.         },
  13.         {
  14.           "port"8089,
  15.           "protocol""AJP",
  16.           "executor":
  17.         }
  18.       ]
  19.     }
  20.   ]
  21. }

然后修改config的bean生成的代码为:

  1. import com.fasterxml.jackson.databind.ObjectMapper;
  2. @Configuration
  3. public class Configs {
  4.   @Value("classpath:config/tomcat.json")
  5.   File serverConfigJson;
  6.   @Bean
  7.   public ServerCfg readServerConfig() throws IOException {
  8.     return new ObjectMapper().readValue(serverConfigJson, ServerCfg.class);
  9.   }
  10. }

代码太简洁了,有没有?!

==============================XML

===========================

如果使用XML,麻烦一点,我这里使用XStream序列化和反序列化xml。

首先在bean上增加XStream相关注解

  1. @Data
  2. @XStreamAlias("Server")
  3. public class ServerCfg {
  4.   @XStreamAsAttribute
  5.   private int port = 8005;
  6.   @XStreamAsAttribute
  7.   private String shutDown = "SHUTDOWN";
  8.   private List<ServiceCfg> services;
  9. }
  10. @Data
  11. @XStreamAlias("Service")
  12. public class ServiceCfg {
  13.   @XStreamAsAttribute
  14.   private String name;
  15.   private List<ConnectorCfg> connectors;
  16. }
  17. @Data
  18. @XStreamAlias("Connector")
  19. public class ConnectorCfg {
  20.   @XStreamAsAttribute
  21.   private int port = 8080;
  22.   @XStreamAsAttribute
  23.   private String protocol = "HTTP/1.1";
  24. }

然后修改产品文件的bean代码如下:

  1. @Configuration
  2. public class Configs {
  3.   @Value("classpath:config/tomcat.xml")
  4.   File serverConfigXML;
  5.   @Bean
  6.   public ServerCfg readServerConfig() throws IOException {
  7.     return XMLConfig.toBean(serverConfigXML, ServerCfg.class);
  8.   }
  9. }

XMLConfig工具类相关代码:

  1. public class XMLConfig {
  2.   public static String toXML(Object obj) {
  3.     XStream xstream = new XStream();
  4.     xstream.autodetectAnnotations(true);
  5.     // xstream.processAnnotations(Server.class);
  6.     return xstream.toXML(obj);
  7.   }
  8.   public static <T> T toBean(String xml, Class<T> cls) {
  9.     XStream xstream = new XStream();
  10.     xstream.processAnnotations(cls);
  11.     T obj = (T) xstream.fromXML(xml);
  12.     return obj;
  13.   }
  14.   public static <T> T toBean(File file, Class<T> cls) {
  15.     XStream xstream = new XStream();
  16.     xstream.processAnnotations(cls);
  17.     T obj = (T) xstream.fromXML(file);
  18.     return obj;
  19.   }
  20. }

XStream库需要增加以下依赖:

  1. <dependency>
  2.   <groupId>com.thoughtworks.xstream</groupId>
  3.   <artifactId>xstream</artifactId>
  4.   <version>1.4.10</version>
  5. </dependency>

所以个人爱好,格式推荐json格式配置。

=========================编码习惯=========================

配置文件编码禁忌:

1. 读取配置的代码和业务代码耦合在一起!大忌!千万千万不要!

如下,业务代码里面出现了json的配置代码。

  1. public void someServiceCode() {
  2.   // 使用json配置,这里读取到了配置文件,返回的是json格式
  3.   JSONObject config = readJsonConfig();
  4.   // 如果某个配置了
  5.   if(config.getBoolean("somekey")){
  6.     // dosomething
  7.   }
  8.   else{
  9.   }
  10. }

2. 开发初期就定配置文件

毫无意义,还导致频繁改动!先定义bean,改bean简单多了。我的习惯是转测试前一天才生成配置文件。

=============================重要

============================

最主要的思想是,不要直接和配置文件发生关系,一定要有第三者(这里是配置的bean)。你可以说是中间件,中介都行。 否则,一开始说用xml配置,后面说用json配置,再后面说配置放数据库?这算不算需求变更?你们说算不算?算吗?不算吗?何必这么认真呢?只是1,2行代码的问题,这里使用xml还是json,代码修改量是2行。而且改了测试的话,写个main函数或者junit测试即可,不需要测试业务,工程都不用起,你自己算算节约多少时间。

另外,代码里面是使用spring的习惯,没有spring也是一样的,或者配置的bean你不用spring注入,而用工具类获取也是一样,区别不大。

呕心沥血苦口婆心之作,希望对大家有帮助!其他人有好的习惯更加简洁的方式请在留言区留言,我会逐一回复的,谢谢阅读!

所有的代码细节都在已经上了github了,地址 xwjie/PLMCodeTemplate,欢迎加星。有问题欢迎提出。

本文来源:知乎(晓风轻)

发表评论

:?::razz::sad::evil::!::smile::oops::grin::eek::shock::???::cool::lol::mad::twisted::roll::wink::idea::arrow::neutral::cry::mrgreen:

目前评论:1   其中:访客  1   博主  0

    • avatar 2048 3

      不错的编程习惯