У меня есть следующий код для управления двумя типами репозиториев. Оба класса репозитория наследуют интерфейс, позволяющий повторно инициализировать свои ресурсы.
public interface CachingRepository
{
public void invalidateCache();
}
Глобальный репозиторий на уровне приложения:
@Named("globalRepo")
@ApplicationScoped
public class GlobalRepository implements CachingRepository
{
private List<Category> categories;
...
@Override
public void invalidateCache()
{
categories = null;
}
...
}
Для каждого пользователя, репозиторий на уровне сеанса:
@Named("userRepo")
@SessionScoped
//@Stateful // <- NOTE HERE
public class UserRepository implements CachingRepository, Serializable
{
private List<MyFile> files;
@Override
public void invalidateCache()
{
files = null;
}
...
}
При вставке этого (без @Stateful
) в контекст
@Named
@ViewScoped
public class MyHandler implements Serializable
{
@Inject
private UserRepository userRepo;
...
}
оно работает. Однако при добавлении @Stateful
в класс UserRepository
развертывание завершается с ошибкой с сообщением об исключении:
Caused by: org.jboss.weld.exceptions.DeploymentException: WELD-001408 Unsatisfied dependencies for type [UserRepository] with qualifiers [@Default] at injection point [[field] @Inject private de.company.project.pack.MyHandler.userRepo]
at org.jboss.weld.bootstrap.Validator.validateInjectionPoint(Validator.java:275)
at org.jboss.weld.bootstrap.Validator.validateInjectionPoint(Validator.java:244)
at org.jboss.weld.bootstrap.Validator.validateBean(Validator.java:107)
at org.jboss.weld.bootstrap.Validator.validateRIBean(Validator.java:127)
at org.jboss.weld.bootstrap.Validator.validateBeans(Validator.java:346)
at org.jboss.weld.bootstrap.Validator.validateDeployment(Validator.java:331)
at org.jboss.weld.bootstrap.WeldBootstrap.validateBeans(WeldBootstrap.java:366)
at org.jboss.as.weld.WeldContainer.start(WeldContainer.java:83)
at org.jboss.as.weld.services.WeldService.start(WeldService.java:76)
... 5 more
Добавление имени компонента CDI, например
@Inject @Named("userRepo")
private UserRepository userRepo;
приводит к тому же исключению. Единственное, что работает в связке с @Stateful
, это использование интерфейса в объявлении var:
@Inject @Named("userRepo")
private CachingRepository userRepo;
Однако здесь мне может понадобиться функциональность подкласса, поэтому использование CachingRepository
на самом деле не желательно (на данный момент).
Вопросы:
- Почему это не работает, как ожидалось? Переменная
UserRepository
уже должна указывать, какой класс создавать, не так ли? Какая в этом логика? - Почему аннотация
@Stateful
EJB имеет здесь такие серьезные последствия? Почему это по существу вынуждает меня использовать интерфейсCachingRepository
в объявлении var?
Примечание. Я использую Seam 3 Faces, превращая @ViewScoped
в bean-компонент CDI с областью видимости, поэтому проблема, скорее всего, по-прежнему только для CDI.
@Named
тогда и только тогда, когда вам нужен JSF-доступ для управляемого компонента CDI? Все, что он делает, это предоставляет квалифицированное EL-имя, он не создает pojo для управляемого компонента CDI (это "сделано" beans.xml)... - person jan groth   schedule 27.04.2012