【问题标题】:Spring data JPA repository not found when Apache Shiro annotations enabled in springSpring 中启用 Apache Shiro 注释时未找到 Spring 数据 JPA 存储库
【发布时间】:2011-12-31 22:18:23
【问题描述】:

这就是问题所在。

我有 spring 3.0.5,使用其新的 DATA JPA 存储库模块(接口扩展 CrudRepository<T, ID extends Serializable>)。

我有 Apache Shiro 1.1.0 作为我的应用程序的安全解决方案。 Apache shiro 已配置 在spring bean定义xml文件中如下:

<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&lt;T, ID extends Serializable&gt;),用于访问存储凭据的数据库。

@Component
public class SecurityDAORealm extends AuthorizingRealm {

@Autowired
CredentialRepository credentialRepository;
...
}

现在解决问题。

配置 Apache Shiro 注释扫描时,未找到 CredentialsRepository 类型的自动装配 bean,因此未装配。关闭注释扫描后,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 托管接口实现。

但是我很好奇这是否是一个需要修复的错误,或者这里是否存在一些额外的 spring 魔法可以使其也适用于 spring 数据接口。

【问题讨论】:

    标签: spring repository shiro


    【解决方案1】:

    我遇到了同样的问题。

    我的解决方法是让 securityManager 依赖于需要注入的存储库。因此,在您的情况下:

    <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"
      depends-on="userRepository">
        <property name="realm" ref="credentialRepository" />
    </bean>
    

    【讨论】:

    • 因为我将 shiro 集成到应用程序中,所以这适用于安全模块。但是现在我必须继续为我的所有@Service 课程做同样的事情,因为@Autowire&lt;jpa:scan ... 不起作用,而是留给NPE。
    • 您好@LeovR,感谢您的贡献。但是我对你的建议有点困惑。第一个是 Thomas Bilka 存储库是 CredentialRepository,Realm 是 SecurityDAORealm 所以我想(除非我弄错了)他的问题的解决方案应该是:&lt;bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager" depends-on="CreadentialRepository"&gt; &lt;property name="realm" ref="securityRealm" /&gt; &lt;/bean&gt; 现在我的困惑是存储库没有像 @ 一样在任何 applicationContext 中单独声明987654326@depends on 将如何工作?
    【解决方案2】:

    我也遇到过类似的情况,我不是用shiro做安全,而是用spring security。

    当我自动装配时,由于在组件扫描 spring-data @Repository 之前初始化了 spring 安全 bean,它没有正确注入。由于 spring security 需要在容器启动时初始化以设置 servlet 过滤器等,因此我必须在 spring security 之前连接我的存储库,以便进行正确的注入。

    知道这并不完全是你的情况,但也许它会有所帮助!

    另外,最令人困惑的部分,也是导致我解决问题的原因,我设置了一个单元测试,@Autowired UserDetailsS​​ervice 将存储库注入其中,并且单元测试运行良好。让我相信这是 bean 设置方式的排序问题。

    【讨论】:

    • 我认为您对“实例化”的安全性、存储库顺序是正确的,即 shiro 在存储库扫描发生之前被实例化
    猜你喜欢
    • 2018-08-27
    • 2011-10-15
    • 2015-06-19
    • 1970-01-01
    • 2018-06-05
    • 2021-03-05
    • 2017-05-26
    • 2020-09-09
    • 1970-01-01
    相关资源
    最近更新 更多