Spring MongoDB和Apache Shiro

我试图使用Apache Shiro与Spring和MongoDB。 我正在使用自动assembly的Spring Data Repositories。 我为Shiro创建了自己的自定义域,它使用Spring Data存储库与Mongo交谈:

public class PlatformRealm extends AuthorizingRealm { @Autowired(required = true) protected UserRepository userRepository = null; @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { ... } } 

我看到的问题是userRepository没有自动assembly。 我在控制台输出中得到以下行,引用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 Shiro ShiroFilterFactoryBean。 发生了什么事情是这个bean及其所有依赖项在容器启动时立即被加载。 在解析依赖项之前,它不会等待我的持久性bean被初始化。 这会导致存储库引用为null。

通过contextConfigLocation参数加载以下bean配置:

  contextConfigLocation  /WEB-INF/web-platform-persistence.xml, /WEB-INF/web-platform-services.xml   

服务bean配置:

           <!--      -->   # some example chain definitions: /admin/** = passThruFilter, roles[admin] /** = passThruFilter         <!--  -->          

持久性bean配置:

           

用户存储库:

 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 { /** * Gets a user by the specified login. * @param login * @return */ User getByLogin(String login); } 

我的问题是,如何正确解析userRepository依赖关系? 我知道ShiroFilterFactoryBean必须在其他依赖项和诸如此类之前初始化,但必须有一种方法来解析userRepository依赖项。

编辑:添加了用户存储库代码。

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

  1. 来自dispacher-servlet.xml由于在基本包级别定义的组件扫描而加载@Service @Repository类,因此我可以@Autowire Service类进入Controller。
  2. 来自应用程序上下文似乎没有将@Autowire类标记为@Service,因为它们未加载。

如果我理解正确,你应该能够创建一个实现org.springframework.beans.factory.InitializingBeanShiroFilterFactoryBean的子类。 在InitializingBean.afterPropertiesSet()您将添加一些获取UserRepository并将其设置为该字段的代码。 不是最优雅的解决方案,但这看起来像一个特例。

我也遇到过这个问题。 它与Spring容器中bean初始化的顺序有关。 解决方法不是自动assembly存储库,而是让您的领域实现ApplicationContextAware并直接从上下文获取所需的bean。 它不优雅,但它会起作用。

我不太确定这是否有用,但您可以向我查看这个问题以寻找替代解决方案。

但是,核心问题可能仍然存在。

从ShiroFilterFactoryBean-and-a-spring-data-mongodb-realm获取的具体问题解释:

问题是spring-data-mongodb需要一个Spring ApplicationEventMulticaster在它可以使用之前已经初始化。

ShiroFilterFactoryBean是一个beanPostProcessor,因此,在初始化期间,spring尝试配置它的领域(因此我的领域和spring数据mongo基于userDao)。 它失败,因为还没有创建ApplicationEventMulticaster。

在我尝试了几种建议的方法来解决这个问题之后,比如InitializingBeanApplicationContextAwareBeanPostProcessor接口(每个都导致过早的调用,因此在初始化我必要的服务/存储库之前),我提出了以下解决方案:

  1. 让spring创建你的shiro上下文,而不需要对服务/存储库进行任何自动bean解析。
  2. 让spring创建您的服务/存储库上下文,包括mongodb
  3. 创建一个简单的类,它将处理你的shiro-service耦合并在spring配置中相应地配置它。 在成功设置shiro和服务上下文后,将调用此类。

至(1),某事。 像这样:

           /> 

至(2),某事。 像这样:

  ...   

至(3):

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

优点:

  • 它适用于xD
  • 没有额外的负担/依赖你的shiro东西
  • 完整的弹簧配置和设置,在初始化后产生一致的状态

坏处:

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

ShiroFilterFactoryBean实现了BeanPostProcessor,因为它依赖于安全管理器w /它自己对数据存储,数据访问对象等的依赖性,它可能导致一大堆Y类型Bean X没有资格被所有人处理BeanPostProcessors消息。

最糟糕的是,它似乎只是一种方式来查看Spring实例化的Filter实现,以便跟踪并可能将属性注入AuthorizationFilters。

坦率地说,我不需要为filter跟踪而头疼,所以我创建了一个不包含BeanPostProcessor的自定义版本。 我现在被迫手动将Filter实现连接到bean“filters”属性,但至少我不必处理该错误以及我的安全管理器和相关bean的可疑状态。