Как зарегистрировать декорированные объекты в каркасах Dependency Injection (PicoContainer)?
Я хочу обернуть несколько классов, реализующих интерфейс Job, в объект JobEnabledDecorator, который определяет, будет ли он выполняться.
У меня возникают проблемы с выяснением, как настроить это в PicoContainer, чтобы он знал, как создавать объекты реализации Job с обертыванием их JobEnabledDecorator.
Возможно ли это в рамках внедрения зависимостей?
Возможно ли это в PicoContainer?
Если так, любая помощь будет оценена.
1 ответ
Возможно, вы захотите добавить "поведение". Коротко говоря, вам нужно зарегистрировать фабрику поведения, которая создает поведения, которые обертывают ваши адаптеры компонентов. Проще описать, пройдя по примеру.
Во-первых, вы хотите создать контейнер, что-то вроде этого.
final MutablePicoContainer container = new PicoBuilder()
.withBehaviors(new JobEnabledDecorating())
.build();
Это означает, что, как только базовый объект создан - в вашем случае Job
- Вы хотите добавить что-то еще к этому. Есть несколько встроенных поведений, но вы хотите свой собственный: JobEnabledDecorating
,
public class JobEnabledDecorating extends AbstractBehaviorFactory {
@Override
public ComponentAdapter createComponentAdapter(
final ComponentMonitor componentMonitor, final LifecycleStrategy lifecycleStrategy,
final Properties componentProperties, final Object componentKey,
final Class componentImplementation, final Parameter... parameters) throws PicoCompositionException
{
return componentMonitor.newBehavior(
new JobEnabledDecorated(
super.createComponentAdapter(
componentMonitor, lifecycleStrategy, componentProperties,
componentKey, componentImplementation, parameters
)
)
);
}
}
Фабрика создает JobEnabledDecorated
поведения, оборачивая компонентный адаптер, который, в свою очередь, предоставляет ваши экземпляры. Реальная работа теперь сделана в этом поведении.
public class JobEnabledDecorated extends AbstractBehavior<Job> {
public JobEnabledDecorated(final ComponentAdapter<Job> delegate) {
super(delegate);
}
@Override
public Job getComponentInstance(final PicoContainer container, final Type into)
throws PicoCompositionException {
final Job instance = super.getComponentInstance(container, into);
return new JobEnabledDecorator(instance);
}
@Override
public String getDescriptor() {
return "JobEnabledDecorator-";
}
}
getComponentInstance
запрашивает задание, добавляет декоратор и возвращает этот обернутый объект как новый экземпляр. Вы должны будете добавить свою собственную логику здесь.
public interface Job {
void execute();
}
public class JobEnabledDecorator implements Job {
private Job delegate;
public JobEnabledDecorator(final Job delegate) {
this.delegate = delegate;
}
@Override
public void execute() {
System.out.println("before");
delegate.execute();
System.out.println("after");
}
}
public class MyJob implements Job {
@Override
public void execute() {
System.out.println("execute");
}
}
Вернемся к нашему использованию контейнера, рассмотрим этот пример.
final MutablePicoContainer container = new PicoBuilder()
.withBehaviors(new JobEnabledDecorating())
.build();
container.addComponent(Job.class, MyJob.class);
final Job job = container.getComponent(Job.class);
job.execute();
Запуск этого будет печатать:
before
execute
after
Это, конечно, потому что контейнер передал вам JobEnabledDecorator(MyJob)
объект.