春天的MongoDB和Apache四郎(Spring MongoDB and Apache Shir

2019-09-17 02:40发布

我试图使用Apache四郎与Spring和MongoDB。 我使用这些自动装配弹簧数据存储库。 我已经创建了四郎我自己定制的境界,它使用一个Spring数据仓库交谈蒙戈:

public class PlatformRealm extends AuthorizingRealm {

    @Autowired(required = true)
    protected UserRepository userRepository = null;

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
         ...
    }
}

我看到的问题是userRepository没有被自动装配。 我得到以下线在我的控制台输出指的是PlatformRealm:

INFO  org.springframework.web.context.support.XmlWebApplicationContext  - Bean 'platformRealm' of type [class com.resonance.platform.core.security.PlatformRealm] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)

这是因为Apache四郎ShiroFilterFactoryBean的。 正在发生的事情是这个bean及其全部附属的容器启动时被立即装起来。 它不会等待我的持久性Bean之前要解决的依赖初始化。 这将导致库引用为空。

下面bean配置经由contextConfigLocation的参数加载:

<context-param> 
    <param-name>contextConfigLocation</param-name> 
    <param-value>
        /WEB-INF/web-platform-persistence.xml,
        /WEB-INF/web-platform-services.xml
    </param-value> 
</context-param> 

服务bean的配置:

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/context
      http://www.springframework.org/schema/context/spring-context-3.0.xsd
      http://www.springframework.org/schema/beans
      http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
      http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd">

<bean id="userSession"
    class="com.resonance.platform.web.core.services.ShiroUserSessionService" />

<!-- Shiro (Security) -->
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
    <property name="securityManager" ref="securityManager" />
    <property name="loginUrl" value="/login" />
    <property name="successUrl" value="/" />
    <!-- The 'filters' property is not necessary since any declared javax.servlet.Filter 
        bean -->
    <!-- defined will be automatically acquired and available via its beanName 
        in chain -->
    <!-- definitions, but you can perform instance overrides or name aliases 
        here if you like: -->
    <!-- <property name="filters"> <util:map> <entry key="anAlias" value-ref="someFilter"/> 
        </util:map> </property> -->
    <property name="filterChainDefinitions">
        <value>
            # some example chain definitions:
            /admin/** = passThruFilter, roles[admin]
            /** = passThruFilter
        </value>
    </property>
</bean>

<bean id="passThruFilter"
    class="org.apache.shiro.web.filter.authc.PassThruAuthenticationFilter" />

<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
    <!-- Single realm app. If you have multiple realms, use the 'realms' property 
        instead. -->
    <property name="realm" ref="platformRealm" />
    <!-- By default the servlet container sessions will be used. Uncomment 
        this line to use shiro's native sessions (see the JavaDoc for more): -->
    <!-- <property name="sessionMode" value="native"/> -->
</bean>

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

<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 Shiro Realm implementation you want to use to connect to 
    your back-end -->
<!-- security datasource: -->
<bean id="platformRealm" class="com.resonance.platform.core.security.PlatformRealm" />

持久性豆配置:

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:mongo="http://www.springframework.org/schema/data/mongo"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/context
      http://www.springframework.org/schema/context/spring-context-3.0.xsd
      http://www.springframework.org/schema/data/mongo
      http://www.springframework.org/schema/data/mongo/spring-mongo-1.0.xsd
      http://www.springframework.org/schema/beans
      http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
      http://www.springframework.org/schema/util
      http://www.springframework.org/schema/util/spring-util-3.0.xsd">

<mongo:mongo id="mongo" />

<bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
    <constructor-arg ref="mongo" />
    <constructor-arg value="platform" />
    <property name="writeConcern">
        <util:constant static-field="com.mongodb.WriteConcern.SAFE" ></util:constant>
    </property>
</bean>

<mongo:repositories base-package="com.resonance.platform.core.data.repositories" />

用户系统信息库:

package com.resonance.platform.core.data.repositories;

import org.bson.types.ObjectId;
import org.springframework.data.repository.CrudRepository;

import com.resonance.platform.core.entities.User;

/**
 * A repository used to manage User entities.
 * @author Kyle
 */
public interface UserRepository extends CrudRepository<User, ObjectId> {

    /**
     * Gets a user by the specified login.
     * @param login
     * @return
     */
    User getByLogin(String login);

}

我的问题是,我怎么能得到userRepository依赖于妥善解决? 据我所知,ShiroFilterFactoryBean有其他依赖和诸如此类的东西之前进行初始化,但必须有一个办法让userRepository依赖得到解决。

编辑:添加的用户信息库的代码。

Answer 1:

我遇到了在这里所描述的同样的问题。 我注意到两个弹簧工厂。

  1. 从其中加载由于在一个基础包级别上定义,所以我可以@Autowire Service类到控制器组件扫描@Service @Repository类dispacher-servlet.xml中。
  2. 从应用程序上下文似乎并没有因为他们没有加载到@Autowire标记为@Service类。


Answer 2:

如果我理解你的权利,你应该能够创建的子类ShiroFilterFactoryBean它实现org.springframework.beans.factory.InitializingBean 。 在InitializingBean.afterPropertiesSet()你会再添加一些代码来获取UserRepository并将其设置到该字段。 没有最完美的解决方案,但是这看起来像一个特例。



Answer 3:

我有这个问题了。 它是与豆初始化在Spring容器中的顺序。 解决方法是不是自动装配仓库里面有你的境界实施了ApplicationContextAware,然后从上下文得到所需要的豆直。 这不是优雅,但它会工作。



Answer 4:

我也不太清楚,如果这是有帮助的,但你可以检查这个由我的问题的替代解决方案。

但是,核心的问题可能仍然保持开放。



Answer 5:

具体问题说明取自ShiroFilterFactoryBean -和- a -弹簧-数据的mongodb-境界 :

问题是弹簧数据mongodb的要求已被初始化的弹簧ApplicationEventMulticaster才能使用它。

ShiroFilterFactoryBean是BeanPostProcessor的,正因为如此,在初始化过程中,弹簧试图配置其领域(因此我的境界和弹簧数据MONGO基于userDAO的)。 因为ApplicationEventMulticaster尚未创建失败。

我已经尝试了几种建议的方式来解决这个问题,像后InitializingBeanApplicationContextAwareBeanPostProcessor (因此我的初始化必要的服务/资源库的东西之前,各导致过早的调用)接口,我想出了以下解决方案:

  1. 让春天创建四郎方面没有任何自动豆腐解决您的服务/资源库。
  2. 让春天创建服务/存储库的内容,包括MongoDB的
  3. 创建一个简单的类,它会照顾你四郎服务耦合的,在你的Spring配置相应的配置。 这个类将被调用后您的四郎和服务方面已经成功设立。

到(1),某事物。 像这样:

<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
    <property name="securityManager" ref="securityManager" />
    <property name="filterChainDefinitions">
        <value>
            <!-- Your definitions -->
        </value>
    </property>
</bean>

<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"
        p:realm-ref="myShiroRealm" />

<bean id="myShiroRealm" class="com.acme.MyShiroRealm" 
    <!--no bean refs here-->
/>

到(2),某事物。 像这样:

<bean id="myService" class="com.acme.MyService"
        c:myRepository-ref="myRepository" />

...

<!-- Ask Spring Data to scan our repositories -->
<mongo:repositories base-package="com.acme.repository.impl.mongodb" />

(3):

public class ShiroRealmServiceBridge {
    public static void postInject( MyShiroServerRealm realm, MyService service ) {
        realm.setService( service );
    }
}

<bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
    <property name="targetClass"><value>com.acme.ShiroRealmServiceBridge</value></property>
    <property name="targetMethod"><value>postInject</value></property>
    <property name="arguments">
    <list>
        <ref bean="myShiroRealm" />
        <ref bean="myService" />
    </list>
</property>

好处:

  • 它的工作原理的xD
  • 您四郎的东西没有额外的负担/依赖性
  • 完整的春天的配置和设置,从而导致初始化后一致的状态

坏处:

  • 一周时间开销设置
  • 可能导致不一致的状态,这会抱怨在运行时,而不是在启动时,如果忘记或碰撞胶水配置


Answer 6:

该ShiroFilterFactoryBean实现了BeanPostProcessor和,因为其对安全管理的依赖瓦特/数据存储,数据访问对象等等,自己的依赖可引起Y型的豆X的整体转换是没有资格给所有得到处理BeanPostProcessor的消息。

最糟糕的是,它似乎只是一个办法看到滤波器实现了Spring是为了跟踪和可能注入的属性分为AuthorizationFilters实例。

坦白说,我并不需要一个头痛只是滤波跟踪,所以我创建了一个定制版本,不包括了BeanPostProcessor。 现在我不得不手工丝过滤器实现对豆“过滤器”的属性,但至少我没有处理的错误,我的安全管理及相关豆的可疑状态。



文章来源: Spring MongoDB and Apache Shiro