Shiro解决无法注入Service问题(包括Spring MVC和Spring Boot)
问题原因:ShiroRelam属于filter即过滤器,它在Spring未完成注入bean之前就已经拦截了,因此无法注入。对于SpringBoot,没有将ShiroRealm注入Bean。 分析:spring加载时候,注入的bean 的顺序是 先是Lisener 然后是 Filter 最后是 Servlet因此如果在过滤器或者监听器里面注入service等会是空,因为在过...
问题原因:
ShiroRelam属于filter即过滤器,它在Spring未完成注入bean之前就已经拦截了,因此无法注入。- 对于SpringBoot,没有将
ShiroRealm注入Bean。
分析:spring加载时候,注入的bean 的顺序是 先是Lisener 然后是 Filter 最后是 Servlet
因此如果在过滤器或者监听器里面注入service等会是空,因为在过滤器或者监听器加载的时候
因此为了解决这个问题,现在要进行手动注入
参考链接:1. https://blog.csdn.net/yuanlaijike/article/details/79627836
2.https://blog.csdn.net/qiufengzh/article/details/80688790
3.https://blog.csdn.net/u010520146/article/details/74025411(推荐)
4.https://blog.csdn.net/fightingboyws/article/details/79158630(shiro实现权限管理时遇到的坑)
思路一:
下面代码是工具类,手动注入service,到此问题解决
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
/**
* spring加载时候,注入的bean 的顺序是 先是Lisener 然后是 Filter 最后是 Servlet
* 因此如果在过滤器或者监听器里面注入service等会是空,因为在过滤器或者监听器加载的时候
* Servlet,service等还没有加载,因此是空的,所以就手动注入
*
* Created by zhong.h on 2018/6/13/013.
*/
@Component
public class SpringBeanFactoryUtils implements ApplicationContextAware {
private static ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext)
throws BeansException {
if (SpringBeanFactoryUtils.applicationContext == null) {
SpringBeanFactoryUtils.applicationContext = applicationContext;
}
}
public static ApplicationContext getApplicationContext() {
return applicationContext;
}
//根据名称(@Resource 注解)
public static Object getBean(String name) {
return getApplicationContext().getBean(name);
}
//根据类型(@Autowired)
public static <T> T getBean(Class<T> clazz) {
return getApplicationContext().getBean(clazz);
}
public static <T> T getBean(String name, Class<T> clazz) {
return getApplicationContext().getBean(name, clazz);
}
}
思路二:
碰到此问题,一开始以为是springmvc注入配置问题,但是controller注入又都正常,此时陷入百思不得解。一项项跟踪,发现原来shiro 自定义realm的认证阶段属于filter,当时的spring bean还没有读取进来。
最后通过配置web.xml文件,把spring mvc的xml提高一点优先级,才最终解决了这个问题。下面是web.xml完整配置:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-mybatis.xml,classpath:dispatcher-servlet.xml,classpath:spring-shiro.xml</param-value>
</context-param>
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:dispatcher-servlet.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<!-- 设置拦截 !-->
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>log4jContextName</param-name>
<param-value>log4jContext</param-value>
</context-param>
<!-- 添加shiro的过滤器代理!-->
<filter>
<filter-name>shiroFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
<async-supported>true</async-supported>
<init-param>
<param-name>targetFilterLifecycle</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>shiroFilter</filter-name> <!-- 此处必需写成"/*",如果只写"/" ,过滤器没有作用-->
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
执行逻辑
1 、启动一个 WEB 项目的时候, WEB 容器会去读取它的配置文件 web.xml ,读取 <listener> 和 <context-param> 两个结点。
2 、紧急着,容创建一个 ServletContext ( servlet 上下文),这个 web 项目的所有部分都将共享这个上下文。
3 、容器将 <context-param> 转换为键值对,并交给 servletContext 。
4 、容器创建 <listener> 中的类实例,创建监听器。
web.xml 的加载顺序是: context-param -> listener -> filter -> servlet ,而同个类型之间的实际程序调用的时候的顺序是根据对应的 mapping 的顺序进行调用的。
更多推荐



所有评论(0)