大家好,又见面了,我是你们的朋友全栈君。
分享一个朋友的人工智能教程(请以“右键”->”在新标签页中打开连接”的方式访问)。比较通俗易懂,风趣幽默,感兴趣的朋友可以去看看。
开发中经常使用到注解,在项目中也偶尔会见到过自定义注解,今天就来探讨一下这个注解是什么鬼,以及注解的应用场景和如何自定义注解。
下面列举开发中常见的注解
下面看一下注解Override.java的庐山真面目
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}
注解是写在.java文件中,使用@interface作为关键字, 所以注解也是Java的一种数据类型,从广泛的定义来说,Class、Interface、Enum、Annotation都属于Class类型。
在创建注解的时候,需要使用一些注解来描述自己创建的注解,就是写在@interface上面的那些注解,这些注解被称为元注解,如在Override中看到的@Target、@Retention等。下面列出一些元注解
在上面的注解源码中可以看到有的注解中没有任何内容,有的注解的有内容,看似像方法。
注解的内容的语法格式: 数据类型 属性名() default 默认值
,数据类型用于描述属性的数据类型,默认值是说当没有给属性赋值时使用默认值,一般String使用空字符串””作为默认值,数组一般使用空数组{ }作为默认值.
下面看一下SpringMVC中的RequestMapping的注解的声明
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Mapping
public @interface RequestMapping {
String name() default "";
@AliasFor("path")
String[] value() default {};
@AliasFor("value")
String[] path() default {};
RequestMethod[] method() default {};
String[] params() default {};
String[] headers() default {};
String[] consumes() default {};
String[] produces() default {};
}
使用SpringMVC中的RequestMapping注解
@RequestMapping(value = "/list",
method = RequestMethod.POST,
produces = {"application/json;charset=UTF-8;"})
public String list(){
}
可以通过注解的声明周期来分析注解的使用场景:
关于配置方式xml vs annotation, 一般使用xml配置一些和业务关系不太紧密的配置,使用注解配置一些和业务密切相关的参数。
// 获取某个类型的注解
public <A extends Annotation> A getAnnotation(Class<A> annotationClass);
// 获取所有注解(包括父类中被Inherited修饰的注解)
public Annotation[] getAnnotations();
// 获取声明的注解(但是不包括父类中被Inherited修饰的注解)
public Annotation[] getDeclaredAnnotations();
// 判断某个对象上是否被某个注解进行标注
public boolean isAnnotationPresent(Class<? extends Annotation> annotationClass)
// 获取某个类声明的所有字段
public Field[] getDeclaredFields() throws SecurityException;
// 获取某个方法
public Method getMethod(String name, Class<?>... parameterTypes);
使用自定义注解+拦截器或者是AOP等可以进行权限的控制。
下面通过定义一个注解用来限制当用户访问接口时必须要登录的示例
步骤一:定义注解 RequiresLogin.java
@Documented
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface RequiresLogin {
}
步骤二:使用注解
@Controller
@RequestMapping("/user")
public class UserController {
@RequiresLogin
@RequestMapping(value = "/list", produces = {"application/json;charset=UTF-8;"})
public String getUserList(){
System.out.println("--------------");
return "[{'id': 1, 'username':'zhangsan'}]";
}
}
步骤三:使用AOP进行拦截,解析注解
public class LoginAdvices {
public void before(JoinPoint joinPoint) throws Exception{
Object target = joinPoint.getTarget();
String methodName = joinPoint.getSignature().getName();
System.out.println(target + "-------" + methodName);
Method method = target.getClass().getMethod(methodName);
boolean annotationPresent = method.isAnnotationPresent(RequiresLogin.class);
if (annotationPresent) {
// 用户必须登录
boolean isLogin = false;
if (!isLogin) {
throw new Exception("访问该接口必须先登录");
} else {
System.out.println("已登录...");
}
}
}
}
在applicationContext.xml中配置aop
<bean id="loginAdvices" class="com.mengdee.manager.aop.LoginAdvices"/>
<!-- aop配置 -->
<aop:config proxy-target-class="true">
<!--切面 -->
<aop:aspect ref="loginAdvices">
<!-- 切点 -->
<aop:pointcut id="pointcut1" expression="execution(* com.mengdee.manager.controller.*.*(..))"/>
<!--连接通知方法与切点 -->
<aop:before method="before" pointcut-ref="pointcut1"/>
</aop:aspect>
</aop:config>
浏览器访问http://localhost:8080/xxx/user/list
关于如何自定义注解对属性值的合法性进行校验,请移步http://blog.csdn.net/vbirdbest/article/details/72620957 这里有完整的示例
public class ShiroException extends RuntimeException {
public ShiroException() {
}
public ShiroException(String message) {
super(message);
}
public ShiroException(Throwable cause) {
super(cause);
}
public ShiroException(String message, Throwable cause) {
super(message, cause);
}
}
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/129039.html原文链接:https://javaforall.cn