在上一篇文章OpenNMS全接觸-系統啓動(四)中,提到
從%opennms_home%/etc目錄下的service-configuration.xml中的所有service,將所有配置的service生成其實例對象 |
這句話其實在代碼中隱藏了很多比較玄奧的工作,下面將介紹這些對象究竟被怎樣創建,它又引發了哪些操作。
我們以一個例子來看一下吧,在service-configuration.xml文件中,我們可以看到name爲OpenNMS:Name=Collectd的service,其class-name定義爲org.opennms.netmgt.collectd.jmx.Collectd,通過前面的介紹,我們知道系統在啓動後會生成該類的一個實例。但等我們打開該類的定義後卻發現,其實該類並沒有什麼內容:
- package org.opennms.netmgt.collectd.jmx;
- import org.opennms.netmgt.daemon.AbstractSpringContextJmxServiceDaemon;
- public class Collectd extends AbstractSpringContextJmxServiceDaemon implements
- CollectdMBean {
- @Override
- protected String getLoggingPrefix() {
- return "OpenNMS.Collectd";
- }
- @Override
- protected String getSpringContext() {
- return "collectdContext";
- }
- }
我們已經知道Collectd負責定期收集網絡設備性能數據,可從這裏我們看不到任何它做的工作。
所以只能沿着基類網上找,讓我們看下AbstractSpringContextJmxServiceDaemon的內容吧,在這裏我們
可以找到所有的答案。
我曾經一直疑惑於OpenNMS-service中命名定義了好多*-context.xml文件,卻始終沒有看到在哪裏加載這些
context的定義文件,但事實又告訴我它們肯定被加載了,因爲我已經在代碼中使用過這些context中定義的
bean了,程序員的最大痛苦莫過於知道用一個東西,卻又不知道它怎麼來的了。後來終於在這個地方找到了答案。
因爲在AbstractSpringContextJmxServiceDaemon中我終於看到了熟悉的代碼:
- protected ApplicationContext getContext() {
- return m_context;
- }
是的,有了context,對spring來說,就有了一切。
在onInit中我們終於看到它對該context的初始化了
- m_context = BeanUtils.getFactory(getSpringContext(), ClassPathXmlApplicationContext.class);
嗯,從上面的Collectd中我們已經看到了對於getSpringContext()的覆寫,是的,通過該名字,終於在opennms-service中找到了該bean,它對應的context文件在applicationContext-collectd.xml文件中。而
- public T getDaemon() {
- return (T) m_context.getBean(DAEMON_BEAN_NAME, SpringServiceDaemon.class);
- }
終於通過bean的名稱(daemon)來加載真正幹活的傢伙了,因爲我們從applicationContext-collectd.xml文件中已經看到了那個默默無聞卻承受所有工作的人,
- <bean id="daemon" class="org.opennms.netmgt.collectd.Collectd">
在start函數中正是通過獲取這個名爲"daemon"的bean來調用其start()方法來讓其run起來的。而它的init()方法則是因爲基類AbstractServiceDaemon繼承了InitializingBean接口,在實現該接口的afterPropertiesSet()方法時,調用了init()方法,從而保證了在該bean的屬性初始化後調用init()方法。