Reputation: 8030
I'm reading the JavaBean specification but I can't find a sentence where it clearly states that a bean must have a default constructor. So does it or doesn't?
Upvotes: 7
Views: 11885
Reputation: 10246
You can look at the wikipedia about java bean:
https://en.wikipedia.org/wiki/JavaBeans
The bean should have a public default constructor is one of the rules for it qualifying as a JavaBean. However, this is not explicitly defined by the standard, but is a good practice adopted by many frameworks.
EDIT: If we were to elaborate about the reasons WHY a non-args constructor is desired (but generally not enforced), below is one of the reasons:
CDI frameworks generally have two way of injecting dependencies in your bean:
Constructor injection: Where you have defined explicitly the dependencies of your bean in its constructor. Example (Spring):
@Component
public class SuchBean {
private MuchDependency muchDependency;
@Autowired
public SuchBean(MuchDependency muchDependency){
this.muchDependency = muchDependency;
}
}
Setter/Reflection injection: Where you haven't necessarily injected any dependencies through the constructor, but the dependencies are injected by the CDI environment by either using reflection or the setters. Example:
@Component
public class SuchBean {
// this dep doesn't have a setter, so the CDI will use reflection to set it
@Autowired private MuchDependencyWithReflection muchDependencyWithReflection;
// this dep has a setter so the CDI will use the setter to set it
@Autowired private MuchDependencyWithSetter muchDependencyWithSetter;
public void setMuchDependencyWithSetter(MuchDependencyWithSetter muchDependencyWithSetter){
this.muchDependencyWithSetter = muchDependencyWithSetter;
}
}
In the above example, if you haven't explicitly defined the no-args constructor, of course, you know, Java provides it for you (cause every class that doesn't have any constructor explicitly defined, just has an automatically provided no-args constructor). So everything would be fine and dandy until you decide to define your own constructor with args:
@Component
public class SuchBean {
// this dep doesn't have a setter, so the CDI will use reflection to set it
@Autowired private MuchDependencyWithReflection muchDependencyWithReflection;
// this dep has a setter so the CDI will use the setter to set it
@Autowired private MuchDependencyWithSetter muchDependencyWithSetter;
public SuchBean(String nonDefaultConstuctorArg){
System.out.println(nonDefaultConstuctorArg);
}
public void setMuchDependencyWithSetter(MuchDependencyWithSetter muchDependencyWithSetter){
this.muchDependencyWithSetter = muchDependencyWithSetter;
}
}
In the above example it is not obvious, but any dependency framework would complain and won't be able to instantiate it, because in fact, when you are using reflection/setter injection, the framework does:
Constructor.newInstance();
behind the scenes AND then injects the dependencies. However, since you just made your class not have a default constructor, newInstance() without args wouldn't work. Hence, you need a default args constructor in this case. To summarize:
Upvotes: 12
Reputation: 33000
A bean does not need to have a default constructor. Simply because the spec does not define that requirement.
Additionally chapter 10.3 Instantiating a bean talks about obtaining bean instances:
A bean can be delivered as either a serialized template (which must be deserialized to create an instance of the bean) or as an implementation class (where a bean instance is created simply by creating an instance of the class).
This strategy is implemented by Beans.instantiate
: It looks for a serialized bean (a special named Java resource). If it doesn't find one it tries to instantiate the bean via Class.newInstance
. But this mechanism clearly shows that the spec writers thought about providing a generic method to get bean instances which do not have a default constructor.
Upvotes: 3
Reputation: 118
Don't need it (some refection framework required), but is a good practice
Upvotes: 1