【问题标题】:Access level aware dependency injection into inherited field访问级别感知依赖注入到继承的字段
【发布时间】:2017-07-28 12:53:28
【问题描述】:

在工作中有一个流程框架。它使用键和容器来设置参数,而不使用专用的构造函数(它基本上是类型安全的异构容器模式)。

我最近添加了依赖注入。 下面是一个具有代表性的示例(它缺少一些空值检查、访问控制等)

  private static void inject(Process instance, Container c) throws Exception
  {
    Class<?> reference = instance.getClass();
    for (Field field : reference.getDeclaredFields())
    {
      Inject inject = field.getAnnotation(Inject.class);

      Key<Object> key = new Key<>(inject.key());
      field.set(instance, c.getObject(key));
    }
  }

该实现正在运行,但现在我需要对其进行增强以便也注入到继承的字段中。

检索类型层次结构和所有带注释的继承字段没有问题。但是为了符合Java,我不能注入到每个检索到的字段中。

仅当字段为:

  1. public
  2. protected
  3. package-privated 并在与 reference 具有相同包的类中声明
  4. private 并在包含 reference 的类中声明,该类必须是内部类(非静态嵌套类)。

项目 1 - 3 很容易检查。我对最后一项有困难。有没有优雅的解决方案?

我想使用 java.lang.Class.isMemberClass() 并比较类名。

目前我的支票是这样的

  private static boolean accessAllowed(Class<?> reference, Field field)
  {
    int modifiers = field.getModifiers();

    boolean hasAccess = Modifier.isPublic(modifiers);
    hasAccess |= Modifier.isProtected(modifiers);

    // TODO fix
    hasAccess |= Modifier.isPrivate(modifiers) /* add check as defined in 4. */;

    // no access and not private means field is package-private
    if (!hasAccess && !Modifier.isPrivate(modifiers))
      hasAccess = reference.getPackage().equals(field.getDeclaringClass().getPackage());

    return hasAccess;
  }

是否有一种简单和/或有效的方法来确定一个类是否被另一个类包围?或者有没有其他方法可以查明我是否可以注射?

【问题讨论】:

    标签: java inheritance reflection dependency-injection inversion-of-control


    【解决方案1】:

    以下解决方案应处理私人案例。

    派生类是reference,它尝试设置继承自fieldDeclaringClass的成员

      static boolean hasPrivateAccessRelation(Class<?> reference, Class<?> fieldDeclaringClass)
      {
        boolean isMemberClass = reference.isMemberClass();
        boolean isEnclosingClass = reference.getName().contains(fieldDeclaringClass.getName());
    
        // static nested classes can't access private members of enclosing class
        return isMemberClass && isEnclosingClass && !Modifier.isStatic(reference.getModifiers());
      }
    

    如果派生类是fieldDeclaringClass内部类,则代码有效。如果它是静态嵌套类,它会失败,因为它们无法访问封闭类的私有字段。

    需要事先检查以确保 referencefieldDeclaringClass 不相等。因为在那种情况下static 将是一个有效的修饰符,因为嵌套类总是可以访问它自己的字段。

    【讨论】:

      猜你喜欢
      • 2023-03-28
      • 2014-04-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-24
      • 2021-11-05
      • 2015-09-03
      相关资源
      最近更新 更多