Репозиторий данных Spring JPA не найден, когда аннотации Apache Shiro включены весной

Вот в чем проблема.

У меня есть spring 3.0.5, использующий новый модуль репозитория DATA JPA (интерфейсы, расширяющие CrudRepository<T, ID extends Serializable>).

У меня есть Apache Shiro 1.1.0 в качестве решения для обеспечения безопасности моего приложения. Apache shiro настраивается в XML-файле определения bean-компонента spring следующим образом:

<bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>

<!-- Enable Shiro Annotations for Spring-configured beans.  Only run after -->
<!-- the lifecycleBeanProcessor has run: -->
<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" depends-on="lifecycleBeanPostProcessor"/>
<bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
    <property name="securityManager" ref="securityManager"/>
</bean> 

<!-- Define the realm you want to use to connect to your back-end security datasource: -->
<bean id="securityDAORealm" class="com.bilto.archiweb.security.SecurityDAORealm" />

<bean id="securityManager" class="org.apache.shiro.mgt.DefaultSecurityManager">
    <!-- Single realm app.  If you have multiple realms, use the 'realms' property instead. -->
    <property name="realm" ref="securityDAORealm"/>
</bean>

<!-- For simplest integration, so that all SecurityUtils.* methods work in all cases, -->
<!-- make the securityManager bean a static singleton.  DO NOT do this in web         -->
<!-- applications - see the 'Web Applications' section below instead.                 -->
<bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
    <property name="staticMethod" value="org.apache.shiro.SecurityUtils.setSecurityManager"/>
    <property name="arguments" ref="securityManager"/>
</bean> 

Обратите внимание, что мое приложение является автономным приложением, и эта конфигурация Apachoe Shiro отражает его.

Конфигурация для репозиториев spring jpa, а также стандартные конфигурации spring (сканирование аннотаций) настраиваются в других файлах, они не кажутся актуальными для этой проблемы, поэтому я не буду их печатать.

Мой класс SecurityDAORealm автоматически подключает CredentialsRepository в качестве интерфейса контроллера репозитория jpa (CredentialsRepository extends CrudRepository<T, ID extends Serializable>), который служит для доступа к базе данных, в которой хранятся учетные данные.

@Component
public class SecurityDAORealm extends AuthorizingRealm {

@Autowired
CredentialRepository credentialRepository;
...
}

Теперь о проблеме.

Когда настроено сканирование аннотаций Apache Shiro, автосвязанный bean-компонент типа CredentialsRepository не найден и, следовательно, не связан. Когда сканирование аннотаций отключено, переменная CredentialsRepository подключается автоматически, и все работает правильно.

Часть, которая позволяет обрабатывать аннотации Apache Shiro, это

    <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>

<!-- Enable Shiro Annotations for Spring-configured beans.  Only run after -->
<!-- the lifecycleBeanProcessor has run: -->
<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" depends-on="lifecycleBeanPostProcessor"/>
<bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
    <property name="securityManager" ref="securityManager"/>
</bean> 

Комментируя его центральный мир

<!-- <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" depends-on="lifecycleBeanPostProcessor"/> -->

Аннотации отключены, раскомментировав их, они снова включатся.

В качестве теста я попытался автоматически подключить простое pojo вместо моего CredentialsRepository, это хорошо работает в обоих случаях (аннотации вкл / выкл).

Я не вижу много пружинных внутренностей. Здесь может происходить то, что переменная CredentialsRepository не подключается автоматически, поскольку Spring не имеет возможности создать соответствующую реализацию (SimpleJpaRepository) на своем бэкэнде.

Обходной путь существует здесь просто путем автоматического подключения некоторого контроллера JPA «полного класса» вместо реализации интерфейса, управляемого пружиной.

Однако мне любопытно, является ли это ошибкой, которую необходимо исправить, или существует ли здесь какая-то дополнительная пружинная магия, которая может заставить ее работать также с интерфейсами данных Spring.


person Tomas Bilka    schedule 18.11.2011    source источник


Ответы (2)


Я столкнулся с той же проблемой.

Мой обходной путь - заставить securityManager зависеть от репозитория, который необходимо внедрить. Таким образом, в вашем случае:

<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"
  depends-on="userRepository">
    <property name="realm" ref="credentialRepository" />
</bean>
person Jan Marten    schedule 10.02.2012
comment
так как я интегрирую Широ в приложение, это сработало для модуля безопасности. Однако теперь я должен продолжить и сделать то же самое для всех моих @Service классов, потому что @Autowire с <jpa:scan ... не работает и вместо этого уходит в NPE. - person sunny; 28.06.2012
comment
Привет @LeovR, спасибо за вклад. Однако я немного смущен вашим предложением. во-первых, репозиторий Томаса Билки - это CredentialRepository, а Realm - SecurityDAORealm, поэтому я предполагаю (если я не ошибаюсь) решение его проблемы должно быть: depends on работает? - person black sensei; 10.10.2012

У меня была аналогичная ситуация с этим, я не использую shiro для обеспечения безопасности, но я использую Spring Security.

Когда я автоматически подключался, он не вводил правильно из-за того, что bean-компоненты безопасности Spring были инициализированы до сканирования компонентов для Spring-data @Repository. Поскольку безопасность Spring необходимо инициализировать при запуске контейнера, чтобы настроить фильтры сервлетов и тому подобное, мне пришлось подключить свои репозитории до безопасности Spring, чтобы обеспечить правильное внедрение.

Знайте, что это не совсем ваша ситуация, но, возможно, это поможет!

Кроме того, самая запутанная часть и то, что привело меня к моему решению проблемы, я настроил модульный тест, который @Autowired UserDetailsService, в который был внедрен репозиторий, и модульный тест работал нормально. Привел меня к мысли, что это была проблема с заказом из-за того, как устанавливались bean-компоненты.

person dardo    schedule 11.01.2012
comment
Я думаю, вы правы с безопасностью, порядком создания экземпляров репозитория, то есть сиро создается до того, как происходит сканирование репозитория. - person Tomas Bilka; 16.02.2012