在 Spring 中,bean 的类是否可能没有公共构造函数而只有私有构造函数? 创建bean时会调用这个私有构造函数吗?
是的,Spring 可以调用私有构造函数。如果它找到具有正确参数的构造函数,无论可见性如何,它将使用反射将其构造函数设置为可访问。
您始终可以使用工厂方法来创建bean,而不是依赖于默认构造函数,来自IoC容器:使用实例工厂方法进行实例化:
<!-- 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>
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。 这是 Spring 推荐的方式,而不是违反可见性限制。
Spring 永远不会将私有构造函数作为 Bean 范围调用。如果这样做将会出现以下错误。
此问题的常见原因包括使用最终类或不可见类。嵌套异常是
java.lang.IllegalArgumentException:类中没有可见的构造函数。