上回说到,测试环境的搭建,这回说点儿正经事:bnudle之间的bean相互调用。
总结一个字,贼简单。
用广东话说就是:贼拉拉的简单。
<bean id="fileProbe" class="com.monitor.bundle.probe.file.FileProbeImpl"> <property name="folder" value="r:/testdata/" /> <property name="ext" value="txt" /> <property name="messageSender"> <osgi:reference interface="com.monitor.bundle.interfaces.MessageSenderIF" /> </property> </bean> <osgi:service id="fileProbeService" interface="com.monitor.bundle.interfaces.ProbeIF" ref="fileProbe" />
fileProbe这个bean定义了一个bean,与标准spring不同的是,定义了messageSender,里面用了osgi:reference,表示你要引用别人了,interface属性定义了你要引用的接口,至于到底引用的是哪个实现呢?答案是:爱谁谁,谁在容器中定义的服务实现了这个接口,就是说,如果有多个,就看谁的rank大,具体的机制自己看spring dm的文档吧。另外,也可以定义destroy-method="stop" init-method="start",以便spring-osgi-extender能在加载这个bean的时候自动引用start()方法和卸载bean的时候引用stop(),比如,我们的mq这个bundle就是这么配置的
<bean id="listener" class="com.monitor.bundle.amq.Listener" destroy-method="stop" init-method="start"> <property name="mqUrl" value="tcp://localhost:61616" /> <property name="userName" value="system" /> <property name="password" value="manager" /> <property name="qName" value="steveq" /> <property name="persisHandler"> <osgi:reference interface="com.monitor.bundle.interfaces.PersistanceIF" /> </property> <property name="stradgy"> <osgi:reference interface="com.monitor.bundle.interfaces.StradgyIF" /> </property> </bean>
代码如下:
package com.zeromonitor.bundle.amq; import javax.jms.Connection; import javax.jms.DeliveryMode; import javax.jms.ExceptionListener; import javax.jms.JMSException; import javax.jms.Message; import javax.jms.MessageConsumer; import javax.jms.MessageListener; import javax.jms.MessageProducer; import javax.jms.ObjectMessage; import javax.jms.Queue; import javax.jms.Session; import javax.jms.TextMessage; import org.apache.activemq.ActiveMQConnectionFactory; import org.eclipse.core.runtime.adaptor.EclipseStarter; import org.osgi.framework.Bundle; import org.osgi.framework.BundleContext; import org.osgi.framework.BundleException; import com.monitor.bundle.beans.ZmBean; import com.monitor.bundle.interfaces.PersistanceIF; import com.monitor.bundle.interfaces.StradgyIF; /** * User: steve * Date: 2009-7-21 12:02:35 */ public class Listener implements MessageListener, ExceptionListener { String mqUrl = ""; String userName = ""; String password = ""; String qName = ""; PersistanceIF persisHandler = null; StradgyIF stradgy = null; Connection connection = null; BundleContext equinoxContext = null; public void onException(JMSException e) { System.out.println("JMS Exception occured. Shutting down client."); } public void stop() { try { this.connection.stop(); } catch (JMSException e) { e.printStackTrace(); } } public void start() { try { //ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory("system", "manager", "tcp://localhost:61616"); ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory(this.userName, this.password, this.mqUrl); this.connection = connectionFactory.createConnection(); connection.setExceptionListener(this); connection.start(); Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); Queue destination = session.createQueue(this.qName); MessageProducer replyProducer = session.createProducer(null); replyProducer.setDeliveryMode(DeliveryMode.NON_PERSISTENT); MessageConsumer consumer = session.createConsumer(destination); consumer.setMessageListener(this); this.equinoxContext = EclipseStarter.getSystemBundleContext(); } catch (Exception e) { //System.out.println("Caught: " + e); // do nothing } } public void onMessage(Message message) { try { if (message instanceof TextMessage) { //表示操作Bundle,!暂时方案! TextMessage txtMsg = (TextMessage) message; String msg = txtMsg.getText(); if(msg.startsWith("i")) { // 安装 this.equinoxContext.installBundle("file:" + msg.substring(1)); } if(msg.startsWith("list")) { for(int i=0;i<this.equinoxContext.getBundles().length;i++) { System.out.println(this.equinoxContext.getBundles()[i].getSymbolicName()); } } else { //更新 for(int i=0;i<this.equinoxContext.getBundles().length;i++) { Bundle tmp = this.equinoxContext.getBundles()[i]; String bundleName = msg.substring(1); if(bundleName.equalsIgnoreCase(tmp.getSymbolicName())) { if(msg.startsWith("s")) { tmp.start(); } else if(msg.startsWith("t")) { tmp.stop(); } else if(msg.startsWith("d")) { tmp.update(); } else if(msg.startsWith("u")) { tmp.uninstall(); } } } } } else { //表示是一个ZMBean ZmBean zmBean = (ZmBean)((ObjectMessage) message).getObject(); this.persisHandler.persist(this.stradgy.doStradgy(zmBean)); } /* if (message.getJMSReplyTo() != null) { replyProducer.send(message.getJMSReplyTo(), session.createTextMessage("Reply: " + message.getJMSMessageID())); } */ } catch (JMSException e) { System.out.println("Caught: " + e); e.printStackTrace(); } catch (BundleException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public String getMqUrl() { return mqUrl; } public void setMqUrl(String mqUrl) { this.mqUrl = mqUrl; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getqName() { return qName; } public void setqName(String qName) { this.qName = qName; } public PersistanceIF getPersisHandler() { return persisHandler; } public void setPersisHandler(PersistanceIF persisHandler) { this.persisHandler = persisHandler; } public StradgyIF getStradgy() { return stradgy; } public void setStradgy(StradgyIF stradgy) { this.stradgy = stradgy; } }
其中:
1、start()里面开启监听;
2、stop()里面停止;
3、至于onmessage方法,是听到以后怎么办(以后的章节会讲用api怎么操作equinox)
在这个bean的定义下面,是定义了一个osgi:service,表示这个bundle提供什么样的服务,就是说,“我能干什么,或者说,我实现了什么接口”,定义好了以后,别人就可以用osgi:reference引用自己了。
这里有一个好的实践经验:为了让你整个工程提供的接口不至于分散在各个bundle里面,最好建一个interfaces的bundle,这里面都是接口,而且对外不提供任何的服务,也不引用任何的别人。