简体   繁体   English

使用ManagedProperty有条件地注入bean

[英]Conditional injection of bean with ManagedProperty

I have a controller with the following properties: 我有一个具有以下属性的控制器:

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

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

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

I would like to inject beans conditionally, according to a property file telling if the services shall be local or remote. 根据一个属性文件,我想有条件地注入bean,该文件告诉服务是本地的还是远程的。

Example provided hereabove is for remote, and for local, would be: 上面提供的示例是针对远程的,对于本地而言的是:

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

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

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

Is there any way to do this with JSF (maybe using ValueExpression as specified in ManagedProperty documentation ) ? 有什么方法可以用JSF做到这一点(也许使用ManagedProperty文档中指定的ValueExpression )? Or do I have to use CDI ? 还是我必须使用CDI?

Many thanks in advance for your suggestions! 预先非常感谢您的建议!

Kind regards, 亲切的问候,

Zim 以星

You can do it with just JSF, even a CDI integration could help you dividing it in proper layers. 您可以只使用JSF做到这一点,即使CDI集成也可以帮助您将其划分为适当的层。 Take a look at this JSF solution, using an application scoped bean which manages the configuration. 使用管理配置的应用程序范围的Bean,看看这个JSF解决方案。 The scope of the Bean can be anyone you need. Bean的范围可以是您需要的任何人。 Being your Service classes @ManagedBean : 作为您的服务类@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");
    }

}

Then, implement a Configuration Bean which reads the file you want and stores a flag with the read value. 然后,实现一个配置Bean,该Bean读取所需的文件并存储带有读取值的标志。 I use a Random function for testing purpose: 我使用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;
    }

}

Once you've got it, in your view controller make the injection depending on that flag value, using a ternary operator: 一旦获得,在您的视图控制器中使用三元运算符根据该标志值进行注入:

@ManagedBean
@ViewScoped
public class Bean {

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

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

}

Alternativelly, you could store the service reference directly in your PropertiesBean , in order not to have to evaluate that flag value in your managed beans. 或者,您可以将服务引用直接存储在PropertiesBean ,以便不必在托管bean中评估该标志值。 Just evaluate the EL expression you need into the context (see the reference). 只需在上下文中评估所需的EL表达式即可(请参阅参考资料)。

See also: 也可以看看:

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM