2014-01-09 1 views
0

у меня есть (в минималистском варианте) следующие КДИ управляемые компоненты в JBoss EAP 6.0.1Ошибка в частном секторе доступа CDI впрыскивается внешний класс от статического внутреннего класса

@ApplicationScoped 
public class Outer { 
    private final List<String> values = new ArrayList<String>(); 

    public void printValues() { 
     System.out.println("Values: " + values); 
    } 

    private void addValue(String value) { 
     values.add(value); 
    } 

    public static class Inner { 

     @Inject 
     private Outer outer; 

     public void addFoo() { 
      outer.addValue("foo"); 
     } 
    } 
} 

А следующий код, чтобы проверить это (не вопрос, почему это только для этой витрины)..

@Inject 
Outer outer; 

@Inject 
Outer.Inner inner; 

public void test() { 
    inner.addFoo(); 
    outer.printValues(); 
} 

я получаю выход:

Values: {} 

ш здесь я бы ожидал значения foo.

Дальнейшее исследование показало, что призыв к private void addValue обращается к версии атрибута values, который живет в Weld сгенерированного прокси из Outer в то время как призыв к public void printValues обращается реальный атрибут экземпляра реального управляемого компонента.

Чтобы сделать вещи еще более запутанной: Если изменить уровень доступа addValue к одному из package, protected или public все работает, как ожидалось.

Но цель внутреннего класса в моем случае состояла в том, чтобы облегчить метод, чтобы быть приватным, чтобы другие клиенты CDI Outer не могли вызвать метод. И теперь это единственное, что не работает: D

Любая идея, что не так? Это ошибка в Weld?

ответ

1

В настоящее время все провайдеры CDI используют прокси-серверы (это не требуется спецификацией, но это то, как все три имплантата были выполнены) для инъекции любых объектов, не содержащих псевдообъектов. Если Outer был @DependantScoped, я уверен, что он будет работать так, как вы этого хотите. Созданные прокси представляют собой естественные подклассы ваших классов, поэтому вызов частного метода на инъецируемый объект не будет работать. Честно говоря, я удивлен, что он не взорвется.

+0

После дальнейшего чтения, я думаю, объяснение поведения лежит где-то в способе создания Java и использует синтетические методы доступа для доступа внутренних классов к частным членам внешнего класса. – Gandalf

Смежные вопросы