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

zer*_*uno 4 java javabeans

我正在阅读JavaBean规范,但我找不到一个句子,它明确指出bean必须有一个默认的构造函数.是这样或不是吗?

Nik*_*hev 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;
     }

}
Run Code Online (Sandbox Code Playgroud)

Setter/Reflection注入:你没有必要通过构造函数注入任何依赖项,但是依赖项是由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;
     }
}
Run Code Online (Sandbox Code Playgroud)

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

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

Constructor.newInstance();
Run Code Online (Sandbox Code Playgroud)

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

  • 如果使用构造函数注入,则不需要no-args构造函数.
  • 如果使用反射/设置器注入,则需要使用no-args构造函数.
  • 由于良好的代码应具有良好的约定,因此JavaBeans标准"轻推"您在任何地方都拥有默认的no-args构造函数,以获得一致的常规代码,该代码可在各种框架中使用,并且由于其标准化而可读/可理解/可维护.