0

给定一个Sender具有属性的服务和一个切面服务LogSender,如何LogSender获取当前的服务属性Sender?我想添加一个属性来选择性地记录特定Sender发送的数据。

component.getServiceProperties();似乎返回LogSender' 服务属性而不是Sender' 属性。

我已经看过了,ConfigAdmin但我没有看到一种方法可以将Sender那个LogSender方面与使用的特定配置相关联。

如果相关,我将使用 Apache Felix 作为我的 OSGi 容器。

这是添加到依赖列表后的Activator'方法。initConfigurationAdmin

public void init(BundleContext context, DependencyManager manager) throws Exception {
     manager.add(createAspectService(Sender.class, null, 10).setImplementation(LogSender.class)
            .add(createServiceDependency().setService(ConfigurationAdmin.class)
                    .setRequired(true)));
            .add(createServiceDependency().setService(LogService.class).setRequired(true)));
}
4

1 回答 1

0

要将原始 Sender 的服务属性注入 LogSender 方面,您可以使用 DependencyActivatorBase(或 DependencyManager)中的签名,它允许指定“添加/更改/删除”LogSender 方面的回调方法:

DependencyActivatorBase.createAspectService(
    Class<?> serviceInterface,
    String serviceFilter,
    int ranking,
    String add,
    String change,
    String remove);

然后 LogSenderAspect 回调方法签名可以将 Sender 服务以及 Sender 服务属性 Map 作为参数。

现在,第二个(更简单的)解决方案是为您的方面指定一个服务过滤器,在这种情况下;无需指定任何回调。

让我们看看第一个带有回调的解决方案,其中 LogSender 方面定义了一个“setSender(Sender, Map)”方法,然后该方面将只记录具有“foo=bar”服务属性的 Sender 服务的“发送”方法(在这里,我们忽略服务更改/删除的回调):

public class Activator extends DependencyActivatorBase{
    public void init(BundleContext ctx, DependencyManager dm) throws Exception {
        Component logSender = createAspectService(Sender.class, null, 10, "setSender", null, null)
                .setImplementation(LogSender.class)    
                .add(createServiceDependency().setService(LogService.class).setRequired(true));
        dm.add(logSender);         
    }
}

class LogSender implements Sender {     
    volatile Sender sender;
    volatile Map<String, Object> senderProperties;
    volatile LogService log;

    void setSender(Sender sender, Map<String, Object> senderProperties) {
        this.sender = sender;
        this.senderProperties = senderProperties;
    }

    @Override
    public void send() {
        if ("bar".equals(senderProperties.get("foo"))) {
            log.log(LogService.LOG_DEBUG, "calling method send called on Sender service having properties foo=bar");
        }
        this.sender.send();         
    }       
}

现在,一个更简单的解决方案是在定义方面时使用服务过滤器“(foo=bar)”,在这种情况下,不需要使用回调:

public class Activator extends DependencyActivatorBase{
    public void init(BundleContext ctx, DependencyManager dm) throws Exception {
        Component logSender = createAspectService(Sender.class, "(foo=bar)", 10)
                .setImplementation(LogSender.class)    
                .add(createServiceDependency().setService(LogService.class).setRequired(true));
        dm.add(logSender);         
    }
}

class LogSender implements Sender {     
    volatile Sender sender;

    @Override
    public void send() {
        log.log(LogService.LOG_DEBUG, "calling method send called on Sender service having properties foo=bar");
        this.sender.send();
    }       
}

这有帮助吗?/皮埃尔

于 2018-01-21T21:59:55.133 回答