zoukankan      html  css  js  c++  java
  • spring容器与java访问权限的关系!

    java中的访问控制权限有:

    public:无限制 任何人都能访问

    protected:只允许在本类中相互调用,还可以由基于父类的子类来调用(即子类可以调用父类中的protected定义的参数或者方法)

    默认:默认的权限为同包类调用(即com.xx能调用com包下的其他类,属性和方法,但没法调用com.demo.xx下由默认权限定义的类或者属性或者方法)

    private:私有权限,只能在本类中相互调用,不对外开放

    public class Dem {
    
        private Dem () {}
        
        public static Dem dem () {
            return new Dem();
        }
    }

    可以将构造方法定义为私有方法,可以控制对象的创建。通过静态方法dem()来创建对象,这样可以防止该类被继承(由于继承的子类会优先调用父类的构造方法).

    稍微了解了java的权限控制之后来,突然发现一个问题:

    spring容器是通过类的构造方法或者set方法等方式将bean注入到容器中的,那么如果将这些方法都设置为private私有的情况下,spring还能正常的创建对象并存到容器中嘛?

    答案是可以的。

    自己写了一个简单的测试Demo 将一个类的构造方法定义为private私有的,然后通过@component注解在容器初始化的时候正常被扫描到

    发现容器中存在这个bean的对象,说明被正常的创建了。明明是私有的构造方法却能被正常创建。

    原因在于Spring源码中的反射无视了java的权限控制。

    fields[i].setAccessible(true);  
    
    public void setAccessible(boolean flag) throws SecurityException {  
        SecurityManager sm = System.getSecurityManager();  
      //根据是否设置了系统的安全性来获得访问private的权限
    if (sm != null) sm.checkPermission(ACCESS_PERMISSION); setAccessible0(this, flag); } //当前定义的唯一名称是suppressAccessChecks,它允许取消由反射对象在其使用点上执行的标准 Java 语言访问检查 - 对于 public、default(包)访问、protected、private 成员。 static final private java.security.Permission ACCESS_PERMISSION = new ReflectPermission("suppressAccessChecks");

    反射在初始化需要的实例时就设置了System.setSecurityManager 系统安全性。

    所以当spring在初始话容器的时候通过反射来创建bean的时候其实是忽略了访问权限的限制的!

  • 相关阅读:
    ubuntu远程windows桌面
    spring boot 给返回值加状态 BaseData
    spring boot 拦截异常 统一处理
    IntelliJ IDEA spring boot 远程Ddbug调试
    IntelliJ IDEA 常用插件
    spring boot 请求地址带有.json 兼容处理
    spring boot 接口返回值去掉为null的字段
    spring boot 集成disconf
    Spring boot 自定义拦截器
    Linux下安装MySQL
  • 原文地址:https://www.cnblogs.com/culushitai/p/9044790.html
Copyright © 2011-2022 走看看