Условное внедрение бина с ManagedProperty

У меня есть контроллер со следующими свойствами:

@ManagedProperty(value="#{remoteApplication}")
private transient ProcessService applicationService;

@ManagedProperty(value="#{remoteSystem}")
private transient SystemService systemService;

@ManagedProperty(value="#{remoteFileSystem}")
private transient FileSystemService fileSystemService;

Я хотел бы ввести бины условно, в соответствии с файлом свойств, указывающим, должны ли службы быть локальными или удаленными.

Приведенный выше пример предназначен для удаленного и локального:

@ManagedProperty(value="#{localApplication}")
private transient ProcessService applicationService;

@ManagedProperty(value="#{localSystem}")
private transient SystemService systemService;

@ManagedProperty(value="#{localFileSystem}")
private transient FileSystemService fileSystemService;

Есть ли способ сделать это с помощью JSF (возможно, используя ValueExpression как указано в документации ManagedProperty)? Или я должен использовать CDI?

Заранее большое спасибо за ваши предложения!

С уважением,

Zim

1 ответ

Решение

Вы можете сделать это только с помощью JSF, даже интеграция CDI может помочь вам разделить его на соответствующие слои. Взгляните на это решение JSF, использующее bean-объект области применения, который управляет конфигурацией. Сфера действия Bean может быть кем угодно. Быть вашим классом обслуживания @ManagedBean:

@ManagedBean
@ApplicationScoped
public class LocalProcessService implements ProcessService {

    public LocalProcessService() {
        System.out.println("Local service created");
    }

}

@ManagedBean
@ApplicationScoped
public class RemoteProcessService implements ProcessService {

    public RemoteProcessService() {
        System.out.println("Remote service created");
    }

}

Затем реализуйте компонент конфигурации, который читает требуемый файл и сохраняет флаг со значением чтения. Я использую Random функция для тестирования:

@ManagedBean(eager = true)
@ApplicationScoped
public class PropertiesBean {

    private boolean localConfig = false;

    public PropertiesBean() {
        // Read your config file here and determine wether it is local
        //or remote configuration
        if (new Random().nextInt(2) == 1) {
            localConfig = true;
        }
    }

    public boolean isLocalConfig() {
        return localConfig;
    }

}

Как только вы получите его, в вашем контроллере вида сделайте инъекцию в зависимости от значения этого флага, используя троичный оператор:

@ManagedBean
@ViewScoped
public class Bean {

    @ManagedProperty(value = "#{propertiesBean.localConfig ? localProcessService : remoteProcessService}")
    protected ProcessService processService;

    public void setProcessService(ProcessService processService) {
        this.processService = processService;
    }

}

Кроме того, вы можете сохранить ссылку на сервис непосредственно в вашем PropertiesBean, чтобы не приходилось оценивать значение этого флага в ваших управляемых bean-компонентах. Просто оцените нужное выражение EL в контексте (см. Ссылку).

Смотрите также:

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