【发布时间】:2011-11-07 10:38:57
【问题描述】:
在 Spring 中,bean 的类是否可能没有公共构造函数而只有私有构造函数? 创建 bean 时会调用这个私有构造函数吗? 谢谢。
【问题讨论】:
-
试一试然后发布结果如何?
-
这很难 - 我没有所有来源。
标签: java spring constructor javabeans private
在 Spring 中,bean 的类是否可能没有公共构造函数而只有私有构造函数? 创建 bean 时会调用这个私有构造函数吗? 谢谢。
【问题讨论】:
标签: java spring constructor javabeans private
是的,Spring 可以调用私有构造函数。如果它找到具有正确参数的构造函数,无论可见性如何,它将使用反射将其构造函数设置为可访问。
【讨论】:
您始终可以使用工厂方法来创建 bean,而不是依赖默认构造函数,来自 The IoC container: Instantiation using an instance factory method:
<!-- the factory bean, which contains a method called createInstance() -->
<bean id="serviceLocator" class="com.foo.DefaultServiceLocator">
<!-- inject any dependencies required by this locator bean -->
</bean>
<!-- the bean to be created via the factory bean -->
<bean id="exampleBean"
factory-bean="serviceLocator"
factory-method="createInstance"/>
这样做的好处是你可以为你的bean使用非默认构造函数,并且工厂方法bean的依赖也可以被注入。
【讨论】:
是的,私有构造函数由 spring 调用。 考虑我的代码:
Bean定义文件:
<bean id="message" class="com.aa.testp.Message">
<constructor-arg index="0" value="Hi Nice"/>
</bean>
豆类:
package com.aa.testp;
public class Message {
private String message;
private Message(String msg) {
// You may add your log or print statements to check execution or invocation
message = msg;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public void display() {
System.out.println(" Hi " + message);
}
}
上面的代码工作正常。因此,spring 调用了私有构造函数。
【讨论】:
是的! Spring 可以访问私有构造函数。 它将像下面的代码一样在内部工作。
try {
Class clazz = Class.forName("A"); // A - Fully qualified class name
Constructor constructor[] = clazz.getDeclaredConstructors();
constructor[0].setAccessible(true);
A a = (A) constructor[0].newInstance();
}
catch (Exception e) {
e.printStackTrace();
}
【讨论】:
您通常在此类 bean 中有一个静态工厂方法,您可以为 spring 指定该方法以获取该 bean 的实例。请参阅 3.3.1.3 here. 这是 Spring 推荐的方式,而不是违反可见性限制。
【讨论】:
Spring 永远不会将私有构造函数调用为 Bean 作用域。如果这样做会出现以下错误。
此问题的常见原因包括使用最终类或不可见类。嵌套异常是
java.lang.IllegalArgumentException:类中没有可见的构造函数。
【讨论】: