zoukankan      html  css  js  c++  java
  • 代码阅读小记(一)

    最近在阅读公司内部一套UI 自动化框架的代码,市面上的UI自动框架,八九不离十都是采用WebDriver+TestNG,这个框架也不例外。这篇文章先不讨论整个UI自动化框架的实现,只是记录其中碰到的一些编码知识。看代码的过程中也有一些要吐槽的,比如一个类文件有2k多行,一个类到最上端的基类,经历五次继承。看也有很多值得借鉴的地方

    一、 直接访问抽象类中静态方法   - 日志类的实现

    之前写代码一般会将日志类写成单例模式,保证只实例化一次。在这次的代码里,作者用了另一种方式,即将日志类定义成抽象类,然后直接访问抽象类中的静态方法。

    public abstract class LoggerFactory extends LogFactory{
        public static Logger getLogger(Class clazz){
          return getLogger(getLog(clazz));        
     }
    
    }

    因为静态方法属于类,不需要实例

    public class A {
        protected static Logger logger= LoggerFactory.getLogger(A.class);
        public void method(){
          logger.info("This is a test!");
     }
    }

    二、ThreadLocal的使用

    ThreadLocal,是Thread Local Variable,即线程的局部变量的意思,从字面理解就是为每一个使用该变量的线程提供一个变量副本。

    ThreadLocal提供常用方法:

          T get():   返回线程局部变量中当前线程副本中的值

           void remove(): 删除线程局部变量中当前线程副本中的值

           void set(T value): 设置此线程局部变量中当前线程副本中的值

    线程中的变量只对本线程可见,避免了多线程对同一变量的访问冲突。

    场景:有一Servlet调用一个business method,有一需求,每个对Servert的request但要有一个唯一的transaction id, 并将这个id传给business method以便记录日志。有一个解决方法是讲id作为参数传递给business method,但这并不是个good ideal !

    这时候就该ThreadLocal上场了。产生id ,并将它保存在ThreadLocal中,这样buisness method就可以直接访问了。

    package com.veerasundar;
    
    public class Context {
    
        private String transactionId = null;
    
            /* getters and setters here */
    
    }

    MyThreadLocal作为一个容器,来保存Context Object. 同时,注意ThreadLocal是作为静态变量以便调用的。

    package com.veerasundar;
    
    /**
     * this class acts as a container to our thread local variables.
     * @author vsundar
     *
     */
    public class MyThreadLocal {
    
        public static final ThreadLocal<Context> userThreadLocal = new ThreadLocal();
    
        public static void set(Context user) {
            userThreadLocal.set(user);
        }
    
        public static void unset() {
            userThreadLocal.remove();
        }
    
        public static Context get() {
            return userThreadLocal.get();
        }
    }
    package com.veerasundar;
    
    public class ThreadLocalDemo extends Thread {
    
        public static void main(String args[]) {
    
            Thread threadOne = new ThreadLocalDemo();
            threadOne.start();
    
            Thread threadTwo = new ThreadLocalDemo();
            threadTwo.start();
        }
    
        @Override
        public void run() {
            // sample code to simulate transaction id
            Context context = new Context();
            context.setTransactionId(getName());
    
            // set the context object in thread local to access it somewhere else
            MyThreadLocal.set(context);
    
            /* note that we are not explicitly passing the transaction id */
            new BusinessService().businessMethod();
            MyThreadLocal.unset();
    
        }
    }
    package com.veerasundar;
    
    public class BusinessService {
    
        public void businessMethod() {
            // get the context from thread local
            Context context = MyThreadLocal.get();
            System.out.println(context.getTransactionId());
        }
    }

    三、Java Annotations and Java Reflection

    在框架中看到了自定义的Annotation,之前对于Annotation的理解也是很模糊的,在网上看到一篇很通俗的文档,翻译过来。

    • Java中的Annotations

    Annotations,中文字面意思注释,其本身对其所注释的code , 代码逻辑并没有直接影响,annotations提供了一些额外的信息。这些额外的信息可以被其他comonents所用。比如,常见的@Override,当Java编译器看到这个annotation时,它就会去检查@Override所注释的方法有没有真的覆盖接口或父类中的方法。

    • 定义自己的Annotations
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.METHOD)
    public @interface InstallerMethod {
    }

    和接口的定义有点象哦,@Retention定义annotation的适用范围,如RetentionPolicy.ClASS,注释保留在class file中,但是VM不会处理 。@Target定义被用在,class,fileds,还是methods上

    • 通过反射机制来处理自定义Annotations

    可以通过java反射机制来处理自定义的Annotations,看例子

    package com.vogella.annotations;
    
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    
    @Target(value = ElementType.METHOD)
    @Retention(value = RetentionPolicy.RUNTIME)
    public @interface CanRun {
    
    }
    package com.vogella.annotations;
    
    import java.lang.reflect.Method;
    
    public class AnnotationRunner {
    
      public void method1() {
        System.out.println(&quot;method1&quot;);
      }
    
      @CanRun
      public void method2() {
        System.out.println(&quot;method2&quot;);
      }
    
      @CanRun
      public void method3() {
        System.out.println(&quot;method3&quot;);
      }
    
      public void method4() {
        System.out.println(&quot;method4&quot;);
      }
    
      public void method5() {
        System.out.println(&quot;method5&quot;);
      }
    
    }
    package com.vogella.annotations;
    
    import java.lang.reflect.Method;
    
    public class MyTest {
    
      public static void main(String[] args) {
    
        AnnotationRunner runner = new AnnotationRunner();
        Method[] methods = runner.getClass().getMethods();
    
        for (Method method : methods) {
          CanRun annos = method.getAnnotation(CanRun.class);
          if (annos != null) {
            try {
              method.invoke(runner);
            } catch (Exception e) {
              e.printStackTrace();
            }
          }
        }
      }
    }

    参考文档:

    1. http://www.cnblogs.com/hoojo/archive/2011/05/05/2038111.html

    2. http://veerasundar.com/blog/2010/11/java-thread-local-how-to-use-and-code-sample/

    3. http://www.vogella.com/articles/JavaAnnotations/article.html

    4. http://hi.baidu.com/firnice/item/a9604f14f4d94e0ad1d66dc8

  • 相关阅读:
    2018.11.29 Struts2中拦截器的学习&项目的实际运用
    2018.11.28 OGNL表达式与struts2框架结合的体现---在配置文件中体现(补充)
    信息化战争
    指令周期
    虚拟存储器
    Advice about life
    时间的价值
    计算机病毒的结构
    网上在线考试
    ch03_1_first.jsp
  • 原文地址:https://www.cnblogs.com/matt123/p/3010918.html
Copyright © 2011-2022 走看看