【发布时间】:2011-07-22 18:48:13
【问题描述】:
这里是春季新手。
我观察到 Spring 能够实例化我定义的非公共类(即具有默认可见性的类)。谁能告诉我 Spring 是如何做到这一点的?为什么允许这样做?
【问题讨论】:
-
stackoverflow.com/questions/770635/… 似乎是一个相关的答案,涵盖了所涉及的一些核心技术。
标签: java spring class-visibility
这里是春季新手。
我观察到 Spring 能够实例化我定义的非公共类(即具有默认可见性的类)。谁能告诉我 Spring 是如何做到这一点的?为什么允许这样做?
【问题讨论】:
标签: java spring class-visibility
好的,这就是他们的做法。拿这个示例类:
package hidden;
class YouCantInstantiateMe{
private YouCantInstantiateMe(){
System.out.println("Damn, you did it!!!");
}
}
上面是一个包私有类,在不同的包中有一个私有构造函数,但我们仍然会实例化它:
代码(从不同包中的类运行):
public static void main(final String[] args) throws Exception{
Class<?> clazz = Class.forName("hidden.YouCantInstantiateMe");
// load class by name
Constructor<?> defaultConstructor = clazz.getDeclaredConstructor();
// getDeclaredConstructor(paramTypes) finds constructors with
// all visibility levels, we supply no param types to get the default
// constructor
defaultConstructor.setAccessible(true); // set visibility to public
defaultConstructor.newInstance(); // instantiate the class
}
输出:
该死,你做到了!!!
当然,Spring 所做的事情要复杂得多,因为它们也处理构造函数注入等,但这是实例化不可见类(或不可见构造函数)的方法。
【讨论】:
SecurityManager。没有一个,任何类都可以通过反射实例化,只要你知道类名
负责检查您(或 Spring)是否允许在运行时实例化类的人是 Security Manager 。如果您使用简单的主类运行,您可能根本没有它。如果您将应用程序配置为使用安全管理器运行,并且不授予 Spring 特殊权限,它将无法实例化非公共类。
【讨论】: