blueprint 是 OSGi 的一個規範,相似於 spring 的 IOC,用來處理 OSGi 的動態特性,能夠大大簡化服務的使用。html
blueprint 是以 xml 文檔來構建應用,但它也有采用 Annotation 的方式,咱們在此只介紹 xml 的方式。java
在 bundle 裏,這個 xml 默認的位置在 OSGi-INF/blueprint 下,也能夠在 MANIFEST.MF 裏指定其它位置上的 xml 文檔。git
Bundle-Blueprint: OSGI-INF/blueprint/blueprint.xml
<?xml version="1.0" encoding="UTF-8"?> <blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0 https://osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd"> <!--1. 默認構造函數--> <bean id="obj" class="java.lang.Object" init-method="init" destroy-method="destroy"> <property name="name" value="MP4" /> <property name="type" ref="type1" /> </bean> <!--2. 構造函數--> <bean id="obj" class="java.lang.Object" init-method="init" destroy-method="destroy"> <argument value="..."/> <argument value="..."/> </bean> <!--3. 工廠方法--> <bean id="obj2" factory-ref="factory" factory-method="method"/> </blueprint>
blueprint 的使用方法與 spring 差很少。github
Blueprint Container 規範還定義了許多特殊的環境管理器,它們設置 ID 並提供對環境組件的訪問。它們不具備 XML 定義,而且也不能被重寫,由於它們的 ID 被保護起來,不能被其餘管理器使用。環境管理器提供的對象只能被注入到使用引用的其餘管理器中。Blueprint Container 規範定義了 4 種環境管理器:spring
blueprintBundle
提供包的 Bundle(org.osgi.framework.Bundle) 對象。blueprintBundleContext
提供包的 BundleContext(org.osgi.framework.BundleContext) 對象。blueprintContainer
爲包提供 BlueprintContainer(org.osgi.service.blueprint.container.BlueprintContainer) 對象。blueprintConverter
爲包提供 Converter(org.osgi.service.blueprint.container.Converter) 對象,提供了對 Blueprint Container 類型轉換工具的訪問<bean id="" class="" init-method=""> <property name="bundle" ref="blueprintBundle" /> <property name="bundleContext" ref="blueprintBundleContext" /> </bean>
<bean class="com.edu.osgi.blueprint.Order" init-method="init"> <property name="id" value="20160320" /> <property name="products"> <!--1. 集合、數組的注入--> <list> <ref component-id="mp4"/> <ref component-id="dianshi"/> </list> </property> <property name="map"> <!--2. map的注入--> <map> <entry key="createDate" value="20160320" /> <entry key="userId" value="101" /> </map> </property> </bean>
(1) 新建 3 個 bundle,目錄結構以下:apache
(2) blueprint-api 爲接口api
package com.github.binarylei.email.api; public interface EmailService { void sendEmail(String to, String title, String content); }
(3) blueprint-service 發佈服務數組
package com.github.binarylei.email.service; import com.github.binarylei.email.api.EmailService; public class EmailServiceImpl implements EmailService { public void sendEmail(String dest, String title, String content) { System.out.println("OSGi email send. dest=" + dest + ",title=" + title + ",content=" + content); } }
在 OSGI-INF/blueprint 新建 blueprint.xml 文件,發佈服務:函數
<?xml version="1.0" encoding="UTF-8"?> <blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0 https://osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd"> <bean id="emailServiceImpl" class="com.github.binarylei.email.service.EmailServiceImpl"/> <service interface="com.github.binarylei.email.api.EmailService" ref="emailServiceImpl"> <service-properties> <entry key="vendor" value="163"/> </service-properties> </service> </blueprint>
(3) blueprint-client 處理服務工具
package com.github.binarylei.email.client; import com.github.binarylei.email.api.EmailService; public class EmailClient { private EmailService emailService; public EmailService getEmailService() { return emailService; } public void setEmailService(EmailService emailService) { this.emailService = emailService; } public void init() { emailService.sendEmail("binarylei@qq.com", "blueprint", "成功了"); } }
在 OSGI-INF/blueprint 新建 blueprint.xml 文件,接收服務:
<?xml version="1.0" encoding="UTF-8"?> <blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0 https://osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd"> <!--服務的引用--> <reference id="emailService" interface="com.github.binarylei.email.api.EmailService" filter="(vendor=163)"/> <bean id="client" class="com.github.binarylei.email.client.EmailClient" init-method="init"> <property name="emailService" ref="emailService"/> </bean> </blueprint>
(4) 測試結果以下:
(1) 在 blueprint-client 中編寫一個監聽類 EmailServiceListener
package com.github.binarylei.email.client; import com.github.binarylei.email.api.EmailService; import org.osgi.framework.ServiceReference; import java.util.Map; public class EmailServiceListener { // member-type="service-object" public void register(EmailService emailService, Map<?, ?> properties) { System.out.println("======register====="); System.out.println(properties); emailService.sendEmail("binarylei@qq.com", "blueprint", "成功了"); } /*public void register(EmailService emailService) { }*/ // member-type="service-reference" /*public void register(ServiceReference reference) { }*/ public void unregister(EmailService emailService, Map<?, ?> properties) { System.out.println("======unregister====="); System.out.println(properties); emailService.sendEmail("binarylei@qq.com", "blueprint", "成功了"); } }
(2) blueprint.xml 配製文件
<!--服務的跟蹤--> <reference-list interface="com.github.binarylei.email.api.EmailService" member-type="service-object"> <reference-listener ref="emailServiceListener" bind-method="register" unbind-method="unregister"/> </reference-list> <bean id="emailServiceListener" class="com.github.binarylei.email.client.EmailServiceListener"/>
(3) 測試結果以下: