版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
kotlin编写方法级的注解
前言
实际上编写我们的自定义的注解基本就是一个套路,只要熟悉了这个套路那就可以自己去编写我们想要的注解,此处就不再说java的注解的实现,在网络上搜下一大堆,这边主要讲解的是方法级的kotlin注解的实现,接下来将给大家讲解的是基于spring boot的编写的一个鉴权的注解的例子,首先我们直接使用IDEA创建一个我们的kotlin的web工程。
编写注解类
以下就是我们所需要编写的注解类,只需要在我们的类上加上【annotation】就表示我们的注解类了,后面的【val authorities: Array】表示我们这个注解所接受的一个参数。
package com.kotlin.annotation.auth
/**
* 类描述:一个鉴权的注解类
* @Target(AnnotationTarget.FUNCTION) 表示这个是对方法进行注解
* @Retention(AnnotationRetention.RUNTIME) 表示注解不仅被保存到class文件中,jvm加载class文件之后,仍然存在
*/
@Target(AnnotationTarget.FUNCTION)
@Retention(AnnotationRetention.RUNTIME)
annotation class AuthController (val authorities: Array<String>)
基于spring的注解拦截的实现
上面我们已经完成了我们注解类的编写了,那么接下来就是如何来运用我们的注解了,我们现在是基于web工程的运用,因此我们直接拦截我们在controller方法上的注解,实现如下:
package com.kotlin.annotation.auth.filter
import com.kotlin.annotation.auth.AuthController
import org.springframework.stereotype.Component
import org.springframework.web.method.HandlerMethod
import org.springframework.web.servlet.HandlerInterceptor
import java.util.regex.Pattern
import javax.servlet.http.HttpServletRequest
import javax.servlet.http.HttpServletResponse
/**
* 类描述:基于web的注解拦截的实现
* @author linzf
* @since 2019-09-09
*/
@Component
class AuthControllerInterceptor : HandlerInterceptor {
/**
* 功能描述: 拦截所有的请求
*/
override fun preHandle(request: HttpServletRequest, response: HttpServletResponse, handler: Any): Boolean {
/**
* 这是为了防止跨域访问的时候嗅探方法的进入,因此直接放行
*/
if ("OPTIONS" == request.method) {
return true
}
/**
* 对我们的js,css等直接放行
*/
val actionUrl = request.servletPath
val jsPattern = ".*.js"
val cssPattern = ".*.css"
val pngPattern = ".*.png"
val gifPattern = ".*.gif"
if (Pattern.matches(gifPattern, actionUrl) || Pattern.matches(jsPattern, actionUrl) || Pattern.matches(cssPattern, actionUrl) || Pattern.matches(pngPattern, actionUrl)) {
return true
}
println("响应的地址是:$actionUrl")
// 将handler强转为HandlerMethod, 前面已经证实这个handler就是HandlerMethod
val handlerMethod = handler as HandlerMethod
// 从方法处理器中获取出要调用的方法
val method = handlerMethod.method
// 获取出方法上的AuthController注解
val authController = method.getAnnotation(AuthController::class.java) ?: return true
for (a in authController.authorities) {
println("注解的值是:$a")
}
return true
}
}
配置拦截器
最后我们需要配置使我们的拦截器生效:
package com.kotlin.annotation.config
import com.kotlin.annotation.auth.filter.AuthControllerInterceptor
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Component
import org.springframework.web.servlet.config.annotation.InterceptorRegistry
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer
@Component
class InterceptorConfig : WebMvcConfigurer {
@Autowired
lateinit var authControllerInterceptor: AuthControllerInterceptor
override fun addInterceptors(registry: InterceptorRegistry) {
registry.addInterceptor(authControllerInterceptor).addPathPatterns("/**")
}
}
验证我们的注解
最后自然到了验证我们的注解是否生效的环节了,那么我们首先需要创建一个controller类来实现我们的注解的拦截。
package com.kotlin.annotation.controller
import com.kotlin.annotation.auth.AuthController
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController
@RestController
@RequestMapping("/kotlin")
class KotlinController {
/**
* 带权限的注解的拦截
*/
@GetMapping("hasAnnotation")
@AuthController(authorities = ["roleAdmin"])
fun hasAnnotation(): String {
return "hasAnnotation"
}
/**
* 带不权限的注解的拦截
*/
@GetMapping("hasNoAnnotation")
fun hasNoAnnotation(): String {
return "hasNoAnnotation"
}
}
我们运行我们的项目,然后在浏览器输入:http://127.0.0.1:8080/kotlin/hasAnnotation,我们会在控制台看到如下的结果,则说明我们的注解已经生效了。
接着我们访问http://127.0.0.1:8080/kotlin/hasNoAnnotation,我们会在控制台看到如下的结果,则说明我们并没有在这上面编写注解。
到此为止我们就完成了我们的注解的编写了,代码直接在github上:https://github.com/lazyboyl/kotlin-for-annotation