Spring官方文档中的实例工厂问题

爪哇扫地僧 发布于 2013/03/14 01:32
阅读 398
收藏 0

看到spring官方文档中关于实例工厂方法那部分,如下:

上述的DefaultServiceLocator类,构造方法设为private,那么是不是代表,即使构造方法为private,spring也能正常创建实例?求解答。我知道private方法其实可以通过反射调用。那么是不是说明,spring在创建对象时,跳过了访问检查?求大牛解答.................

加载中
0
爱吃大肉包
爱吃大肉包

各位都在猜吧,呵呵!!上面楼主列出的这个例子是说明在spring中使用单例。

但是楼主的疑问是用了private还可以实例化这个对象,其实楼主疑问没有错误,在spring确实允许构造private为构造函数的bean!!!

先给出个例子,下面这个bean构造方法为private

package com.spring.service;

/**
 * @author hejinbin
 */
public class Test4CreateBean{

	private Test4CreateBean() {
		// TODO Auto-generated constructor stub
	}

	public void saySomethings(){
		System.out.println("test only");
	}



}
在spring中配置如下

<bean id="test4serviceCreateInstace"  class="com.spring.service.Test4CreateBean"></bean>
测试如下

@Test
	public void test4createInstance() throws InstantiationException, IllegalAccessException, ClassNotFoundException{
		ApplicationContext ctx=new ClassPathXmlApplicationContext("Application.xml");
		Test4CreateBean test4CreateBean = (Test4CreateBean) ctx.getBean("test4serviceCreateInstace");
		test4CreateBean.saySomethings();
	}
你会发现,no problems,完全可以调用,什么意识?以为着你的spring中完全你的private构造方法完全失效!!

其实翻开spring源码你就会发现,bean的最终创建是在类org.springframework.beans.BeanUtils中

/**
	 * Convenience method to instantiate a class using the given constructor.
	 * As this method doesn't try to load classes by name, it should avoid
	 * class-loading issues.
	 * <p>Note that this method tries to set the constructor accessible
	 * if given a non-accessible (that is, non-public) constructor.
	 * @param ctor the constructor to instantiate
	 * @param args the constructor arguments to apply
	 * @return the new instance
	 * @throws BeanInstantiationException if the bean cannot be instantiated
	 */
	public static <T> T instantiateClass(Constructor<T> ctor, Object... args) throws BeanInstantiationException {
		Assert.notNull(ctor, "Constructor must not be null");
		try {
			ReflectionUtils.makeAccessible(ctor);
			return ctor.newInstance(args);
		}
关键看这个
ReflectionUtils.makeAccessible(ctor);

这个方法如下

/**
	 * Make the given constructor accessible, explicitly setting it accessible
	 * if necessary. The <code>setAccessible(true)</code> method is only called
	 * when actually necessary, to avoid unnecessary conflicts with a JVM
	 * SecurityManager (if active).
	 * @param ctor the constructor to make accessible
	 * @see java.lang.reflect.Constructor#setAccessible
	 */
	public static void makeAccessible(Constructor<?> ctor) {
		if ((!Modifier.isPublic(ctor.getModifiers()) || !Modifier.isPublic(ctor.getDeclaringClass().getModifiers()))
				&& !ctor.isAccessible()) {
			ctor.setAccessible(true);
		}
	}
 

可以看到,不管是private还是其它,都被设置成了

ctor.setAccessible(true);



爪哇扫地僧
爪哇扫地僧
谢了,确实是这样。
0
逝水fox
逝水fox
你运行过吗?
0
JavaOlder
JavaOlder
上面就是一个单例模式创建。你所谓的访问检查是什么?
爪哇扫地僧
爪哇扫地僧
这不是单例,只是构造方法设置了为private,单例的话是有个静态返回方法,这里没有。以上的创建方法设置为private,就只能通过反射的方法创建,大家一起学习了,谢了。
0
申江渔夫
申江渔夫
LZ应该查一下单例模式的用法,就不会有这样的疑问了
0
polly
polly
工厂方法应该是static吧
返回顶部
顶部