OSGI动态注册和创建服务
来源:互联网 发布:c语言中的char=a[] 编辑:程序博客网 时间:2024/05/16 15:52
1、需要引入
<dependency> <groupId>org.osgi</groupId> <artifactId>org.osgi</artifactId> <version>3.0.0</version> </dependency>
2、创建一个工厂类实现接口ManagedServiceFactory
public class WserviceFactory implements ManagedServiceFactory { private static final Logger log = LoggerFactory.getLogger(WserviceFactory.class); private BundleContext context; private APIServices apiServices; private String[] interfaces; public BundleContext getContext() { return context; } public void setContext(BundleContext context) { this.context = context; } /** * 服务:key为appid */ private final Map<String, ServiceRegistration> existingServices = new HashMap<>(); /** * pid与appid的映射关系 */ private final Map<String, String> PidNameMap = new HashMap<>(); public WserviceFactory() { Class<?>[] allinterfaces = WwService.class.getInterfaces(); List<String> ifacelist = new ArrayList<>(); for (Class<?> iface : allinterfaces) { ifacelist.add(iface.getName()); } interfaces = (String[]) ifacelist.toArray(new String[ifacelist.size()]); } @Override public String getName() { return "JMust_Service"; } @Override public void updated(String pid, Dictionary dctnr) throws ConfigurationException { log.info("JMust_Service update: pid=" + pid); if (dctnr == null) { log.warn("文件:" + pid + "为空,无法创建服务"); return; } String WwServiceName; String WwSecret = null; String WwAppID = dctnr.get("AppID").toString(); // 服务名不能空 if (WwAppID == null) { log.warn(pid + "文件中AppID参数没有配置或者为空,无法创建服务!"); return; } else { WwSecret = dctnr.get("Secret").toString(); if (WxAppID.trim().isEmpty()) { log.warn(pid + "文件中AppID参数没有配置或者为空,无法创建服务!"); return; } // 服务名不能重复 if (existingServices.containsKey(WwAppID)) { if (WwAppID.equals(PidNameMap.get(pid))) { // 同一配置文件修改的情况 log.info("更新已有的服务实例\"" + WwAppID + "\""); ServiceRegistration ppcService; ppcService = existingServices.get(WwAppID); if (ppcService != null) { log.info("Unregister WwService Instance:" + WwAppID); ppcService.unregister(); } else { log.warn("No WwService Instance:" + WwAppID); } existingServices.remove(WwAppID); } else { // 不同配置文件的服务实例名冲突 log.error("服务实例名\"" + WwAppID + "\"和其他配置文件里的服务实例名冲突,保留原有服务实例。"); return; } } // 先清除当前配置文件原来对应的服务资源 String LegacyServiceName = PidNameMap.get(pid); if (LegacyServiceName != null) { ServiceRegistration ppcService = existingServices.get(LegacyServiceName); if (ppcService != null) { ppcService.unregister(); } existingServices.remove(LegacyServiceName); PidNameMap.remove(pid); } } // 设置服务相关属性 ServiceRegistration ppcService; Dictionary props = new Hashtable(); props.put("instance", WxAppID); // 设置WwService相关属性 WxService instance = new WxService(WwAppID, WwSecret); instance.setApiServices(apiServices); if (instance == null) { log.error("[" + pid + "]配置参数格式有误!创建WwService失败!"); return; } ppcService = context.registerService(interfaces, instance, props); existingServices.put(WwAppID, ppcService); PidNameMap.put(pid, WwAppID); } @Override public void deleted(String pid) { ServiceRegistration ppcService; String ServiceName = PidNameMap.get(pid); if (ServiceName != null) { ppcService = existingServices.get(ServiceName); if (ppcService != null) { ppcService.unregister(); } existingServices.remove(ServiceName); PidNameMap.remove(pid); } } public boolean isExistAppId(String appId) { if (existingServices.containsKey(appId)) { return true; } return false; } public void setApiServices(APIServices apiServices) { this.apiServices = apiServices; for (String key : existingServices.keySet()) { WwService service = (WwService) context.getService(existingServices.get(key).getReference()); if (service != null) { service.setApiServices(this.apiServices); } } }}
3、将相关属性初始化到需要用到的地方
public class WwService implements IWwService { private String AppID; private String Secret; private APIServices apiServices; public WxService(String appid, String secret) { this.AppID = appid; this.Secret = secret; } public void setApiServices(APIServices apiServices) { this.apiServices = apiServices; } public APIServices getApiServices() { return apiServices; }}
4、假如说,我们需要初始化的时候创建很多的服务,那么我们可以通过将所有的服务接口注入到一个接口服务类,看blueprint的配置,如:
<reference id="aService" interface="com.jmust.test.iface.IAAPI" availability="optional" /> <reference id="bService" interface="com.jmust.test.iface.IBAPI" availability="optional" /> <reference id="cService" interface="com.jmust.test.iface.ICAPI" availability="optional" /> <reference id="dService" interface="com.jmust.test.iface.IDAPI" availability="optional" /> <reference id="eService" interface="com.jmust.test.iface.IEAPI" availability="optional" /> <reference id="fService" interface="com.jmust.test.iface.IFAPI" availability="optional" /> <reference id="gService" interface="com.jmust.test.iface.IGAPI" availability="optional" /> <reference id="hService" interface="com.jmust.test.iface.IHAPI" availability="optional" /> <reference id="iService" interface="com.jmust.test.iface.IIAPI" availability="optional" /> <reference id="jService" interface="com.jmust.test.iface.IJAPI" availability="optional" /> <reference id="kService" interface="com.jmust.test.iface.IKAPI" availability="optional" /> <bean id="APIServicesBean" class="com.jmust.test.pwservice.Factory.APIServices"> <property name="aService" ref="aService" /> <property name="bService" ref="bService" /> <property name="cService" ref="cService" /> <property name="dService" ref="dService" /> <property name="eService" ref="eService" /> <property name="fService" ref="fService" /> <property name="gService" ref="gService" /> <property name="hService" ref="hService" /> <property name="iService" ref="iService" /> <property name="jService" ref="jService" /> <property name="kService" ref="kService" /> </bean>
5、将上面这些接口通过一个服务发布出去,这样子就相当于一次性发布了所有需要不发布的服务了
<!--服务配置后自动发布 --> <bean id="WServiceFactory" class="com.jmust.test.pwservice.Factory.WserviceFactory"> <property name="context" ref="blueprintBundleContext" /> <property name="apiServices" ref="APIServicesBean" /> </bean> <service id="WServiceFactoryService" ref="WServiceFactory" interface="org.osgi.service.cm.ManagedServiceFactory"> <service-properties> <entry key="service.pid" value="JMust_Service" /> </service-properties> </service>
6、到此,将服务发布出去后,每当我们增加一个新的cfg文件,就会创建一份新的服务,从而达到了横向扩展了。
创建一个JMust_Service_0001.cfg文件,里面的内容是:
AppID=123456789
Secret=abcdefg
保存后,把他扔到servicemix的etc里面既可马上创建对应于这个cfg中的APPID为123456789的服务了;
假如说,我再创建一封新的cfg文件,就上面的APPID不一样外,保存,发布到etc下面,那么也会出马上创建一份服务
7、服务创建好之后,我们就需要应用这些服务了,那么该怎么办呢?
创建个实现类:
blueprint中监听服务public class ServiceRegister{ private BundleContext bundleContext; private static final Logger LOG = LoggerFactory.getLogger(ServiceRegister.class); public static final ConcurrentHashMap<String, IWwService> serviceMap = new ConcurrentHashMap<>(); public synchronized void register(ServiceReference<IWwService> reference) throws Exception { String appId = (String) reference.getProperty("instance"); IWwService service = bundleContext.getService(reference); serviceMap.put(appId, service); LOG.info("服务注册...." + reference.getBundle().getSymbolicName() + " AppID = " + appId); } public synchronized void unRegister(ServiceReference<IWwService> reference) throws Exception { if (reference == null || reference.getProperty("instance") == null) { return; } String appId = (String) reference.getProperty("instance"); if (serviceMap.containsKey(appId)) { serviceMap.remove(appId); } LOG.info("服务卸载...." + reference.getBundle().getSymbolicName() + " AppID = " + appId); } public void setBundleContext(BundleContext bundleContext) { this.bundleContext = bundleContext; }}
<!--获取服务列表--> <bean id="serviceRegister" class="com.jmust.test.service.ServiceRegister"> <property name="bundleContext" ref="blueprintBundleContext" /> </bean> <reference-list availability="optional" interface="com.jmust.dest.pwservice.Iface.IWwService"> <reference-listener ref="serviceRegister" bind-method="register" unbind-method="unRegister" /> </reference-list>
0 0
- OSGI动态注册和创建服务
- OSGI--动态创建服务
- OSGI系列 服务注册
- osgi注册服务和servlet的两种方法
- OSGi 起步(4): 注册服务
- OSGI服务注册、引用、以及跟踪
- [转] 简单osgi实践---ds注册服务
- OSGi 探秘系列 (5)- OSGi之动态服务
- OSGI传统注册式服务与声明式服务
- OSGi起步(6):动态追踪服务
- OSGi、Spring、Hibernate集成:动态注册实体类
- OSGi服务
- OSGI:服务的发布和引用
- OSGi服务发布和获取方式
- Oracle的监听服务配置listener.ora的动态注册和静态注册
- 创建服务工程、注册卸载服务
- 创建动态代理服务
- 创建动态代理服务
- Cassandra系列之入门
- iOS UIActionSheet提示框
- ugui 中有关grid layout group的适配问题
- 编程问题之:花式赋值看输出
- ELK(一)ElasticSearch集群环境安装
- OSGI动态注册和创建服务
- 软件著作权申请中源代码文档的编辑方法
- 机房收费系统总结
- iOS开发基于xcode7.2的应用程序需国际化本地化处理
- C#目录内文件批量查找替换字符串内容
- GDKOI2016 Day2 T4 小学生数学题
- 分糖果
- JPA中查询任意表的任意字段转实体类Dto的Util方法
- [POJ3436]ACM Computer Factory 做题笔记