昨天晚上看spring In Action这本书,说spring会调用默认的构造函数来生成bean实例,如果该默认的构造函数为私有的时候,我们可以指定factory-method来生成实例。我试了一下,下面是代码public class SubBean {
private static SubBean instance = null; private SubBean() {
System.out.println("this is private constructor");
} public static synchronized SubBean getInstance() {
if (instance == null) {
instance = new SubBean();
}
return instance;
}
}在配置文件中这么定义的bean,bean定义为prototype类型的 <bean id="subBean" class="test.SubBean" scope="prototype"></bean>这个事测试类public class Test {
public static void main(String[] args) {
ApplicationContext context = new FileSystemXmlApplicationContext(
"D:/workspace/flex/opview/src/main/java/test/application.xml");
SubBean bean = (SubBean) context.getBean("subBean");
SubBean bean1 = (SubBean) context.getBean("subBean");
System.out.println(bean == bean1); }
}subBean是一个单例,但是打印出来的结果是
this is private constructor
this is private constructor
this is private constructor
false
false说明bean和bean1不是指向同一个对象的,而且私有的构造方法也被调用了
如果xml文件中给bean加一个factory-method="getInstance"属性,那么打印出来的结果就是true
private static SubBean instance = null; private SubBean() {
System.out.println("this is private constructor");
} public static synchronized SubBean getInstance() {
if (instance == null) {
instance = new SubBean();
}
return instance;
}
}在配置文件中这么定义的bean,bean定义为prototype类型的 <bean id="subBean" class="test.SubBean" scope="prototype"></bean>这个事测试类public class Test {
public static void main(String[] args) {
ApplicationContext context = new FileSystemXmlApplicationContext(
"D:/workspace/flex/opview/src/main/java/test/application.xml");
SubBean bean = (SubBean) context.getBean("subBean");
SubBean bean1 = (SubBean) context.getBean("subBean");
System.out.println(bean == bean1); }
}subBean是一个单例,但是打印出来的结果是
this is private constructor
this is private constructor
this is private constructor
false
false说明bean和bean1不是指向同一个对象的,而且私有的构造方法也被调用了
如果xml文件中给bean加一个factory-method="getInstance"属性,那么打印出来的结果就是true
解决方案 »
- hibernate 上面的问题
- hibernate多对多级联添加问题...........................................................
- Fckeditor存入有格式的文本,读取出来的数据成了这样......55555
- 有关Dao使用单例是否会线程不安全的问题
- 对 Serializable 的疑问
- mysql(编码:latin1 )+jsp(编码:GBK)页面显示乱码,求解?
- 我把Eclipse配制好,譬如字体大小,关键字,注释的颜色等,当我新建别的工作区后,设置全部变成原来的,怎么解决啊?
- 请教如何将'号替换成"号 反过来"号替换成'号 谢谢
- 请问如何用J2EE里的类???????????
- 中文问题
- 不能正确读XML文件,请教
- 关于spring配置文件中bean的id的问题
singleton 在spring IOC容器中仅存在一个Bean实例,Bean以单实例的方式存在.
prototype 每次从容器中调用Bean时,都返回一个新的实例,即每次调用getBean()时,相当于执行new XxxBean()的操作.
request 每次HTTP请求都会创建一个新的Bean,该作用域仅适用于webApplicationContext环境.
session 同一个HTTP session共享一个Bean,不同HTTP session使用不同的Bean,该作用域仅适用于webApplicationContext环境.
globalSession 同一个全局session共享一个Bean,一般用于portlet应用环境,该作用域仅适用于webApplicationContext环境.
Class clazz = Class.forName("T");
Constructor cons = clazz.getDeclaredConstructor(null);
//set accessble to access private constructor
cons.setAccessible(true);
cons.newInstance(null);
只不过不建议你这么利用Spring而已。
因为既然你指定了构造函数为私有,说明你设计上有特殊考虑,不希望构造函数被直接调用,比如要准备某些静态资源、共享环境或其它事情,所以希望用工厂模式来做。然后你又借助Spring来绕开这些保护机制,那不是很容易搬起石头砸自己脚么?
public class Test {
private Test() {
}public int add(int param1, int param2) {
return param1 + param2;
}public String echo(String msg) {
return "echo:" + msg;
}public static void main(String[] args) throws Exception {
Class classType = Test.class;
Object invokeTester = classType.newInstance();
// 调用InvokeTester对象的add()方法
Method addMethod = classType.getMethod("add", new Class[] { int.class,
int.class });
Object result = addMethod.invoke(invokeTester, new Object[] {
new Integer(100), new Integer(200) });
System.out.println((Integer) result);
// 调用InvokeTester对象的echo()方法
Method echoMethod = classType.getMethod("echo",
new Class[] { String.class });
result = echoMethod.invoke(invokeTester, new Object[] { "Hello" });
System.out.println((String) result);
}
}