论坛首页 Java企业应用论坛

基于插件开发模式的WEB开发

浏览 37919 次
精华帖 (0) :: 良好帖 (9) :: 新手帖 (20) :: 隐藏帖 (1)
作者 正文
   发表时间:2009-05-04  
1、通过ServletBridge把OSGI框架部署到Tomcat容器中去。
程序文件整体结构图如下:
2、通过一个runtime插件把相关需要启动的插件启动起来。
3、在config.ini文件中配置runtime插件在OSGI启动时即启动。
4、利用WebServiceExporter类来注册WebService服务
5、CXFNonSpringServlet类是用来提供Servlet监听
6、Spring通过插件形式集成到框架中来。
   发表时间:2009-05-04   最后修改:2009-05-04
程序结构图:
Application.war
|-index.jsp
|-WEB-INF
    |-classes
    |-eclipse
    |   |-configuration
    |   |   |-config.ini
    |   |-plugins
    |   |   |-com.**.***.***_1.0.0.jar
    |   |   |-com.***.***.server.cxfbundle_1.0.0.jar
    |   |   |-com.***.***.server.runtime_1.0.0.jar
    |   |   |-com.springsource.net.sf.cglib-2.1.3.jar
    |   |   |-com.springsource.org.aopalliance-1.0.0.jar
    |   |   |-com.springsource.slf4j.api-1.5.0.jar
    |   |   |-com.springsource.slf4j.log4j-1.5.0.jar
    |   |   |-com.springsource.slf4j.org.apache.commons.logging-1.5.0.jar
    |   |   |-log4j.osgi-1.2.15-SNAPSHOT.jar
    |   |   |-org.eclipse.equinox.common_3.4.0.v20080421-2006.jar
    |   |   |-org.eclipse.equinox.http.registry_1.0.100.v20080427-0830.jar
    |   |   |-org.eclipse.equinox.http.servlet_1.0.100.v20080427-0830.jar
    |   |   |-org.eclipse.equinox.http.servletbridge_1.0.0.v20080427-0830.jar
    |   |   |-org.eclipse.equinox.registry_3.4.0.v20080516-0950.jar
    |   |   |-org.eclipse.osgi_3.4.2.R34x_v20080826-1230.jar
    |   |   |-org.eclipse.update.configurator_3.2.201.R34x_v20080819.jar
    |   |   |-spring-aop-2.5.6.jar
    |   |   |-spring-beans-2.5.6.jar
    |   |   |-spring-context-2.5.6.jar
    |   |   |-spring-context-support-2.5.6.jar
    |   |   |-spring-core-2.5.6.jar
    |   |   |-spring-osgi-core-1.2.0-m2.jar
    |   |   |-spring-osgi-extender-1.2.0-m2.jar
    |   |   |-spring-osgi-io-1.2.0-m2.jar
    |   |-launch.ini
    |-lib
    |  |-servletbridge.jar
    |-web.xml
0 请登录后投票
   发表时间:2009-05-04  
web.xml内容
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4" 
	xmlns="http://java.sun.com/xml/ns/j2ee" 
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee 
	http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
	<welcome-file-list>
		<welcome-file>index.html</welcome-file>
		<welcome-file>index.htm</welcome-file>
		<welcome-file>index.jsp</welcome-file>
		<welcome-file>default.html</welcome-file>
		<welcome-file>default.htm</welcome-file>
		<welcome-file>default.jsp</welcome-file>
	</welcome-file-list>
	<servlet>
		<servlet-name>equinoxbridgeservlet</servlet-name>
		<servlet-class>org.eclipse.equinox.servletbridge.BridgeServlet</servlet-class>
		<init-param>
			<param-name>enableFrameworkControls</param-name>
			<param-value>false</param-value>
		</init-param>
		<init-param>
			<param-name>commandline</param-name>
			<param-value>-console</param-value>
		</init-param>
		<init-param>
			<param-name>extendedFrameworkExports</param-name>
			<param-value></param-value>
		</init-param>
		<load-on-startup>1</load-on-startup>
	</servlet>
	<servlet-mapping>
		<servlet-name>equinoxbridgeservlet</servlet-name>
		<url-pattern>/*</url-pattern>
	</servlet-mapping>
</web-app>
0 请登录后投票
   发表时间:2009-05-04   最后修改:2009-05-04
config.ini内容:
#
# initial bundles
#
osgi.bundles=\
org.eclipse.equinox.common@2:start, \
org.eclipse.update.configurator@3:start, \
com.xxx.xxx.server.runtime@start

#
# start level
#
osgi.bundles.defaultStartLevel=4

--------------------

launch.in内容
# Eclipse Runtime Configuration Overrides
# These properties are loaded prior to starting the framework and can also be used to override System Properties
# @null is a special value used to override and clear the framework's copy of a System Property prior to starting the framework
# "*" can be used together with @null to clear System Properties that match a prefix name.

osgi.*=@null
org.osgi.*=@null
eclipse.*=@null

osgi.parentClassloader=ext
osgi.contextClassLoaderParent=ext


0 请登录后投票
   发表时间:2009-05-04   最后修改:2009-05-04
runtime插件(该插件也就只有一个java程序)的Activator.java内容:


import org.osgi.framework.Bundle;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;

public class Activator implements BundleActivator {

    private static final String SPRING_CONFIG_PATH = "/META-INF/spring";
    private static final String BUNDLE_ACTIVATOR = "Bundle-Activator";

//    private static Log log = LogFactory.getLog(Activator.class);
    
	/*
	 * (non-Javadoc)
	 * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext)
	 */
	public void start(BundleContext context) throws Exception {
        // get this bundle
        Bundle thisBundle = context.getBundle();
        
        // get all bundles
        Bundle[] bundles = context.getBundles();

        // for each bundle except this bundle
        for (Bundle bundle : bundles)
        {
            // if bundle can be start
            if (thisBundle != bundle && canBeStart(bundle))
            {
                startBundle(bundle);
            }
        }
	}

    private void startBundle(Bundle bundle)
    {
        // start the bundle
        try
        {
            bundle.start();
        }
        catch (Exception e)
        {
//            log.error("start bundle " + bundle.getSymbolicName() + " failed", e);
        	System.out.println("start bundle " + bundle.getSymbolicName() + " failed.");
        	System.out.println(e.toString());
        }
    }

    private boolean canBeStart(Bundle bundle)
    {
        // if bundle is ready to start
        if (bundle.getState() == Bundle.RESOLVED
                || bundle.getState() == Bundle.STARTING
                || bundle.getState() == Bundle.INSTALLED)
        {
            // start bundle if bundle activator is set
            if (bundle.getHeaders().get(BUNDLE_ACTIVATOR) != null)
            {
                return true;
            }
            // start bundle if it is spring powered
            else if (bundle.getEntry(SPRING_CONFIG_PATH) != null)
            {
                return true;
            }
        }

        return false;
    }
    
	/*
	 * (non-Javadoc)
	 * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)
	 */
	public void stop(BundleContext context) throws Exception {
	}

}
0 请登录后投票
   发表时间:2009-05-04   最后修改:2009-05-04
WebServiceExporter.java内容:
import org.apache.cxf.frontend.ServerFactoryBean;
import org.apache.cxf.jaxb.JAXBDataBinding;
import org.springframework.beans.factory.InitializingBean;

public class WebServiceExporter implements InitializingBean
{
    // URL访问地址
    private String address = null;

    // Service接口的实现类对象
    private Object serviceImplBean = null;

    // Service接口
    private Class< ? > serviceInterface = null;

    public void afterPropertiesSet() throws Exception
    {
        /**
         * 检查参数的合法性
         */
        checkServiceInterface();

        ServerFactoryBean factory = new ServerFactoryBean();
        factory.setServiceClass(serviceInterface);
        factory.setServiceBean(serviceImplBean);
        factory.setAddress(address);
        factory.getServiceFactory().setDataBinding(new JAXBDataBinding());
        // System.out.println("Address : " + address);
        factory.create();
    }

    /**
     * Check whether a service reference has been set, and whether it matches
     * the specified service.
     * @see #setServiceInterface
     * @see #setService
     * @throws IllegalArgumentException
     *             IllegalArgumentException
     */
    private void checkServiceInterface() throws Exception
    {
        if (serviceInterface == null)
        {
            throw new Exception("Property 'serviceInterface' is required");
        }
        if (serviceImplBean instanceof String)
        {
            throw new Exception(
                    "Service ["
                            + serviceImplBean
                            + "] is a String "
                            + "rather than an actual service reference: Have you accidentally specified "
                            + "the service bean name as value instead of as reference?");
        }
        if (!serviceInterface.isInstance(serviceImplBean))
        {
            throw new Exception("Service interface ["
                    + serviceInterface.getName()
                    + "] needs to be implemented by service ["
                    + serviceImplBean + "] of class ["
                    + serviceImplBean.getClass().getName() + "]");
        }
    }

    public void setAddress(String address)
    {
        if (address.startsWith("/"))
        {
            this.address = address;
        }
        else
        {
            this.address = "/" + address;
        }
    }

    public void setServiceInterface(Class< ? > serviceInterface)
    {
        this.serviceInterface = serviceInterface;
    }

    public void setServiceImplBean(Object serviceImplBean)
    {
        this.serviceImplBean = serviceImplBean;
    }
}
0 请登录后投票
   发表时间:2009-05-04   最后修改:2009-05-04
CXFWrapperServlet.java内容

import java.util.HashMap;
import java.util.Map;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;

import org.apache.cxf.Bus;
import org.apache.cxf.BusFactory;
import org.apache.cxf.transport.servlet.CXFNonSpringServlet;

public class CXFWrapperServlet extends CXFNonSpringServlet
{
    private static final long serialVersionUID = -6994879522066465447L;

    private static Map<String, Bus> busMap = new HashMap<String, Bus>();

    public void init(ServletConfig servletConfig) throws ServletException
    {
        super.init(servletConfig);
        busMap.put("servletBus", getBus());
        Bus bus = CXFWrapperServlet.getMyBus("servletBus");
        BusFactory.setDefaultBus(bus);
    }

    @Override
    public void loadBus(ServletConfig servletConfig) throws ServletException
    {
        this.bus = BusFactory.getDefaultBus(true);
        super.loadBus(servletConfig);
    }

    public static Bus getMyBus(String key)
    {
        return busMap.get(key);
    }
}
0 请登录后投票
   发表时间:2009-05-04   最后修改:2009-05-04
Spring配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:osgi="http://www.springframework.org/schema/osgi"
	xsi:schemaLocation="
  http://www.springframework.org/schema/beans
  http://www.springframework.org/schema/beans/spring-beans.xsd
  http://www.springframework.org/schema/osgi
  http://www.springframework.org/schema/osgi/spring-osgi.xsd">

	 
	<!-- define service bean -->
	<bean id="IProjMgrServiceClient" class="com.***.***.server.pm.service.impl.ProjMgrServiceClientImpl" />
	<bean class="com.***.***.server.cxfbundle.server.WebServiceExporter">
		<property name="address" value="projmgr" />
		<property name="serviceImplBean" ref="IProjMgrServiceClient" />
		<property name="serviceInterface"
			value="com.***.***.server.pm.service.IProjMgrServiceClient" />
	</bean>
	
	
	<bean id="ILoginOnline" class="com.***.***.server.security.login.impls.LoginOnlineImpl" />
	<bean class="com.***.***.server.cxfbundle.server.WebServiceExporter">
		<property name="address" value="login" />
		<property name="serviceImplBean" ref="ILoginOnline" />
		<property name="serviceInterface"
			value="com.***.***.server.security.login.interfaces.ILoginOnline" />
	</bean>
</beans>
0 请登录后投票
   发表时间:2009-05-04   最后修改:2009-05-04
说明一下:
1、由于不能上传附件(主要是因为公司信息安全限制),所以demo无法传,对于新手很抱歉,但是希望对于那些正在研究如何进行插件开发的人有点帮助。
2、带有***的插件都是我自己写的插件包。
3、我们的项目服务端没有UI,所以没有太多考虑服务端UI的事情,但是我细想了一下,应该可以集成到这里面的,大家可以补充一下,共同学习。
4、我们的项目服务端暂时只提供SOAP服务。所有的界面都在客户端,客户端是RCP
0 请登录后投票
   发表时间:2009-05-04  
请问是否有过实际的项目应用,性能如何?
1 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics