Ошибка приватного доступа к внешнему классу, введенному CDI из статического внутреннего класса.

StackOverflow https://stackoverflow.com//questions/21029071

  •  21-12-2019
  •  | 
  •  

Вопрос

У меня есть (в минималистической версии) следующие управляемые компоненты CDI в JBoss EAP 6.0.1.

@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?

Это было полезно?

Решение

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top