0

在工作中有一个流程框架。它使用键和容器来设置参数,而不使用专用的构造函数(它基本上是类型安全的异构容器模式)。访问级别感知依赖注入到继承字段

我最近添加了依赖注入。 下面你找到一个代表性的例子(它缺少null检查,访问控制等)

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; 
    } 

有一个简单的和/或有效的方式来找出一个类是否是另一个类封闭?还是有另一种方法来确定我是否被允许注射?

回答

0

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

派生类是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将是一个有效的修饰符,因为嵌套类总是可以访问自己的字段。