该内容已被发布者删除 该内容被自由微信恢复
文章于 2018年2月21日 被检测为删除。
查看原文
被用户删除
其他

程序员你为什么这么累【续】:编码习惯之配置规范

2017-09-11 晓风轻 程序猿DD

导读:

请先仔细阅读:分享我工作中制定配置文件的习惯

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

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

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

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

  1. @Data

  2. public class Server {

  3.    private int port = 8005;

  4.    private String shutDown = "SHUTDOWN";

  5.    private List<Service> services;

  6. }

  7. @Data

  8. public class Service {

  9.    private String name;

  10.    private List<Connector> connectors;

  11. }

  12. @Data

  13. public class Connector {

  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": null

  12.        },

  13.        {

  14.          "port": 8089,

  15.          "protocol": "AJP",

  16.          "executor": null

  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上增加相关注解

  1. @Data

  2. @XStreamAlias("Server")

  3. public class Server {

  4.    @XStreamAsAttribute

  5.    private int port = 8005;

  6.    @XStreamAsAttribute

  7.    private String shutDown = "SHUTDOWN";

  8.    private List<Service> services;

  9. }

  10. @Data

  11. @XStreamAlias("Service")

  12. public class Service {

  13.    @XStreamAsAttribute

  14.    private String name;

  15.    private List<Connector> connectors;

  16. }

  17. @Data

  18. @XStreamAlias("Connector")

  19. public class Connector {

  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注入,而用工具类获取也是一样,区别不大。

呕心沥血苦口婆心之作,希望对大家有帮助!其他人有好的习惯更加简洁的方式可在作者知乎专栏(点击阅读原文)交流,谢谢阅读!

推荐阅读

系列文章


长按指纹

一键关注

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存