【问题标题】:How is Spring BeanFactory able to instantiate a non-public class?Spring BeanFactory 如何能够实例化非公共类?
【发布时间】:2011-07-22 18:48:13
【问题描述】:

这里是春季新手。

我观察到 Spring 能够实例化我定义的非公共类(即具有默认可见性的类)。谁能告诉我 Spring 是如何做到这一点的?为什么允许这样做?

【问题讨论】:

标签: java spring class-visibility


【解决方案1】:

好的,这就是他们的做法。拿这个示例类:

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 所做的事情要复杂得多,因为它们也处理构造函数注入等,但这是实例化不可见类(或不可见构造函数)的方法。

【讨论】:

  • 谢谢。如果默认的 Java 行为(即没有反射)是防止从其他包访问非公共类,为什么 Spring 允许它?
  • 因为它们不是 Mockito
  • @krems ?能详细点吗?
  • @Sean Patrick Floyd ,我暗示 Mockito 小组拒绝使用反射,即提供模拟静态的能力,基于“这不是一个明确的方式”这一事实。这完全是为了遵循一个或另一个概念。
  • @atishshimpi 如果您不信任您的应用程序,请安装SecurityManager。没有一个,任何类都可以通过反射实例化,只要你知道类名
【解决方案2】:

负责检查您(或 Spring)是否允许在运行时实例化类的人是 Security Manager 。如果您使用简单的主类运行,您可能根本没有它。如果您将应用程序配置为使用安全管理器运行,并且不授予 Spring 特殊权限,它将无法实例化非公共类。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-10
    • 1970-01-01
    • 2018-12-29
    • 1970-01-01
    • 1970-01-01
    • 2019-06-24
    相关资源
    最近更新 更多