完整的部分错误日志:
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