Bean必须有默认构造函数吗?

时间:2016-05-11 20:18:35

标签: java javabeans

我正在阅读JavaBean specification,但我无法找到一个句子,其中明确指出bean必须具有默认构造函数。那么它还是没有?

3 个答案:

答案 0 :(得分:8)

您可以查看有关java bean的维基百科:

https://en.wikipedia.org/wiki/JavaBeans

bean应该有一个公共默认构造函数,它是符合JavaBean资格的规则之一。但是,标准没有明确定义,但这是许多框架采用的良好实践。

编辑:如果我们要详细说明为什么需要非args构造函数(但通常不强制执行),下面是其中一个原因:

CDI框架通常有两种方法在bean中注入依赖项:

构造函数注入:您已在其构造函数中明确定义了bean的依赖关系。示例(Spring):

@Component
public class SuchBean {
     private MuchDependency muchDependency;

     @Autowired
     public SuchBean(MuchDependency muchDependency){
         this.muchDependency = muchDependency;
     }

}

Setter / Reflection injection :你没有必要通过构造函数注入任何依赖项,但是依赖项是由CDI环境通过使用反射或setter注入的。示例:

@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;
     }
}

在上面的例子中,如果你没有明确定义no-args构造函数,当然,你知道,Java为你提供了它(导致每个没有明确定义任何构造函数的类,只是自动生成一个提供了no-args构造函数)。因此,在您决定使用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;
     }
}

在上面的示例中,它并不明显,但任何依赖框架都会抱怨并且无法实例化它,因为实际上,当您使用反射/设置器注入时,框架会执行:

Constructor.newInstance();

幕后然后注入依赖项。但是,由于您刚刚使您的类没有默认构造函数,因此不带args的newInstance()将无效。因此,在这种情况下,您需要一个默认的args构造函数。总结一下:

  • 如果使用构造函数注入,则不需要no-args构造函数。
  • 如果使用反射/设定器注入,则需要使用无参数 构造
  • 由于优秀的代码应具有良好的约定,因此JavaBeans标准 “轻推”你到处都有一个默认的no-args构造函数,以便拥有一个可以在各种框架中使用并且由于其标准化而可读/可理解/可维护的一致的传统代码。

答案 1 :(得分:1)

bean不需要具有默认构造函数。仅仅因为规范没有定义该要求。

另外一章 10.3实例化bean 讨论了获取bean实例:

  

bean可以作为序列化模板(必须是   反序列化以创建bean的实例)或作为   实现类(简单地通过创建bean实例)   创建类的实例。)

此策略由Beans.instantiate实现:它查找序列化bean(一种特殊的名为Java资源)。如果找不到,则尝试通过Class.newInstance实例化bean。但是这种机制清楚地表明规范编写者考虑提供一种泛型方法来获取没有默认构造函数的bean实例。

答案 2 :(得分:0)

不需要它(需要一些反思框架),但这是一个很好的做法