前言
- 整合有缓存、事务的spring boot项目一切正常。
- 在该项目上整合shiro安全框架,发现部分类的缓存Cache不能正常使用。
- 然后发现该类的注解基本失效,包括事务Transaction注解。事务不能正常运行。
分析
- 注解失效的类,都是在shiro框架中(UserRealm)使用过@Autowire注入的类。
- 基本确定是shiro框架与spring框架的BeanFactory有所冲突,导致注入shiro框架的类不能被spring正确初始化。
参考
stackoverflow网站上的一些文章认为,Shiro框架初始化比Spring框架的某些部件早,导致使用@Autowire注入Shiro框架的某些类不能被Spring正确初始化。
解决方法
- 在Shiro框架中注入Bean时,不使用@Autowire,使用ApplicationContextRegister.getBean()方法,手动注入bean。保证该方法只有在程序完全启动运行时,才被注入。
- 使用@Autowire+@Lazy注解,设置注入到Shiro框架的Bean延时加载(即在第一次使用的时候加载)。
示例
1.Shiro中会出问题的代码
public class MyAuthRealm extends AuthorizingRealm {
//UserService中的注解可能会出现无效的情况
@Autowired
private UserService userService;
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
UsernamePasswordToken utoken = (UsernamePasswordToken) token;
String username = utoken.getUsername();
User user = userService.getUserByName(username);
return new SimpleAuthenticationInfo(user, user.getPassword(), this.getClass().getName());
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
2.手动注入bean
public class UserRealm extends AuthorizingRealm {
//该代码仅作手动注入bean的说明,前后略有省略代码
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection arg0) {
Long userId = ShiroUtils.getUserId();
//这里手动注入MenuService
MenuService menuService = ApplicationContextRegister.getBean(MenuService.class);
Set<String> perms = menuService.listPerms(userId);
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
info.setStringPermissions(perms);
return info;
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
3.延时加载(懒加载)
@Component(value = "myAuthRealm")
public class MyAuthRealm extends AuthorizingRealm {
//延时加载(懒加载)
@Autowired
@Lazy
private UserService userService;
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
UsernamePasswordToken utoken = (UsernamePasswordToken) token;
String username = utoken.getUsername();
User user = userService.getUserByName(username);
return new SimpleAuthenticationInfo(user, user.getPassword(), this.getClass().getName());
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构