cdi bean lack of value when accessed through public field - java

I have a 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 the 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);
}
Logs printed after going through constructor:
configuration.value=null
configuration.getValue()=someValue
configuration.value=null
I added postConstructor with the below similar code:
#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);
}
and the result is the same.
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?

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.

Related

Strange behavior calling package-private method of proxied object in Jersey 2

Following class
public class MaskHolder {
private Mask mask;
private UUID id = UUID.randomUUID()
void store() {
System.out.println(id);
}
public void get() {
System.out.println(id);
}
}
is bound to HK2 like this
bind(MaskHolder.class).to(MaskHolder.class)
.proxy(true).proxyForSameScope(false).in(RequestScoped.class);
Proxy injected to bean with #Context behaves as expected for public method but executes package-private method as well. The problem is package-private method does not trigger MethodInterceptor so it actually does not reach the same instance get() does.
The question is what is this "default" instance to which proxy forwards package-private method call. Calling get() method I reach different instance on different requests but calling store method ends up in the same instance every time so it behaves like singleton.
There was one more thing I didn't mention - proxy behaving like singleton was injected into JacksonJsonProvider subclass. So as far as I understand this subclass of JacksonJsonProvider is created only once in Jersey so instance of proxy injected into it does not change between requests.
Proxy is basically an artificial subclass of MaskHolder with interceptor on public methods but it basically is MaskHolder with it's UUID field. So if interceptor does not provide RequestScope bean we access "parent" MaskHolder. And because the proxy instance is injected only once to JacksonJsonProvider it is the same across requests.
Injecting MaskHolder into resource results in different proxy instance (different UUID) across requests.

Injecting #RequestScoped variable in singleton in wildfly

I've got a Java EE app running in wildfly acting as a REST API. Before an endpoint logic is run, a filter grabs a JWT out of the headers and sets the user on a request scoped variable like the CDI solution proposed here: https://stackoverflow.com/a/26778123/4236181
If I then inject that bean in a class annotated with #Singleton and run multiple requests at once I can see that Wildfly is using a single instance of my singleton class as expected, but it seems it's doing proxy magic for my request scope variable. My request scoped variable is different in each request, even though they are using the same instance of the singleton. I was under the impression you could not use request scoped variables in a singleton, does Wildfly allow you to do that now? What is happening here?
A contextual reference to a bean with a normal scope(such as RequestScope), is not a direct reference to a contextual instance of the bean. Instead, the contextual reference is a client proxy object. when a method is called the proxy looks up the current instance. so you could use RequestScope in a singleton
https://developer.jboss.org/blogs/stuartdouglas/2010/10/12/weld-cdi-and-proxies this would look sort of like this:(shows a client proxy).
public class PaymentProcessor_$$Proxy extends PaymentProcessor
{
public void processPayment(int amount)
{
PaymentProcessor instance = lookupBean();
instance.processPayment(amount);
}
private PaymentProcessor lookupBean()
{
//get the correct instance from the BeanManager and return it
}
}
As you can see, client proxy gets the correct instance from the BeanManager(lookupBean method)

spring #Autowire property vs setter

What is the difference between anotate #Autowired to a property or do it in the setter?
As far as I know they both have the same result, but is there any reason to use one over the other?
UPDATE (to be more concise)
Is there a difference between this
package com.tutorialspoint;
import org.springframework.beans.factory.annotation.Autowired;
public class TextEditor {
private SpellChecker spellChecker;
#Autowired
public void setSpellChecker( SpellChecker spellChecker ){
this.spellChecker = spellChecker;
}
public void spellCheck() {
spellChecker.checkSpelling();
}
}
and this
package com.tutorialspoint;
import org.springframework.beans.factory.annotation.Autowired;
public class TextEditor {
#Autowired
private SpellChecker spellChecker;
public TextEditor() {
System.out.println("Inside TextEditor constructor." );
}
public void spellCheck(){
spellChecker.checkSpelling();
}
}
Sometimes you need an instance of class A, but you do not store A in the fields of the class.
You just need A instance to perform a one-shot operation. Or, you use A instance to obtain an instance of B, and you are storing B in the field.
In those cases, a setter (or constructor) autowire will suit you better.
You will not have unused class-level fields.
Concrete example:
You need to construct RabbitTemplate (an object that sends messages to RabbitMQ)
To construct it, you need ConnectionFactory
http://docs.spring.io/spring-amqp/docs/latest_ga/api/org/springframework/amqp/rabbit/core/RabbitTemplate.html#RabbitTemplate-org.springframework.amqp.rabbit.connection.ConnectionFactory-
You do not need to store that ConnectionFactory. In that case, code that looks like this:
Class MyClass {
private RabbitTemplate template;
#Autowired
void setConnectionFactory(ConnectionFactory c) {
template=new RabbitTemplate(c);
}
}
...will serve you better than directly autowiring the ConnectionFactory field.
In this example, autowiring at the constructor level would be even better, because your object will always be completely constructed. It will be clear that ConnectionFactory is a mandatory dependency, not an optional one.
With #Autowired annotation, you don't need a setter method. Once your bean's constructor is done with allocating/creating the object, Spring will scan for this annotation and would inject the object instances that you annotated.
While if you have setter and if you are still using xml config, you would explicitly set properties.
Having said that, You could annotate your constructor and setter method with autowired annotation which i would prefer as this would give me flexibility later on to move away from Spring (although i wont do it).
If you use #Autowired annotation on a property, spring will initiate the property using spring.xml. You don't need setter in this case.
If you use #Autowired annotation on a setter, you are specifying to spring that it should initiate this property using this setter method where you can add your custom code, like initializing some other property with this property.
Usage with Example:
In the case of using DAO operations using JdbcTemplate, you need DataSource as an input to JdbcTemplate, but DataSource is not required as a property in itself. So you can use DataSource Setter to initialize JdbcTempate by auto-wiring DataSource Setter. Please see the below code:
class DaoDemo{
//#Autowired
//private DataSource dataSource;
private JdbcTemplate jdbcTemplate;
#Autowired
public void setDataSource(DataSource dataSource){
//this.dataSource = dataSource;
this.jdbcTemplate = new JdbcTemplate(dataSource);
}
public int getTableRowCount(){
String sql = "SELECT COUNT(*) FROM DEMOTABLE";
//jdbcTemplate.setDataSource(dataSource); //No need to do this as its done in DataSource Setter now.
return jdbcTemplate.queryForObject(sql,Integer.class);
}
In the above code, the only use of dataSource was to get passed in JdbcTemplate. So, creating a property of dataSource doesn't make sense here. So, just use the #Autowired on setter method of DataSource bean to get its entry from spring.xml and make use of it at that particular time itself.
There are 3 types of autowiring:
Property based
#Autowired
private MyService service;
Constructor based. Note in Spring Boot you don't even need #Autowired annotation in this case:
class MyController {
private final MyService service;
public MyController(MyService service) {
this.service = service;
}
}
Setter based:
private MyService service;
#Autowired
public void setService(MyService service) {
this.service = service;
}
It is recommended to use Constructor based, then if not possible, Setter based and lastly Property based.
Why?
First, because in Constructor based you don't even use any Spring annotations. This helps you transition to different frameworks.
Second, Constructor or Setter based, make unit testing much easier. You don't need to use any Spring specific testing tools and you can only use Junit and Mockito.
Third, Constructor based is good because you can declare the property as final and not expose setters which helps with immutability and thread safety of the class.
Autowiring works best when it is used consistently across a project. If autowiring is not used in general, it might be confusing to developers to use it to wire only one or two bean definitions. With #Autowired on a field you don't need a setter method, which, on one hand makes the class smaller and easier to read, but on the other hand makes mocking the class a bit uglier.
Explicit dependencies in property and constructor-arg settings always override autowiring. You cannot autowire so-called simple properties such as primitives, Strings, and Classes (and arrays of such simple properties). This limitation is by-design.
Autowiring is less exact than explicit wiring. Spring is careful to avoid guessing in case of ambiguity that might have unexpected results, the relationships between your Spring-managed objects are no longer documented explicitly.
Wiring information may not be available to tools that may generate documentation from a Spring container.
Multiple bean definitions within the container may match the type specified by the setter method or constructor argument to be autowired. For arrays, collections, or Maps, this is not necessarily a problem. However for dependencies that expect a single value, this ambiguity is not arbitrarily resolved. If no unique bean definition is available, an exception is thrown.
If you can, you should avoid the setter. If you don't need it, it's better when it doesn't exists, right?
I personally prefer Guice allowing me to write
public class TextEditor {
private final SpellChecker spellChecker;
#Inject public TextEditor(SpellChecker spellChecker) {
this.spellChecker = spellChecker;
}
public void spellCheck(){
spellChecker.checkSpelling();
}
}
This goes a step further: With a final field, I know it won't ever change and I get the multithreading visibility guarantee.
There is one case where using #Autowired on an OPTIONAL property would not work.
If you want to do some initialization using that property, it might not be set before the constructor is called, and since it is optional, you cannot put it as an argument in the constructor.
In that case it is better to use an #Autowired setter method, so you can perform the initialization once the property is autowired.

Weld #Inject ApplicationScope bean creates new instance in every inject point

I'm trying to understand CDI using Weld. Got the next structure:
#ApplicationScoped
public class MainFacade {
#Inject
private FooFacade fooFacade;
private static int ins=0;
public MainFacade() {
super();
ins++;
System.out.println("MainFacade instance = "+ins);
}
public FooFacade getFooFacade() {
return fooFacade;
}
}
Where FooFacade is also #ApplicationScope.
When app is starting I've get a MainFacade instance = 1. When I inject it in other class (GWT RPC servlet) and call mainFacade.getFooFacade() then new instance of MainFacade are created along with a new instance of fooFacade.
Thought that Weld would return me the same instance of application scope bean anywhere I inject it. What I'm doing wrong?
I don't think this test will work well to verify that an application scoped bean is really a "singleton".
If you inject this bean into other beans, Weld will create a proxy which will handle the delegation of all invocations to the correct instance. This is important especially if you inject request scoped bean into session scoped beans for example.
The proxy will basically extend MainFacade which is required because otherwise the proxy cannot be injected into the fields where the injection is happening. When creating an instance of the proxy, the default constructor of you bean will be executed. As Weld will create many proxies, you are seeing multiple logs to the console. You could verify this by adding something like this to your constructor:
System.out.println("Type: "+this.getClass().getName());
When you use #ApplicationScoped Weld creates a proxy that calls constructor too, specification here.

Losing Class Custom Annotation For Proxy Classes

I am using Seam to inject beans to my controller using #In annotation. The injected class has a custom annotation, when calling injectedClass.getClass().getAnnotation(annotationClass) it returns null.
When debug I found that Seam passes a proxy instance so getClass() returns InjectedClass_$$_javassist_seam_5 which doesn't have my custom annotation.
How I can get my custom annotation from the proxy class?
Here's how my classes look like:
#CustomAnnotation(value="myvalue")
#Name("myAnnotatedClass")
public class MyAnnotatedClass extends SuperClass {...}
#Scope(ScopeType.SESSION)
#Name("myController")
public class MyController {
#In("#{myAnnotatedClass}")
private MyAnnotatedClass myAnnotatedClass;
public void actionMethod(){
//call another class which call myAnnotatedClass.getClass().getAnnotation(CustomAnnotation.class)
//then do some reflection for MyAnnotatedClass fields
}
}
Good question.
When you call a method by using Seam, it is intercepted by a proxy. And this one enables #In or #Out-jection. But There is an exception to this rule: it does not work when you call an internal method
So try this code
#Name
public class Service {
#In
private MyAnnotatedClass myAnnotatedClass;
public void myInterceptedMethod() {
// internal method bypass interceptor
// So #In or #Out-jection is not enabled
internalMethod();
}
private void internalMethod() {
System.out.println(myAnnotatedClass.getClass().getAnnotation(annotationClass));
}
}
Added to original answer
You want to retrieve an annotation from your bean. But, because of method interceptor, myAnnotatedClass.getClass() returns a proxy object, not the bean class itself.
For each bean class, Seam creates a Component definition, in which is stored in the application context. The name of the attribute follows this pattern: component name plus .component. So if you have a bean like this one
#Name("myBean")
public class MyBean {
}
Its Componet definition is stored in the attribute myBean.component
So inside your method, you can use
Component myBeanComponentDefinition = (Component) Context.getApplicationContext().get("myBean.component");
Now you can call
myBeanComponentDefinition.getBeanClass().getAnnotation(CustomAnnotation.class);
regards,
If you want less "ComponentDefinition" overbloat, you could also use this which also works for CDI and Spring:
Class.forName(myBean.getClass().getCanonicalName().substring(0,myBean.getClass().getCanonicalName().indexOf("$"))).getAnnotation(MyAnnotation.class)

Categories

Resources