闲的无聊把以前写过的几个boot项目都转成了Kotlin,中间有一个小插曲弄得我有点炸
前奏:修改了ShiroConfiguration的部分代码
如果原先有@Bean(name="xxx")
直接用方法名即可(我原先的name
和方法名不一样就很尴尬)
@Bean
open fun securityManager(@Qualifier("myAuthRealm") myAuthRealm:MyRealm): SecurityManager {
val securityManager = DefaultWebSecurityManager()
securityManager.setRealm(myAuthRealm)
securityManager.cacheManager = cacheManager()
securityManager.sessionManager = sessionManager()
return securityManager
}
@Bean
open fun myAuthRealm(): MyRealm {
val myAuthorizingRealm = MyRealm()
myAuthorizingRealm.credentialsMatcher = hashedCredentialsMatcher()
return myAuthorizingRealm
}
hashedCredentialsMatcher
中的内容可以直接new
,所以不需要注入
/**
* 密码匹配凭证管理器
* @return
*/
@Bean
open fun hashedCredentialsMatcher(): HashedCredentialsMatcher {
val hashedCredentialsMatcher = HashedCredentialsMatcher()
hashedCredentialsMatcher.hashAlgorithmName = "MD5"
return hashedCredentialsMatcher
}
如果SpringBoot的版本从1.5.x
变成了2.0.x
,shiroDialect
或者shiroFilter
可能会报如下错误
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'shiroDialect' defined in class path resource
……
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [at.pollux.thymeleaf.shiro.dialect.ShiroDialect]: Factory method
……
Caused by: java.lang.NoClassDefFoundError: org/thymeleaf/processor/attr/AbstractTextChildModifierAttrProcessor
把thymeleaf-extras-shiro
的版本号改成2.0.0
即可(原先是1.2.1
)
<dependency>
<groupId>com.github.theborakompanioni</groupId>
<artifactId>thymeleaf-extras-shiro</artifactId>
<version>2.0.0</version>
</dependency>
然后炸的地方就来了
在SpringBoot
版本中,在Realm
中注入Service
时,为了启用缓存,需要在前面加上@Lazy
注解,如下
@Autowired
@Lazy
private UserRolesService userRolesService;
在Kotlin
版本中我不知道发了啥疯就把它去掉了(可能是看到前面类型是lateinit var
,自以为是的觉得可以代替@Lazy
),然后改成了改成如下形式
//@Lazy
@Autowired
lateinit var userRolesService: UserRolesService
然后就原地爆炸了。
拷贝完整个项目之后,测试功能的时候,发现缓存没了……然后就开始疯狂DEBUG,从版本问题,到jar
包冲突问题,经历了很漫长的一段时间后,我定位到了ShiroConfiguration
,只要把shiro aop
注解关闭就可以开启缓存了
WHAT??
疯狂谷歌一个小时无果(因为一直以为是Kotlin
不兼容啥的,或者是shiro
在boot2.x
之后需要修改相应的配置)
然后又疯狂DEBUG,把Kotlin
版和springboot
版进行对比,最后。定位到了@Lazy
(还好只是改成了注释,没把它给直接删了)
果然。加了@Lazy
,整个天都亮了
总结一下
-
lateinit
是Kotlin
中的延迟初始化的实现,别想太多 - 从
SpringBoot
到Kotlin
除部分格式原因不能完全转换的代码之外,其余关键代码(注解、类型、配置)都是一样的 - 好好复习英语数学,别敲代码搞些有的没的
最后顺便提一句Realm
认证超级管理员的问题,可以直接在Realm
中加上超级管理员的特别认证,就不用去方法级别上区分这个权限可以超级管理和XX管理员都可用了
override fun isPermitted(principals: PrincipalCollection, permission: String): Boolean {
return super.hasRole(principals, "xxx") || super.isPermitted(principals, permission)
}
override fun hasRole(principals: PrincipalCollection, roleIdentifier: String): Boolean {
return super.hasRole(principals, "xxx") || super.hasRole(principals, roleIdentifier)
}