SPRing 框架將體系結(jié)構(gòu)依靠性降至最低,并且將應(yīng)用程序中得組成部分進(jìn)行了具體化,但是應(yīng)用程序仍然是需要治理的。幸運(yùn)的是,Spring 1.2 包括高級(jí)的 JMX 集成支持,并且 JMX 為應(yīng)用程序提供了一種實(shí)用的治理基礎(chǔ)架構(gòu)。在本文中,Claude Duguay 從 Spring JMX 更進(jìn)一步,向您展示了如何為方法和屬性透明地增加通知事件。最后得到的代碼使您可以監(jiān)視狀態(tài)變化,同時(shí)不會(huì)搞亂 java? 對(duì)象。
雖然 Spring 框架的 JMX 治理基礎(chǔ)架構(gòu)的默認(rèn)配置已經(jīng)很不錯(cuò)了,但是仍然有定制的余地,非凡是涉及 Model MBean 提供的更高層功能時(shí)。在本文中,我使用了一種相對(duì)簡(jiǎn)單的操作 —— 為基于 Spring 的應(yīng)用程序的方法和屬性增加通知事件 —— 以幫助您熟悉對(duì) Spring JMX 的定制。從頭到尾完成我的例子后,您將可以根據(jù)自己應(yīng)用程序的需要調(diào)整 Spring JMX 治理基礎(chǔ)架構(gòu)。
我首先對(duì) JMX API、Spring 框架和 Spring JMX 進(jìn)行簡(jiǎn)單回顧,然后轉(zhuǎn)入開(kāi)發(fā)擴(kuò)展。第一個(gè)擴(kuò)展讓我可以用一個(gè)外部 xml 格式配置 MBean 元數(shù)據(jù),這個(gè)格式(像 Hibernate 映射文件)可以與 Java 對(duì)象一起存儲(chǔ)在類(lèi)路徑中。我的第二個(gè)擴(kuò)展為 ModelMBean 類(lèi)增加一個(gè)簡(jiǎn)單的命名規(guī)范,以透明地配置定制的通知消息。在屬性改變時(shí)或者調(diào)用了特定的方法之前或者之后觸發(fā)新的通知消息。
Standard MBean 直接實(shí)現(xiàn)用于治理對(duì)象的方法,既可以通過(guò)實(shí)現(xiàn)一個(gè)由程序員定義的、類(lèi)名以 “MBean” 結(jié)束的接口,也可以使用一個(gè)以一個(gè)類(lèi)作為構(gòu)造函數(shù)參數(shù)的 Standard MBean 實(shí)例,加上一個(gè)可選的接口類(lèi)規(guī)范。這個(gè)接口可以開(kāi)放用于治理的部分對(duì)象方法。
Model MBean 提供了一個(gè)改進(jìn)的抽象層,并擴(kuò)展了 Dynamic MBean 模型以進(jìn)一步減少對(duì)給定實(shí)現(xiàn)的依靠性。這對(duì)于可能使用多個(gè)版本的 JVM 或者需要用松散耦合治理第三方類(lèi)的情況會(huì)有幫助。Dynamic MBean 與 Model MBean 之間的主要區(qū)別是,在 Model MBean 中有額外的元數(shù)據(jù)。
Open MBean 是受限的 Model MBean,它限制類(lèi)型為固定的一組類(lèi)型,以得到最大的可移植性。通過(guò)限制數(shù)據(jù)類(lèi)型,可以使用更多的適配器,并且像 SMTP 這樣的技術(shù)可以更輕易適應(yīng) Java 應(yīng)用程序的治理。這種變體還指定了數(shù)組和表等標(biāo)準(zhǔn)結(jié)構(gòu)以改進(jìn)復(fù)合對(duì)象的治理。
假如要同時(shí)控制客戶(hù)機(jī)和服務(wù)器,那么 Standard MBean 是最輕易實(shí)現(xiàn)的一種變體。它們的優(yōu)點(diǎn)是有類(lèi)型,但是假如在更一般化的治理控制臺(tái)環(huán)境中使用時(shí)會(huì)缺少一些靈活性。假如計(jì)劃使用 Dynamic MBean,那么您也可以更一步使用 Model MBean,在大多數(shù)情況下它會(huì)改善抽象層而幾乎不會(huì)增加復(fù)雜性。Open MBean 是是可移植性最高的一種變體,假如需要開(kāi)放復(fù)合對(duì)象,那么它是惟一的方法。不幸的是,在 Open MBean 中開(kāi)放復(fù)合結(jié)構(gòu)所需要的代碼數(shù)量過(guò)多,只有在需要高級(jí)的商業(yè)治理解決方案時(shí)才合算。
JMX 還支持使用帶過(guò)濾器和廣播器的事件模型的通知。為此目的,Standard MBean 需要聲明一個(gè) MBeanInfo 元數(shù)據(jù)描述。 Standard MBean 實(shí)現(xiàn)通常在內(nèi)部構(gòu)造這些內(nèi)容,開(kāi)發(fā)人員不能直接看到它們。在本文后面,您會(huì)看到如何用 Model MBean 元數(shù)據(jù)的 XML 描述符格式和 Spring 的 JMX 支持進(jìn)行實(shí)際上透明的配置。
Spring 的支持 AOP 的、以復(fù)合為中心的(IOC)bean 可以很大程度上使基礎(chǔ)架構(gòu)和業(yè)務(wù)對(duì)象彼此分離。因此,橫切關(guān)注點(diǎn)(如日志、事務(wù)和安全)不會(huì)再干擾應(yīng)用程序代碼。
IOC(控制反轉(zhuǎn))是減少耦合度的主要策略。Spring 的 IOC 實(shí)現(xiàn)使用依靠性注入有效地將控制從應(yīng)用程序代碼 “反轉(zhuǎn)”到 Spring 容器。Spring 不是在創(chuàng)建時(shí)將類(lèi)耦合到應(yīng)用程序的對(duì)象圖,它使您可以用 XML 或者屬性文件(盡管 XML 被認(rèn)為是最好的方法)配置類(lèi)及它們的依靠性。然后用標(biāo)準(zhǔn)訪問(wèn)器將引用“注入”到類(lèi)所依靠的對(duì)象中。可以將它看成具體化復(fù)合(externalizing composition),在典型應(yīng)用程序中,它的比重遠(yuǎn)遠(yuǎn)大于繼續(xù)。
AOP 是在應(yīng)用程序開(kāi)發(fā)中治理橫切關(guān)注點(diǎn)的要害。就像在傳統(tǒng)面向?qū)ο缶幊讨袑?shí)現(xiàn)的那樣,這些關(guān)注點(diǎn)是作為單獨(dú)的實(shí)例處理的,有可能在應(yīng)用程序類(lèi)中產(chǎn)生互不相關(guān)的代碼(就是混亂)。 Spring 使用 AOP 規(guī)范和一個(gè) XML 配置文件具體化橫切關(guān)注點(diǎn),因而保持了 Java 代碼的純潔性。
Spring 1.2 提供的大量裝配器使得透明地構(gòu)造 MBean 成為可能,包括使用內(nèi)省、Standard MBean 接口、元數(shù)據(jù)(使用類(lèi)級(jí)別注釋?zhuān)┖惋@式聲明的方法名。Spring 的基于導(dǎo)出器和裝配器的模型輕易擴(kuò)展,并在創(chuàng)建注冊(cè)的 MBean 時(shí)提供所需要的控制能力。
JMX 使用 ObjectName 語(yǔ)言注冊(cè)和訪問(wèn)治理對(duì)象。假如選擇使用自動(dòng)注冊(cè),那么 Spring 提供了不同的命名策略。使用“鍵”命名策略時(shí),可以使用一個(gè)屬性把 MBean 名與 NameObject 實(shí)例關(guān)聯(lián)起來(lái)。假如實(shí)現(xiàn) ManagedResource 接口,那么可以使用元數(shù)據(jù)命名規(guī)范。由于 Spring 高度靈活的體系結(jié)構(gòu)和大量擴(kuò)展點(diǎn),還可以實(shí)現(xiàn)自已的策略。
在默認(rèn)情況下,Spring 會(huì)發(fā)現(xiàn)運(yùn)行的 MBeanServer 實(shí)例,假如沒(méi)有實(shí)例在運(yùn)行或者沒(méi)有顯式聲明的話(huà),它會(huì)創(chuàng)建一個(gè)默認(rèn)實(shí)例。用 Spring 配置直接實(shí)例化自己的 MBeanServer 與使用各種連接器同樣輕易。Spring 通過(guò)客戶(hù)機(jī)和服務(wù)器連接提供控制,并提供客戶(hù)機(jī)代理以協(xié)助客戶(hù)端編程。
所有這些功能都是 Spring 1.2 默認(rèn)提供的。雖然 Spring JMX 提供了大量選項(xiàng),但是默認(rèn)的導(dǎo)出器對(duì)于許多項(xiàng)目來(lái)說(shuō)已經(jīng)足夠了,使您可以很快地投入運(yùn)行。不過(guò),使用 JMX 時(shí),在使用隱式 MBean 構(gòu)造時(shí)會(huì)注重到一些特性。結(jié)果,可能會(huì)慢慢地從 Standard MBean 轉(zhuǎn)移到 Model MBean,它答應(yīng)對(duì)應(yīng)用程序的屬性、操作和通知元數(shù)據(jù)施加更多的控制。要保留松散耦合的好處(也就是 Spring 靈活的體系結(jié)構(gòu)內(nèi)在的優(yōu)點(diǎn)),需要在 Java 對(duì)象之外實(shí)現(xiàn)這個(gè)控制。
Spring 的 IOC 使得從外部連接(wire)對(duì)象依靠性輕易了,在 Spring 的體系結(jié)構(gòu)中很輕易利用這種優(yōu)點(diǎn)。IOC 保持對(duì)象依靠性的可注入性,這使得增加、替換或者補(bǔ)充對(duì)象的行為(包括 Spring 的 JMX 支持)變得輕而易舉。在本文的其余部分,我將重點(diǎn)放到擴(kuò)展 Spring JMX 以得到更細(xì)化的應(yīng)用程序治理,而不會(huì)搞亂應(yīng)用程序代碼或者破壞 Spring 固有的靈活性。