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.
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) ? Or do I have to use 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. Take a look at this JSF solution, using an application scoped bean which manages the configuration. The scope of the Bean
can be anyone you need. Being your Service classes @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. I use a Random
function for testing purpose:
@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. Just evaluate the EL expression you need into the context (see the reference).
See also: