FloodLight模块加载过程
模块加载部分:
core/module/FloodlightModuleLoader.java => (396 – 403)
loadModulesFromList函数
<br />
for (IFloodlightModule module : moduleSet) {<br />
// init the module<br />
if (logger.isDebugEnabled()) {<br />
logger.debug("Initializing " + module.getClass().getCanonicalName());<br />
}<br />
module.init(floodlightModuleContext);<br />
}<br />
循环加载启动列表中的模块。其中module.init(floodlightModuleContext);执行
core/module/IFloodlightModule.java => (77 – 88)
Interface,转换到模块override的init函数。
<br />
void init(FloodlightModuleContext context) throws FloodlightModuleException;</p>
<p>/**<br />
* This is a hook for each module to do its <em>external</em> initializations,<br />
* e.g., register for callbacks or query for state in other modules<br />
*<br />
* It is expected that this function will not block and that modules that want<br />
* non-event driven CPU will spawn their own threads.<br />
*<br />
* @param context<br />
* @throws FloodlightModuleException<br />
*/<br />
随后执行初始化完成的组件中的startUp函数。对于如下的事件绑定代码
<br />
floodlightProvider.addOFMessageListener(OFType.PACKET_IN, this);<br />
core/internal/Controller.java ==> (1451 – 1460)
<br />
//line 149 声明messageListeners实例<br />
protected ConcurrentMap<oftype,
ListenerDispatcher<oftype,IOFMessageListener>><br />
messageListeners;<br />
//line 1446<br />
// ***************<br />
// IFloodlightProvider<br />
// ***************</p>
<p>@Override<br />
public synchronized void addOFMessageListener(OFType type,<br />
IOFMessageListener listener) {<br />
ListenerDispatcher<oftype, IOFMessageListener> ldd =<br />
messageListeners.get(type); //从messageListeners中获取tpye事件的监听列表<br />
if (ldd == null) { //先检测对应事件列表ldd是否为空<br />
ldd = new ListenerDispatcher<oftype, IOFMessageListener>();<br />
messageListeners.put(type, ldd);<br />
}<br />
ldd.addListener(type, listener);<br />
}<br />
其中,ldd是事件注册列表(具体属性:listeners ArrayList
<br />
elementData Object[10] (id=189)<br />
[0] LinkDiscoveryManager (id=193)<br />
[1] TopologyManager (id=200)<br />
[2] DeviceManagerImpl (id=207)<br />
[3] Firewall (id=213)<br />
[4] LoadBalancer (id=66)<br />
[5] Forwarding (id=218)<br />
[6] null<br />
...<br />
事件加入函数
core/util/ListenerDispatcher.java ==> (71 – 107)
<br />
//line 38<br />
List<t> listeners = null;</p>
<p>//line 71<br />
public void addListener(U type, T listener) {<br />
List<t> newlisteners = new ArrayList<t>();<br />
if (listeners != null) //listeners列表是否为空(当前监听者列表)<br />
newlisteners.addAll(listeners);//将原列表中信息复制进来</p>
<p> newlisteners.add(listener);<br />
// Find nodes without outgoing edges<br />
List<t> terminals = new ArrayList<t>();<br />
for (T i : newlisteners) {<br />
boolean isterm = true;<br />
for (T j : newlisteners) {<br />
if (ispre(type, i, j)) {<br />
isterm = false;<br />
break;<br />
}<br />
}<br />
if (isterm) {<br />
terminals.add(i);<br />
}<br />
}</p>
<p> if (terminals.size() == 0) {<br />
logger.error("No listener dependency solution: " +<br />
"No listeners without incoming dependencies");<br />
listeners = newlisteners;<br />
return;<br />
}</p>
<p> // visit depth-first traversing in the opposite order from<br />
// the dependencies. Note we will not generally detect cycles<br />
HashSet<t> visited = new HashSet<t>();<br />
List<t> ordering = new ArrayList<t>();<br />
for (T term : terminals) {<br />
visit(newlisteners, type, visited, ordering, term);<br />
}<br />
listeners = ordering;<br />
}<br />