• 利用OSGi DS实现可配置Web应用程序初探


    Eclipse的插件体系结构让我们可以灵活定义插件,组装成可插拔的软件系统,OSGi的Declarative Services(DS)有着和Eclipse扩展点类似的思想(见很详细的一篇对比文章),很自然的想到,如果把DS应用在Web应用程序上,我们将能够通过定义自己的“扩展点”,打造SOA的Web应用程序。题目中“可配置”是指,根据用户需求,提供给客户不同的包即可形成针对该客户定制的产品/解决方案。

    现在来试试怎样用DS实现动态配置一个Web应用程序界面里菜单,使用的OSGi实现还是Equinox。Eclipse里菜单项是通过实现actionSets、editorActions等等扩展点添加的,在OSGi里没有这些“扩展点”,没关系,我们可以自己定义。

    一、用一个Bundle定义Java接口文件,和Eclipse扩展点的功能类似,这些接口可以作为服务的接入点。例子里这个Bundle的ID是net.bjzhanghao.osgi.services,接口类是IMenuContributor,内容很简单如下所示:

    public interface IMenuContributor {
        
        
    public List<MenuItem> getItems();
        
    }

    上面用到的MenuItem是自己定义的一个简单的数据结构,包含name和url两个String类型的成员变量和相应的getter/setter方法,这里就不展示了。

    二、用0..n个Bundle实现上面定义的接口(暂时称之为Contributor),并声明为服务。例子里有两个这样的Bundle,ID分别是net.bjzhanghao.osgi.menu.contributor和net.bjzhanghao.osgi.menu.contributor2,实现类都是MyMenuContributor,前者提供了Menu1..3,后者提供了Menu4..5;以下是服务的声明,即项目里OSGI-INF/component.xml文件的内容:

    <?xml version="1.0" encoding="UTF-8"?>
    <component name="services">
        
    <implementation 
            
    class="net.bjzhanghao.osgi.menu.contributor.MyMenuContributor"/> 
        
    <service>
            
    <provide interface="net.bjzhanghao.osgi.services.IMenuContributor"/>
        
    </service>
    </component>

    MyMenuContributor实现IMenuContributor,你可以任意实现它,例子里是让它提供三个菜单项:

    public class MyMenuContributor implements IMenuContributor {

        
    public List<MenuItem> getItems() {
            List
    <MenuItem> list = new ArrayList<MenuItem>();
            list.add(
    new MenuItem("Menu1"null));
            list.add(
    new MenuItem("Menu2"null));
            list.add(
    new MenuItem("Menu3"null));
            
    return list;
        }

    }

    三、现在SOA的一半工作也就是注册服务的部分完成了,剩下要做的是另一半,消费这些服务。首先在web应用程序Bundle里,创建一个Helper类收集这些服务,这个Helper类的功能相当于一个Registry。例子里这个Bundle的ID是net.bjzhanghao.osgi.example,Helper类是MenuHelper;以下是对MenuHelper的配置,即项目里OSGI-INF/component.xml文件的内容,这样OSGi在启动Bundle时会把实现IMenuContributor的服务通过addMenuContributor方法注册到MenuHelper里,注意cardinality的值要为"0..n",policy的值要为"dynamic":

    <?xml version="1.0" encoding="UTF-8"?>
    <component name="menuHelper">
        
    <implementation     
            
    class="net.bjzhanghao.osgi.example.MenuHelper"/>   
        
    <reference name="menuHelper"
            interface
    ="net.bjzhanghao.osgi.services.IMenuContributor"
            cardinality
    ="0..n"
            policy
    ="dynamic"
            bind
    ="addMenuContributor"
            unbind
    ="removeMenuContributor"
        
    />
    </component>

    四、在JSP/Servlet里,利用上面的Helper类构造界面(或业务逻辑)。因为我们定义的接口是关于菜单的,所以例子应用的菜单会根据Bundle配置(启动/停止)变化。例子里是在ExampleServlet里实现的,代码很简单如下所示:

    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType(
    "text/html");
        resp.getWriter().write(
    "Hello<br/>");
        resp.getWriter().write(
    "<ul>");
        
    for (IMenuContributor menuContributor : MenuHelper.getInstance().getMenuContributors()) {
            
    for (MenuItem mItem : menuContributor.getItems()) {
                resp.getWriter().write(
    "<li><a href=\"" + mItem.getUrl() + "\">" + mItem.getName() + "</a></li>");
            }
        }
        resp.getWriter().write(
    "</ul>");
    }

    五、执行方式:

    1、在Eclipse里导入代码包里所有项目,启动上述所有项目及其依赖的项目(Add Required Bundles),见下图:


    2、在浏览器里输入地址http://localhost/exampleServlet,应该可以看到五个菜单项,见下图(这个简单的例子里没有考虑顺序问题,所以Menu4..5可能出现在前面,使用类似Eclipse里为Menu预留位置的方式可以解决):


    3、回到Eclipse,在Console里输入ss查看当前的Bundle,应该可以看到类似下图的内容:


    4、在Console里输入stop 35(35是Contributor的Bundle序号),Console会提示“Calling removeMenuContributor”,然后到浏览器里刷新页面,应该看到菜单项只剩下Menu4..5。


    代码下载

    如果觉得本文内容有帮助:试试我开发的Android应用 应用计时折扣君推荐+1(需登录)

  • 相关阅读:
    Elasticsearch (二) 索引
    Elasticsearch (一)搭建与启动
    IDEA 插件
    IDEA 导入华丽的皮肤
    Tomcat https 访问
    oracle系统视图SQL语句整理
    Java内存优化和性能优化的几点建议
    Tomcat配置SSL证书
    sublime集成MinGW,打造C/C++开发环境
    一个简单的Vue.js组件开发示例
  • 原文地址:https://www.cnblogs.com/bjzhanghao/p/967320.html
Copyright © 2020-2023  润新知