I have configuration class, which I inject into another class.
Configuration class looks as follows:
@RequestScoped
public class Configuration {
@ConfigProperty(name = "VALUE")
public String value;
public String getValue() {
return value;
}
}
This configuration is injected into following place:
@ApplicationScoped
public class EndpointImpl implements Endpoint {
private Configuration configuration;
@Inject
public EndpointImpl(Configuration configuration) {
this.configuration = configuration;
System.out.println("configuration.value=" + configuration.value);
System.out.println("configuration.getValue()=" + configuration.getValue());
System.out.println("configuration.value=" + configuration.value);
}
@PostConstruct
public void postConstruct() {
System.out.println("configuration.value=" + configuration.value);
System.out.println("configuration.getValue()=" + configuration.getValue());
System.out.println("configuration.value=" + configuration.value);
}
Both the constructor and postConstruct give the same output:
configuration.value=null
configuration.getValue()=someValue
configuration.value=null
Everything works fine as long as the value is retrieved through the getter method. When I try to retrieve it through the public field it returns null. I thought that, when CDI completes the process of building the bean, the fields inside the class will be set to appropriate values.
Why does it behave in such a way?
>Solution :
This is expected, because your Configuration bean is @RequestScoped. The request scope is one of so-called normal scopes, and whenever you @Inject a normal-scoped bean, you will always get a so-called client proxy.
The client proxy exists to lookup the correct bean instance and forward method invocations to it. In this case, it will lookup the bean instance for current request.
So, when you’re accessing fields, you’re accessing them on the client proxy — not on the instance that pertains to the current request.
Whenever you inject a normal-scoped bean, never access fields directly. Always call methods. You may access fields directly on @Singleton and @Dependent beans, because they don’t come up with a client proxy.