jmeter系列四(Visualizer)

今天开始jmeter的核心元素Visualizer

在jmeter中每个testelement元素都对应着他的gui,Visualizer也不例外,可以定位到包org.apache.jmeter.visualizers和org.apache.jmeter.visualizers.gui

包下面的类全部都是有关于visualizers这个元素,Visualizer比较特殊还会涉及到org.apache.jmeter.reporters包下面的类,可以看到visualizers包下面Visualizer接口

 1 public interface Visualizer {
 2     /**
 3      * This method is called by sampling thread to inform the visualizer about
 4      * the arrival of a new sample.
 5      */
 6     void add(SampleResult sample);
 7 
 8     /**
 9      * This method is used to indicate a visualizer generates statistics.
10      *
11      * @return true if visualiser generates statistics
12      */
13     boolean isStats();
14 } 

接口很简单,但是visualizer扮演的角色却很重要,看来要去engine仔细查看一番,不过可以先看下这两个方法都是怎样被调用了

利用neatbeans的方法导航功能,方法add(SampleResult sample)经过了类ResultCollector、ListenerNotifier和JMeterThread看来最后还是engine

而isStats()则会经过ResultCollector的调用

接口过于简单,我们还是看看它的实现类对我们去engine分析他的流程还是有帮助的,利用neatbeans的转到实现功能,我们可以定位到它的抽象实现类

AbstractVisualizer,咦怎么了,它继承了AbstractListenerGui,原来Visualizer这个接口是针对gui设置的,lz原来以为是testelement,其实不然,那testelement

的接口在哪儿或者继承了AbstractTestElement的类在哪儿?在这org.apache.jmeter.reporters包下的AbstractListenerElement

看来Visualizer比较复杂我们慢慢来看吧,但愿一切顺利

---------------------------------------------------------------忧伤的分割线,休息一下------------------------------------------------------------------------------------

看一下AbstractVisualizer,它实现了这么几个接口Visualizer,ChangeListener,UnsharedComponent,Clearable

Visualizer上面讲了

ChangeListener干嘛的呢?swing下面的接口,当我们注册的事件监听器改变状态时被调用

UnsharedComponent干嘛的呢?导航一下 发现如下public interface UnsharedComponent {}

这看起来很显然是一个标记接口,看了下注释,说如果没有实现这个接口的Component,会被testelement共享使用,不是很理解具体含义,而后分析代码可以好好看看

Clearable接口干嘛的呢?

public interface Clearable {
/**
* Clears the current data of the object.
*/
void clearData();
// N.B. originally called clear()
// @see also JMeterGUIComponent
}

很明显了,实现了该接口的组件可以被调用clearData清除上面的信息,额还是不是很理解具体含义,而后分析代码可以好好看看~。~

可以看下AbstractVisualizer实现的一些基本方法了,通过查看createTestElement,modifyTestElement,configure可以得知

Visualizer的testelement就是你了ResultCollector.

-----------------------------------------------------------------Visualizer的gui告一段落,下面是Visualizer的testelement-----------------------------------------

 1 public abstract class AbstractListenerElement extends AbstractTestElement {
 2     private static final long serialVersionUID = 240L;
 3 
 4     // TODO should class implement SampleListener?
 5     private transient WeakReference<Visualizer> listener;
 6 
 7     public AbstractListenerElement() {
 8     }
 9 
10     protected final Visualizer getVisualizer() {
11         if (listener == null){ // e.g. in non-GUI mode
12             return null;
13         }
14         return listener.get();
15     }
16 
17     public void setListener(Visualizer vis) {
18         listener = new WeakReference<Visualizer>(vis);
19     }
20 
21     @Override
22     public Object clone() {
23         AbstractListenerElement clone = (AbstractListenerElement) super.clone();
24 
25         clone.listener=this.listener;
26         return clone;
27     }
28 }

会有一个Visualizer组件于之关联,现在看下ResultCollector的定义

public class ResultCollector extends AbstractListenerElement implements SampleListener, Clearable, Serializable,
TestStateListener, Remoteable, NoThreadClone

它实现了这么多的接口我们可以一个一个的来看

SampleListener接口 notification on events occuring during the sampling process

Clearable接口 同上

Serializable接口 可序列化

TestStateListener接口 测试开始的过程中实现了这个接口的类可以被回调

Remoteable接口 以后分析

NoThreadClone接口 标记接口,标记了这个接口的testelement,在多个test run之间不会被clone

---------------------------------------------------------现在是Visualizer在engine中的执行情况------------------------------------------------------------------------

 定位到JMeterThread类的run方法中 通过观察在process_sampler方法中notifyListeners,看下notifyListeners的内容

1 private void notifyListeners(List<SampleListener> listeners, SampleResult result) {
2         SampleEvent event = new SampleEvent(result, threadGroup.getName(), threadVars);
3         notifier.notifyListeners(event, listeners);
4 
5     }

有两点注意

1.SampleListener的List,我们的ResultCollector就实现了SampleListener接口,上面分析了

2.notifier这个变量,通过观察他是ListenerNotifier,JMeterThread类的属性,可以看下ListenerNotifier源码

可以看出就是简单的调用SampleListener(当然不是这么简单)

process_sampler方法中的代码

 1 List<SampleListener> sampleListeners = getSampleListeners(pack, transactionPack, transactionSampler); 2 notifyListeners(sampleListeners, result); 

 ListenerNotifier类中的notifyListeners方法

 1 @SuppressWarnings("deprecation") // TestBeanHelper.prepare() is OK
 2     public void notifyListeners(SampleEvent res, List<SampleListener> listeners) {
 3         for (SampleListener sampleListener : listeners) {
 4             try {
 5                 TestBeanHelper.prepare((TestElement) sampleListener);
 6                 sampleListener.sampleOccurred(res);
 7             } catch (RuntimeException e) {
 8                 log.error("Detected problem in Listener: ", e);
 9                 log.info("Continuing to process further listeners");
10             }
11         }
12     }

通过看到这行代码sampleListener.sampleOccurred(res)可以看出对于ResultCollector这个是实现了sampleListener接口的类来说sampleOccurred这个方法是关键。

ResultCollector会单独开一篇未完待续

posted @ 2015-02-07 21:28  tom是cat  阅读(1793)  评论(0编辑  收藏  举报