Java之Annotation简易上手实践

  • 2019 年 10 月 4 日
  • 筆記

在做Java中Spring全家桶是大家的必选,它淘汰了竞争对手Struts(也挺优秀的)成为Java开发的首选。而我们在做Spring开发时遇到一大堆的为我们带来便利的注解,那么今天就带领大家来看看注解吧……

说到注解这就不得不先来看看反射啦,因为之谈注解不去聊反射那就耍流氓啊–注解的完美使用是建立在反射基础上的。

引子

Mybatis是国内互联网大规模使用的半自动化的数据库连接操作框架(别问我为啥它那么受欢迎,拿板砖拍产品经理就行),大家首要配置的就是@MapperScan和@Mapper这两个注解之一?

今天我们就模拟一个

我们系统中有很多的Animal???,每次获取一中小动物怎么通过一个注解方式来达到不去修改内部代码来实现内部切换呢?—工厂方法

class AnimalFactory {      public static Animal animalByName(String name) {          switch (name) {              case "DOg":                  return new Dog();              case "Duck":                  return new Duck();              default:                  return null;          }      }   }

这种方法固然可以,但是每次添加一种动物就修改内部代码,耦合和侵入行太强。那么如何能达到非侵入性,低耦合的方式呢?—-不妨使用注解来完成

注解之前我们先看看怎么获取Java的实例

1 new一个对象(单身狗可以多多new对象说不定就new出个媳妇)

2 Class.forName加载(我们MySQL数据经常使用这种方式)

显然我们不能使用1,因为它是耦合高,侵入式,那么我们看看2怎么走

我么都知道每个Object都有一个Class,而Clas.forName也是值获取了一个Class并非是一个实例,我们需要newInstance出一个实例

 Class<?> clas = Class.forName("com.company.Student");  clas.newInstance()

我们现在知道怎么通过类名获取一个实例了,那么对于注解呢?我们能否获取实例对象的注解呢?答案是可以的

clas.getDeclaredAnnotation(A.class);

那么对于此方式我们使用到我们的动物工厂里

static Animal someOne() {          Animal animal = null;          boolean hasAnimalBean = AnimalFactory.class.isAnnotationPresent(AnimalBean.class);          if (hasAnimalBean == false) {              return null;          }          AnimalBean animalBean = AnimalFactory.class.getDeclaredAnnotation(AnimalBean.class);          if (animalBean == null) {              return null;          }          String animalClassName = animalBean.animal();          try {              Class animalClz = Class.forName(animalClassName);              animal = (Animal) animalClz.newInstance();          } catch (ClassNotFoundException e) {              e.printStackTrace();          } catch (IllegalAccessException e) {              e.printStackTrace();          } catch (InstantiationException e) {              e.printStackTrace();          }          return animal;      }

上栗就是这么简单的加载了出了动物,那么除此之外我们还要什么呢?当然是创建一个注解了

@Retention(RetentionPolicy.RUNTIME)  @interface AnimalBean {      String animal();  }

对于上栗的注解怎么使用呢?

  @AnimalBean(animal = "com.company.Dog")  class AnimalFactory {}

没错就是这么的随意,通过修改注解中animal你就实现了内部轻松切换注入不同的小动物,是不是感觉很方便很魔性啊……

class Dog implements Animal {        @Override      public void move() {          System.out.println("run");      }  }    @Retention(RetentionPolicy.RUNTIME)  @interface AnimalBean {      String animal();  }    @AnimalBean(animal = "com.company.Dog")  class AnimalFactory {      public static Animal animalByName(String name) {          switch (name) {              case "DOg":                  return new Dog();              case "Duck":                  return new Duck();              default:                  return null;          }      }      static Animal someOne() {          Animal animal = null;          boolean hasAnimalBean = AnimalFactory.class.isAnnotationPresent(AnimalBean.class);          if (hasAnimalBean == false) {              return null;          }          AnimalBean animalBean = AnimalFactory.class.getDeclaredAnnotation(AnimalBean.class);          if (animalBean == null) {              return null;          }          String animalClassName = animalBean.animal();          try {              Class animalClz = Class.forName(animalClassName);              animal = (Animal) animalClz.newInstance();          } catch (ClassNotFoundException e) {              e.printStackTrace();          } catch (IllegalAccessException e) {              e.printStackTrace();          } catch (InstantiationException e) {              e.printStackTrace();          }          return animal;      }  }