【解决】SpringMVC整合Shiro之 Error creating bean with name 'shiroFilter' defined in class path resource...

时间:2021-07-02 08:56:20

完整的部分错误日志:

org.springframework.beans.factory.BeanCreationException: 

Error creating bean with name 'shiroFilter' defined in class path resource [spring_mvc_shiro.xml]: Cannot resolve reference to bean 'securityManager' while setting bean property 'securityManager';

Could not autowire field: private com.guide.user.service.UserService com.guide.web.controller.UserRealm.userService;

No qualifying bean of type [com.guide.user.service.UserService] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}

spring_mvc_shiro.xml

<bean id="credentialsMatcher" class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">
<property name="hashAlgorithmName" value="md5"></property>
<property name="hashIterations" value="2"></property>
<property name="storedCredentialsHexEncoded" value="true"></property>
</bean>

<!-- 缓存管理 -->
<bean id="cacheManager" class="org.apache.shiro.cache.MemoryConstrainedCacheManager"></bean>


<bean id="userRealm" class="com.guide.web.controller.UserRealm">
<property name="credentialsMatcher" ref="credentialsMatcher"></property>
</bean>


<!-- Shiro安全管理器 -->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<property name="realm" ref="userRealm"></property>
<!-- <property name="cacheManager" ref="cacheManager"></property> -->
</bean>


<!--
Shiro主过滤器本身功能十分强大,其强大之处就在于它支持任何基于URL路径表达式的、自定义的过滤器的执行
Web应用中,Shiro可控制的Web请求必须经过Shiro主过滤器的拦截,Shiro对基于Spring的Web应用提供了完美的支持
-->

<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<!-- Shiro的核心安全接口,这个属性是必须的 -->
<property name="securityManager" ref="securityManager"></property>
<!-- 要求登录时的链接(登录页面地址),非必须的属性,默认会自动寻找Web工程根目录下的"/login.jsp"页面 -->
<property name="loginUrl" value=""></property>
<!-- 登录成功后要跳转的连接(本例中此属性用不到,因为登录成功后的处理逻辑在LoginController里硬编码) -->
<!-- <property name="successUrl" value="https://www.baidu.com" ></property> -->
<!-- 用户访问未对其授权的资源时,所显示的连接 -->
<!-- <property name="unauthorizedUrl" value=""></property> -->
<property name="filterChainDefinitions">
<value>
/user/**=anon
/js/**=anon
/css**/=anon

</value>
</property>
</bean>

web.xml

<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath:spring_mybatis.xml,
classpath:spring_mvc_shiro.xml
</param-value>
</context-param>
...
<servlet>
<servlet-name>spring</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring_mvc.xml</param-value>
</init-param>

<!-- 设置执行的优先级 -->
<load-on-startup>1</load-on-startup>
</servlet>

UserRealm .java

public class UserRealm extends AuthorizingRealm {

@Autowired
private UserService userService;

@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
...

错误分析:

整合shiro之前程序正常启动,但是整合完之后出现问题,原因就是在项目启动加载web.xml的时候,<context-param>的执行顺序是在<servlet>之前的,但是呢,加载注入UserRealm的时候,再次注入UserService就会出现注入失败的情况,原因就是开启注解,扫描包的配置写在spring_mvc.xml中,也就是说我们在访问一个我们还没有注入到Spring容器的bean。所以出现异常。

解决办法是在加载shiro配置文件之前或者之中配置扫描包和开启自动注解。

对应的spring_mvc_shiro.xml文件中加入:

<mvc:annotation-driven />
<!-- 扫描的包 -->
<context:component-scan base-package="com.guide.*.service,com.guide.*.mapper" />

OK