我也来玩OSGI(二)

在 src 中新建 org.vwpolo.login.service 包,如果修改Activator这个控制插件生命周期的这个类,为了阅读方便,将他重命名了

package  org.vwpolo.login.service;

import
 org.osgi.framework.BundleActivator;
import
 org.osgi.framework.BundleContext;
import
 org.osgi.util.tracker.ServiceTracker;
import
 org.vwpolo.services.LoginService;

public class StartLoginActivator implements BundleActivator 
{

    
private BundleContext context = null
;
    
private ServiceTracker tracker = null
;
    
private LoginDialog loginDialog = new LoginDialog(null
);
    
    
/*
     * (non-Javadoc)
     * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext)
     
*/

    
public void start(BundleContext context) throws Exception {
        
this.context =
 context;
        tracker 
= new ServiceTracker(context, LoginService.class
.getName(),
                
new
 LoginServiceTracker(context,loginDialog));
        tracker.open();
        loginDialog.open();
    }


    
/*
     * (non-Javadoc)
     * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)
     
*/

    
public void stop(BundleContext context) throws Exception {
        tracker.close();
    }


}

 

//登陆服务跟踪器,记录登陆情况
package  org.vwpolo.login.service;

import
 org.osgi.framework.BundleContext;
import
 org.osgi.framework.ServiceReference;
import
 org.osgi.util.tracker.ServiceTrackerCustomizer;
import
 org.vwpolo.services.LoginService;
/**
 * 
@author 刘尧兴
 *
 
*/

public class LoginServiceTracker implements ServiceTrackerCustomizer  {
    
private
 LoginDialog loginDialog;
    
private
 BundleContext bundleContext;
    
    
public LoginServiceTracker(BundleContext bundleContext,LoginDialog loginDialog) 
{
        
this.loginDialog =
 loginDialog;
        
this.bundleContext =
 bundleContext;
    }


    @Override
    
public Object addingService(ServiceReference reference) {
        LoginService service 
=
 (LoginService)bundleContext.getService(reference);
        loginDialog.addLoginService(service);
        
return
 service;
    }


    @Override
    
public void modifiedService(ServiceReference reference, Object serviceObject) {
        LoginService service 
=
 (LoginService)bundleContext.getService(reference);
        loginDialog.setLoginService(service);
    }


    @Override
    
public void removedService(ServiceReference reference, Object serviceObject) {
        LoginService service 
=
 (LoginService)bundleContext.getService(reference);
        loginDialog.removeLoginService(service);
    }

}

 

//登陆对话框
package  org.vwpolo.login.service;

import
 java.util.ArrayList;

public class LoginDialog extends TitleAreaDialog 
{

    
private
 Text passwordText;
    
private
 Text userNameText;
    
private
 LoginService loginService;
    
private List<LoginService> loginServiceList = new ArrayList<LoginService>
();
    
/**
     * Create the dialog
     * 
@param parentShell
     
*/

    
public LoginDialog(Shell parentShell) {
        
super
(parentShell);
    }

    
    
/**
     * Create the dialog
     * 
@param parentShell
     
*/

    
public LoginDialog(Shell parentShell, LoginService loginService) {
        
super
(parentShell);
        
        
this.loginService =
 loginService;
    }


    
/**
     * 
@param service
     
*/

    
public void addLoginService(LoginService service) {
        loginServiceList.add(service);
        
this.loginService =
 service;
    }


    
/**
     * 
@param service
     
*/

    
public void setLoginService(LoginService service) {
        
this.loginService =
 service;
    }


    
/**
     * 
@param service
     
*/

    
public void removeLoginService(LoginService service) {
        loginServiceList.remove(service);
        
if(loginServiceList.size() == 0
)
            loginService 
= null
;
        
else
 
           
this.loginService = loginServiceList.get(loginServiceList.size() - 1
);
    }

    
    
/**
     * Create contents of the dialog
     * 
@param parent
     
*/

    @Override
    
protected Control createDialogArea(Composite parent) {
        Composite area 
= (Composite) super
.createDialogArea(parent);
        Composite container 
= new
 Composite(area, SWT.NONE);
        
final GridLayout gridLayout = new
 GridLayout();
        gridLayout.numColumns 
= 2
;
        container.setLayout(gridLayout);
        container.setLayoutData(
new
 GridData(GridData.FILL_BOTH));

        
final Label label = new
 Label(container, SWT.NONE);
        label.setText(
"用户名"
);

        userNameText 
= new
 Text(container, SWT.BORDER);
        
final GridData gd_userNameText = new GridData(SWT.FILL, SWT.CENTER, truefalse
);
        userNameText.setLayoutData(gd_userNameText);

        
final Label label_1 = new
 Label(container, SWT.NONE);
        label_1.setText(
"密 码"
);

        passwordText 
= new
 Text(container, SWT.BORDER);
        
final GridData gd_passwordText = new GridData(SWT.FILL, SWT.CENTER, truefalse
);
        passwordText.setLayoutData(gd_passwordText);
        setTitle(
"欢迎登录"
);
        setMessage(
"请输入用户名和密码"
);
        
//
        return
 area;
    }


    
/**
     * Create contents of the button bar
     * 
@param parent
     
*/

    @Override
    
protected void createButtonsForButtonBar(Composite parent) {
        createButton(parent, IDialogConstants.OK_ID, 
"登录"
,
                
true
);
        createButton(parent, IDialogConstants.CANCEL_ID,
                
"取消"false
);
    }


    
/**
     * Return the initial size of the dialog
     
*/

    @Override
    
protected Point getInitialSize() {
        
return new Point(359221
);
    }

    
protected void configureShell(Shell newShell) {
        
super
.configureShell(newShell);
        newShell.setText(
"欢迎登录"
);
    }

    
protected void buttonPressed(int buttonId) {
        
if (buttonId == IDialogConstants.OK_ID) 
{
            
if(!doLogin()) 
{
                setErrorMessage(
"用户名或密码错误!"
);
                
return
;
            }

        }

    }


    
private boolean doLogin() {
        String userName 
=
 userNameText.getText().trim();
        String password 
=
 passwordText.getText().trim();
        
if(loginService == null
{
            System.out.println(
"登录服务不可用!"
);
            
return false
;
        }

        
boolean success = loginService.login(userName, password);
        
if
(success) 
            System.out.println(
"登录成功!"
);
        
else

            System.out.println(
"登录失败!");
        
return
 success;
    }

 MANIFEST.MF文件内容为:

Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: StartLoginBundle Plug-in
Bundle-SymbolicName: StartLoginBundle
Bundle-Version: 1.0.0
Bundle-Activator: org.vwpolo.login.service.StartLoginActivator
Import-Package: org.eclipse.jface,
 org.eclipse.jface.dialogs,
 org.eclipse.jface.window,
 org.eclipse.swt,
 org.eclipse.swt.events,
 org.eclipse.swt.graphics,
 org.eclipse.swt.layout,
 org.eclipse.swt.widgets,
 org.osgi.framework;version="1.3.0",
 org.osgi.util.tracker;version="1.3.3",
 org.vwpolo.services
Eclipse-LazyStart: true
Export-Package: org.vwpolo.login.service

<think>我们正在回答用户关于OSGI框架的介绍技术实现的问题。根据引用内容,我们可以整合信息如下:1.OSGI(OpenServiceGatewayInitiative)框架是一个用于构建模块化、动态化的Java应用的标准。2.它提供了模块化(Bundle)、服务注册与发现、生命周期管理等特性。3.在OSGI中,每个模块称为一个Bundle,每个Bundle有独立的类加载器,实现了模块间的类隔离。4.引用[1]提到,SpringBoot应用可以集成OSGI框架,通过Servletbridge原理实现相互调用。5.引用[2]展示了如何创建OSGI模块的MANIFEST.MF文件,以及如何运行OSGI应用程序。6.引用[3]说明了OSGI处理动态性的能力,例如设备(服务)的动态注册注销。7.引用[4]提到了在Android上使用OSGI框架时,生成manifest.mf文件的方法。因此,我们可以组织回答如下:</think>### OSGI框架介绍与技术实现 #### 一、OSGI框架核心概念 OSGI(Open Service Gateway Initiative)是一个面向Java的动态模块化系统规范,主要解决以下问题: 1. **模块化**: 应用程序被拆分为独立模块(Bundle),每个Bundle包含: - Java类文件 - 资源文件 - 元数据(MANIFEST.MF) 示例Bundle声明: ```plaintext Bundle-SymbolicName: com.example.module Bundle-Version: 1.0.0 Bundle-Activator: com.example.Activator # 生命周期入口 ``` 2. **动态性**: Bundle支持运行时安装、更新、卸载,服务可动态注册/注销[^3]。例如设备接入时自动注册服务,移除时注销。 3. **类加载机制**: 每个Bundle拥有独立类加载器,通过`Import-Package``Export-Package`声明依赖关系[^1],实现模块间隔离与共享。 #### 、关键技术实现 1. **Bundle生命周期管理** - `BundleActivator`接口控制启动/停止: ```java public class Activator implements BundleActivator { public void start(BundleContext ctx) { ctx.registerService(MyService.class, new MyServiceImpl(), null); } public void stop(BundleContext ctx) { /* 资源释放 */ } } ``` 2. **服务注册与发现** 通过`BundleContext`发布/获取服务: ```java // 服务注册 ServiceRegistration reg = ctx.registerService(MyService.class.getName(), serviceObj, null); // 服务获取 ServiceReference ref = ctx.getServiceReference(MyService.class.getName()); MyService service = (MyService) ctx.getService(ref); ``` 3. **依赖解析** OSGI框架自动解决Bundle间的包依赖,确保: - 导入包必须有导出包匹配 - 版本号兼容性检查(如`Import-Package: com.utils;version="[1.0,2.0)"`) #### 三、集成实践 1. **Spring Boot集成OSGI** - 通过`ServletBridge`将OSGI容器嵌入Spring Boot应用[^1] - Spring Boot作为宿主环境,OSGI Bundle提供插件功能 - 双向调用机制: ```java // Spring调用OSGI服务 OsgiServiceProxyFactoryBean proxy = new OsgiServiceProxyFactoryBean(); proxy.setBundleContext(osgiContext); proxy.setInterface(MyOsgiService.class); ``` 2. **Android平台实现** - 使用bnd工具生成MANIFEST.MF[^4]: ```shell java -jar bnd.jar build --classpath bin --output module.jar descriptor.bnd ``` - 框架选择:Apache Felix或Eclipse Equinox #### 四、典型应用场景 1. **热部署系统**:无需重启更新模块 2. **物联网网关**:动态管理设备服务[^3] 3. **插件化应用**:如Eclipse IDE、企业级中间件 4. **微服务架构**:Bundle作为轻量级服务单元 ---
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值