OSGi AspectService получает свойства службы для соответствующей службы

Данный сервис Sender со свойствами и аспектным обслуживанием LogSenderкак LogSender получить служебные свойства текущего Sender? Я хотел бы добавить свойство, чтобы опционально регистрировать данные, которые конкретный Sender отправляет.

component.getServiceProperties(); кажется, возвращает LogSenderСервисные свойства вместо Senderсвойства.

Я смотрел на ConfigAdmin но я не вижу способа связать Sender тот LogSender с учетом конкретной конфигурации.

Я использую Apache Felix в качестве контейнера OSGi, если это актуально.

Вот Activator"s init метод после добавления ConfigurationAdmin в список зависимостей.

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)));
}

1 ответ

Решение

Чтобы внедрить свойства сервиса исходного Отправителя в аспект LogSender, вы можете использовать подпись в DependencyActivatorBase (или DependencyManager), которая позволяет указать "добавить / изменить / удалить" методы обратного вызова аспекта LogSender:

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

Тогда сигнатура метода обратного вызова LogSenderAspect может принимать в качестве аргументов службу отправителя, а также свойства карты службы отправителя.

Теперь второе (более простое) решение - указать сервисный фильтр для вашего аспекта, и в этом случае; нет необходимости указывать какие-либо обратные вызовы.

давайте посмотрим на первое решение с обратными вызовами, где аспект LogSender определяет метод "setSender(Sender, Map)", и этот аспект будет регистрировать только метод "send" служб Sender, имеющих свойства службы "foo=bar" (здесь мы игнорируем изменения / удаленные обратные вызовы службы):

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();
    }       
}

это помогает? /Pierre

Другие вопросы по тегам