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