java----注解

 Annotation:

 注解:

  作用1:当对程序做解释的时候和注释的意义差不多

  作用2:可以在编译期读取注解中的信息然后为程序所利用。

注释作用1

public class Test{
    //可以起到一个提示的作用
    @Override
    public String toString() {
        return super.toString();
    }
}

系统自带注解

public class Demo{
    public static void main(String[] args) {
        Test test = new Test();
        test.test(); //使用了不推荐使用的方法
    }
}

//忽略编译期不当的警告
@SuppressWarnings("all")
class Test{
    //表示这个方法不再建议使用;
    @Deprecated
    public void test(){
        System.out.println("方法已经过时");
    }
    //检查此方法是不是覆盖了父类的方法
    @Override
    public String toString() {
        return super.toString();
    }
}

  

 

前言:注解的解析完全依赖于反射。

自定义注解,一个简单的例子

import java.lang.annotation.Annotation;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Arrays;

public class Demo{
    public static void main(String[] args) throws IllegalAccessException, InstantiationException {
        Class<Cat> catClass = Cat.class;
        //获取类中应用的指定的注解
        MyAnnotation annotation = catClass.getAnnotation(MyAnnotation.class);
        //通过反射获取注解中的值
        String name = annotation.name();
        int age = annotation.age();
        String[] like = annotation.like();
        Color color = annotation.color();

        //实例化对象
        Cat cat = catClass.newInstance();
        cat.setAge(age);
        cat.setColor(color);
        cat.setLike(like);
        cat.setName(name);
        System.out.println(cat);

    }
}

enum Color{
    red,black;
}
//表示注解再运行时依然存在
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation{
    public String name();
    public int age() default 10; //给变量设置默认值
    public String[] like(); //定义一个数组变量
    public Color color(); //定义一个枚举变量
}
@MyAnnotation(name="bin",like = {"鱼",},color = Color.black)
class Cat{
    private String name;
    private String[] like;
    private Color color;
    private int age;
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String[] getLike() {
        return like;
    }

    public void setLike(String[] like) {
        this.like = like;
    }

    public Color getColor() {
        return color;
    }

    public void setColor(Color color) {
        this.color = color;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Cat{" +
                "name='" + name + '\'' +
                ", like=" + Arrays.toString(like) +
                ", color=" + color +
                ", age=" + age +
                '}';
    }
}

  

 

注解详细解释

注解我们可以定义在类上,成员变量上等等

@TestA    //使用了类注解
public class UserAnnotation {
    @TestA //使用了类成员注解
    private Integer age;
    @TestA //使用了构造方法注解
    public UserAnnotation(){
    }
    @TestA //使用了类方法注解
    public void a(){
        @TestA //使用了局部变量注解
        Map m = new HashMap(0);
    }
    public void b(@TestA Integer a){ //使用了方法参数注解
        
    }
}

四个元注解

@Target 表示该注解用于什么地方,可能的值在枚举类 ElemenetType 中,包括: 
          ElemenetType.CONSTRUCTOR----------------------------构造器声明 
          ElemenetType.FIELD --------------------------------------域声明(包括 enum 实例) 
          ElemenetType.LOCAL_VARIABLE------------------------- 局部变量声明 
          ElemenetType.METHOD ----------------------------------方法声明 
          ElemenetType.PACKAGE --------------------------------- 包声明 
          ElemenetType.PARAMETER ------------------------------参数声明 
          ElemenetType.TYPE--------------------------------------- 类,接口(包括注解类型)或enum声明 
@Retention 表示在什么级别保存该注解信息。可选的参数值在枚举类型 RetentionPolicy 中,包括: 
          RetentionPolicy.SOURCE ---------------------------------注解将被编译器丢弃 
          RetentionPolicy.CLASS -----------------------------------注解在class文件中可用,但会被JVM丢弃 
          RetentionPolicy.RUNTIME VM-------将在运行期也保留注释,因此可以通过反射机制读取注解的信息。 
           
@Documented 将此注解包含在 javadoc 中 ,它代表着此注解会被javadoc工具提取成文档。在doc文档中的内容会因为此注解的信息内容不同而不同。相当与@see,@param 等。
@Inherited 允许子类继承父类中的注解。

方法

#判断方法或者类是否有这个注解
xx.isAnnotationPresent(X.class)
#isAssignableFrom()方法是判断是否为某个类的父类,instanceof关键字是判断是否某个类的子类。
父类.class.isAssignableFrom(子类.class)
子类实例 instanceof 父类类型

示例

import org.junit.Test;
import java.lang.annotation.Annotation;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import static java.lang.annotation.ElementType.*;


@Target({TYPE, METHOD, FIELD, CONSTRUCTOR})
@Retention(RetentionPolicy.RUNTIME)
@interface TestA {
    String name();

    int id() default 0;

    Class gid();
}

@TestA(id = 1, name = "type", gid = Long.class) //类注解
class UserAnnotation {
    @TestA(name = "param", id = 2, gid = Long.class) //类成员注解
    private Integer age;

    @TestA(name = "construct", id = 3, gid = Long.class)//构造方法注解
    public UserAnnotation() {
    }

    @TestA(name = "public method", id = 4, gid = Long.class) //类方法注解
    public void a() {
    }

    @TestA(name = "protected method", id = 5, gid = Long.class) //类方法注解
    protected void b() {
    }

    @TestA(name = "private method", id = 6, gid = Long.class) //类方法注解
    private void c() {
    }

    public void b(Integer a) {
    }
}

public class SpringbootProjectApplicationTests {
    @Test
    public void test() throws ClassNotFoundException, NoSuchMethodException {
        Class<UserAnnotation> userAnnotationClass = UserAnnotation.class;

        //获取类上注解的信息
        Annotation[] annotations = userAnnotationClass.getAnnotations();
        for (Annotation annotation : annotations) {
            TestA testA = (TestA) annotation;
            //打印了类注解的信息
            System.out.println(testA.id() + "--" + testA.name() + "-" + testA.gid());
        }

        //获取所有声明的方法的注解信息(不包含构造方法)
        Method[] declaredMethods = userAnnotationClass.getDeclaredMethods();
        for (Method method:declaredMethods){
            boolean annotationPresent = method.isAnnotationPresent(TestA.class);
            if (annotationPresent){
                TestA testA = method.getAnnotation(TestA.class);
                System.out.println(testA.id() + "--" + testA.name() + "-" + testA.gid());
            }
        }

        //获取指定的声明的方法的注解信息(不包含构造方法),获取字段的方式和方法类似getDeclareField("xx");
        Method b = userAnnotationClass.getDeclaredMethod("b");
        System.out.println(b.getAnnotation(TestA.class).id());

        //获取所有构造方法的注解信息(指定的构造方法同理)
        Constructor<?>[] constructors = userAnnotationClass.getConstructors();
        for (Constructor constructor:constructors){
            boolean annotationPresent = constructor.isAnnotationPresent(TestA.class);
            if (annotationPresent){
                TestA testA = (TestA) constructor.getAnnotation(TestA.class);
                System.out.println(testA.id() + "--" + testA.name() + "-" + testA.gid());
            }
        }
    }
}

使用注解完成类和表结构的映射关系(ORM)

使用注解进行数据表的创建

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@interface TestTable{
    String value();
}
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@interface TestUser{
    public String columnName();
    public String type();
    public int len();
}

@TestTable("table")
public class Test{
    @TestUser(columnName="id",type = "int",len = 10)
    private int id;
    @TestUser(columnName="username",type = "String",len = 32)
    private String username;
    @TestUser(columnName="password",type = "String",len = 32)
    private String password;

    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException {
        Class<?> aClass = Class.forName("com.zy.Test");

        Field username = aClass.getDeclaredField("username");
        TestUser annotation = username.getAnnotation(TestUser.class);
        System.out.println("字段:"+annotation.columnName());
        System.out.println("属性:"+annotation.type());
        System.out.println("长度:"+annotation.len());
        //字段:username
        //属性:String
        //长度:32
        //可以向这样获取所有的数据,拼接sql语句来创建数据表;
    }
}

通过注解进行拦截 

1、创建注解

import java.lang.annotation.*;
 
/***
 * @Target 注解修饰类型
 * @Retention 生命周期
 * @Documented注解标记的元素,Javadoc工具会将此注解标记元素的注解信息包含在javadoc中
 */
@Target(value = {ElementType.METHOD,ElementType.TYPE,ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface LoginUser {
 
    /**
     * 用户角色及默认值
     * @return
     */
    String role() default "admin";

2、重写拦截组件,拦截逻辑

import org.apache.commons.lang3.ObjectUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
 
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
 
@Component
public class LoginUserInterceptor extends HandlerInterceptorAdapter {
    private static final Logger logger = LoggerFactory.getLogger(LoginUserInterceptor.class);
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
 
        if (handler instanceof HandlerMethod) {
            //注解在方法上的获取方法
            LoginUser loginUserAnnotation = ((HandlerMethod) handler).getMethodAnnotation(LoginUser.class);
            //注解在类上的获取方法
            LoginUser classLoginUserAnnotation = ((HandlerMethod) handler).getMethod().getDeclaringClass().getAnnotation(LoginUser.class);
            if (ObjectUtils.anyNotNull(loginUserAnnotation, classLoginUserAnnotation)) {
                HttpSession session = request.getSession(false);
                //获取注解使用过程中的值
                System.out.println("pppppppppppppppppppppppppppppppppppppppppppppp"+loginUserAnnotation.role());
            }
        }
        return true;
    }
}

3.设置拦截规则

import org.springframework.boot.SpringBootConfiguration;
import org.springframework.format.FormatterRegistry;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.validation.MessageCodesResolver;
import org.springframework.validation.Validator;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.config.annotation.*;
 
import javax.annotation.Resource;
import java.util.List;
 
 
@SpringBootConfiguration
public class WebMvcConfiguration implements WebMvcConfigurer {
 
    @Resource
    private LoginUserInterceptor loginUserInterceptor;
 
    /**
     * addInterceptor()的顺序需要严格按照程序的执行的顺序
     *
     * @param registry
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
 
        // "/**" 拦截路径及其子路径
        registry.addInterceptor(loginUserInterceptor).addPathPatterns("/**");
        // "/*"  不拦截子路径
//        registry.addInterceptor(loginUserInterceptor).addPathPatterns("/*");
 
    }
 
 
    @Override
    public void configurePathMatch(PathMatchConfigurer pathMatchConfigurer) {
 
    }
 
    @Override
    public void configureContentNegotiation(ContentNegotiationConfigurer contentNegotiationConfigurer) {
 
    }
 
    @Override
    public void configureAsyncSupport(AsyncSupportConfigurer asyncSupportConfigurer) {
 
    }
 
    @Override
    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer defaultServletHandlerConfigurer) {
 
    }
 
    @Override
    public void addFormatters(FormatterRegistry formatterRegistry) {
 
    }
 
 
 
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry resourceHandlerRegistry) {
 
    }
 
    @Override
    public void addCorsMappings(CorsRegistry corsRegistry) {
 
    }
 
    @Override
    public void addViewControllers(ViewControllerRegistry viewControllerRegistry) {
 
    }
 
    @Override
    public void configureViewResolvers(ViewResolverRegistry viewResolverRegistry) {
 
    }
 
    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> list) {
 
    }
 
    @Override
    public void addReturnValueHandlers(List<HandlerMethodReturnValueHandler> list) {
 
    }
 
    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> list) {
 
    }
 
    @Override
    public void extendMessageConverters(List<HttpMessageConverter<?>> list) {
 
    }
 
    @Override
    public void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> list) {
 
    }
 
    @Override
    public void extendHandlerExceptionResolvers(List<HandlerExceptionResolver> list) {
 
    }
 
    @Override
    public Validator getValidator() {
        return null;
    }
 
    @Override
    public MessageCodesResolver getMessageCodesResolver() {
        return null;
    }
}

 4.在controller上添加注解

@RequestMapping("/toRegister")
	@LoginUser(role = "tester")
	public String toRegister(Model model, HttpServletRequest request) {
		return "register";
	}

  

posted @ 2019-04-24 18:40  小名的同学  阅读(180)  评论(0编辑  收藏  举报