注解

Java注解

  • @Deprecated:标记方法或类过时
  • @SuppressWarning: 在确定结果的前提下忽略警告

第三方注解

  • @Autoware

按运行机制分

  • 源码注解(SOURCE):只在源码中存在
  • 编译时注解(CLASS):源码和.class文件时都存在。@Override
  • 运行时注解(RUNTIME): 源码和.class文件存在、程序运行时也存在。@Autoware

按来源分

  • JDK
  • 第三方
  • 自定义
    元注解 :给注解用的注解

自定义注解

  1. 语法:
  • 使用@interface关键字
  • 成员变量要生命成无参函数形式,并且无异常,只能是基本数据类型和String,使用default关键字赋默认值
  • 只有一个成员变量时,必须命名为value()
@Target({ElementType.METHOD,ElementType.TYPE})
@Rentention(RententionPolicy.RUNTIME)
@Inherited
@Document
public @interface Discription{
  String desc();
  String author();
  int age() default 18;
}
  1. 元注解
  • @Target:注解适用范围,可以设置多个。
    取值:
ElementType.CONSTRUCTOR
ElementType.FIELD
ElementType.LOCAL_VARIABLE //局部变量
ElementType.METHOD
ElementType.PACKAGE
ElementType.PARAMETER
ElementType.TYPE //类,接口
  • @Rentention:注解生命周期
    取值:
RententionPolicy.SOURCE // 源码
RententionPolicy.CLASS // 编译
RententionPolicy.RUNTIME //运行
  • @Inherited:允许注解继承
  • @Document:生成doc时生成注解信息
  1. 使用注解
@Discription(desc="我是一段描述",author="yujian",age=18)
public String getMyName(){
  return "yujian";
}
  1. 解析注解
    通过反射获取类运行时注解信息,从而动态控制类的运行逻辑。

实战

自定义table和column注解映射字段和表,查询数据,打印书SQL
table和column注解:

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface Table {
    String value();
}
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Column {
    String value();
}

User类使用table和column注解

@Table("user")
public class User {

    @Column("id")
    private String id;

    @Column("name")
    private String name;

    @Column("email")
    private String email;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

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

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }
}

根据注解获取标名和字段名,根据反射获取字段值:

        //获取class
        Class c = user.getClass();
        //获取table名称
        if (!c.isAnnotationPresent(Table.class)){
            return null;
        }
        Table table = (Table) c.getAnnotation(Table.class);
        System.out.println(table.value());
        //获取field名称
        Field[] fields = c.getDeclaredFields();
        for (Field field : fields){
            if (field.isAnnotationPresent(Column.class)){
                Column column = field.getAnnotation(Column.class);
                System.out.print(column.value() + ":");
                //通过反射获取对象值
                String fieldName = field.getName();
                String methodName = "get"
                        + fieldName.substring(0,1).toUpperCase()
                        + fieldName.substring(1);
                try {
                    Method method = c.getMethod(methodName);
                    System.out.println(method.invoke(user));
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

常见概念

  • 为什么需要把 @Autowired写在构造器上:注入注解要等类构造完成才会注入外部依赖,但变量是按顺序加载的,容易出现空指针异常,使用构造器注入在调用时去初始化,能保证已经注入了外部依赖。

  • @Autowired只按照byType 注入;
    @Resource默认按byName自动注入,也提供按照byType 注入;

  • @Configuration:配置文件,与@Bean连用可配置单个Bean,eg.@Bean(name="user")

  • @EnableAutoConfiguration:配合spring.factories文件将配置文件装配到spring中,参考。

  • @ComponentScan:叠加在配置文件类上,可以定策略扫描Bean,默认扫描配置文件同包的类,注意类上需要配置

//@Component注解。basePackages定义扫描的包
@ComponentScan(basePackages = { ” com.springboot . chapter3 . pojo” })
//basePackageClasses 定义扫描的类
@ComponentScan(basePackageClasses = {User. class} ) 
//还有 includeFilters 和 excludeFilters 
@ComponentScan(basePackages = "com.springboot.chapter3 . * ”, excludeFilters = {@Filter(classes = {Service . class})}) 。
  • Constraint注解自定义校验
  • Constraint注解分组校验

你可能感兴趣的:(注解)