Подробное объяснение аннотаций Java

Java

При перепечатке просьба указывать источник:
blog.CSDN.net/forephotos/Аретти…
Эта статья взята изБлог Фан Чжипэна

После использования SpringBoot в качестве основы для гибкой веб-разработки, в дополнение к удобству настройки автоматического связывания, SpringBoot во многих случаях необходимо разрабатывать на основе аннотаций. Аннотации не только повышают читабельность кода, но и увеличивают скорость разработки. Эта статья посвящена аннотациям Java.

метааннотация

Мета-аннотации используются для аннотирования других аннотаций. Java 5.0 определяет четыре стандартных метааннотации следующим образом:

  • @Target
  • @Retention
  • @Documented
  • Inherited

Теперь давайте поговорим о том, что делают эти четыре мета-аннотации.

@Target

Аннотация @Target используется для объявления области действия аннотации, например, областью действия является класс, интерфейс, метод и т. д. Его значения и соответствующий диапазон значений следующие:

  • CONSTRUCTOR: используется для описания конструктора
  • FIELD: используется для описания поля
  • LOCAL_VARIABLE: используется для описания локальных переменных.
  • МЕТОД: используется для описания метода
  • ПАКЕТ: используется для описания пакета
  • ПАРАМЕТР: используется для описания параметров
  • ТИП: используется для описания классов, интерфейсов (включая типы аннотаций) или объявлений перечисления.

@Retention

Эта аннотация объявляет время жизни аннотации, то есть область, в которой аннотация действительна.

  • ИСТОЧНИК: Действительно в исходном файле
  • CLASS: допустимо в файлах классов
  • ВРЕМЯ ВЫПОЛНЕНИЯ: Действителен во время выполнения (т. е. зарезервировано во время выполнения)

Большинство аннотаций RUNTIME

@Documented

Является аннотацией разметки, аннотация с этой аннотацией будет сохранена в сгенерированном java-документе.

@Inherited

Эта аннотация указывает, что подкласс унаследовал аннотацию суперкласса. Например, аннотация модифицируется метааннотацией, и аннотация действует на родительский класс, тогда аннотация есть у подкласса. Если аннотация не украшена этой мета-аннотацией, подкласс не содержит аннотацию суперкласса.

пользовательская аннотация

Для Java-разработчиков JDK поставляется с некоторыми аннотациями, а Spring имеет большое количество аннотаций в сторонней среде, которые называются сторонними аннотациями. Во многих реальных процессах разработки нам необходимо определять собственные аннотации. Итак, теперь мы объясним пользовательские аннотации в каждом конкретном случае.

В аннотации необходимо использовать четыре вида метааннотаций для объявления области действия, жизненного цикла, наследования, создания документов и т. д. аннотации. Кроме того, аннотации также могут иметь свои собственные переменные-члены.Если аннотация не имеет переменных-членов, она называется помеченной аннотацией. Аннотированные переменные-члены поддерживают только примитивные типы, класс, перечисление и аннотацию.

Теперь определите аннотацию @Writer, которая изменяется с помощью Retention, Documented, Inherited и Target, указывая, что область действия аннотации — это класс, интерфейс и метод, жизненный цикл — это время выполнения, аннотация генерирует документ, а подклассы могут наследовать аннотация. В аннотации есть 2 переменные-члены, одна — имя, а другая — возраст, код выглядит следующим образом:

@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Target({ElementType.TYPE,ElementType.METHOD})
public @interface Writer {

    String name();

    int age();

}

Итак, с этой аннотацией, как ее использовать?

Областью действия аннотации является класс, метод, напишите WriterTest, код выглядит следующим образом:

@Writer(name = "forezp", age = 12)
public class WriterTest {

    @Writer(name = "miya", age = 10)
    public void writeBlog() {
        System.out.println("writing blog");
    }

  }

Какая польза от этого класса с этой аннотацией?

Вообще говоря, класс, украшенный этим классом, должен заниматься развитием логики посредством отражения, что может широко использоваться в АОП, настройке программ и т. д. Теперь напишите метод для разбора аннотации через отражение:

  public static void main(String[] args) throws ClassNotFoundException {
        Class c = Class.forName("com.forezp.annotation.WriterTest");
        if (c.isAnnotationPresent(Writer.class)) {
            Writer w = (Writer) c.getAnnotation(Writer.class);
            System.out.println("name:" + w.name() + "   age:" + w.age());
        }
        Method[] methods = c.getMethods();
        for (Method method : methods) {
            if (method.isAnnotationPresent(Writer.class)) {
                Writer w = method.getAnnotation(Writer.class);
                System.out.println("name:" + w.name() + "   age:" + w.age());
            }
        }
    }

Эти коды в основном и есть содержание рефлексии, потому что рефлексия подробно описана в другой статье, поэтому повторяться не буду.При запуске метода Main консоль выводит следующее содержимое:

name:forezp age:12

name:miya age:10

Дело боевое

С приведенным выше объяснением у вас может быть некоторое понимание аннотаций, но конкретное применение аннотаций не очень глубоко. Теперь возьмем случай, чтобы описать подробно.

Все хорошо знакомы с фреймворком ORM Mybitis, и в нем используется множество аннотаций. Теперь сымитируйте эту структуру и проанализируйте операторы запроса sql с помощью пользовательских аннотаций. Процесс реализации примерно такой:

  • Определите аннотацию @Table @Colum
  • Определите пользователя объекта, определите некоторые основные поля и украсьте их аннотациями.
  • Используйте новый объект класса User для присвоения значений некоторым полям объекта
  • Создание операторов SQL-запроса посредством отражения и аннотации

Сначала определите аннотацию таблицы, ее областью действия является класс, код выглядит следующим образом:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Inherited
public @interface Table {
    String value() default "";
}

Определите аннотацию столбца, областью действия является поле, код выглядит следующим образом:

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

Определите класс пользователя, добавьте аннотацию @Table к классу и аннотацию @Column к определенным полям.Код выглядит следующим образом:

@Table("user")
public class User {
    @Column("id")
    private int id;
    @Column("name")
    private String name;
    @Column("age")
    private int age;
    @Column("address")
    private String address;
    ..//省略getter setter
   }

Напишите класс, который генерирует операторы SQL.Он получает имя таблицы и имя поля посредством отражения, а также определяет значение поля объекта сущности для создания оператора SQL для запроса. код показывает, как показано ниже:

public class GenUserSql {

    public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
        User u1 = new User();
        User u2 = new User();
        u1.setId(1);
        u2.setName("forezp");
        genSql(u2);
        genSql(u1);
    }

    private static void genSql(User user) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        Class c = user.getClass();
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append("select * from ");
        if (c.isAnnotationPresent(Table.class)) {
            Table table = (Table) c.getAnnotation(Table.class);
            String tableName = table.value();
            stringBuilder.append(tableName).append(" where 1=1 and ");
        }
        Field[] fields = c.getDeclaredFields();
        for (Field field : fields) {
            String columnName;
            if (field.isAnnotationPresent(Column.class)) {
                Column column = field.getAnnotation(Column.class);
                columnName = column.value();
            } else {
                continue;
            }
            String fieldName = field.getName();
            String getMethodName = "get" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
                       Method method = c.getMethod(getMethodName);
            Object fieldValue = method.invoke(user);
            if (fieldValue == null || ((fieldValue instanceof Integer) && (Integer) fieldValue == 0)) {
                continue;
            }
            if (fieldValue instanceof Integer) {
                stringBuilder.append(columnName + "=" + fieldValue);
            }
            if (fieldValue instanceof String) {
                stringBuilder.append(columnName + "=" + "'" + fieldValue + "'");
            }

        }
        System.out.println(stringBuilder.toString());

    }
}

Запустив программу, консоль выводит следующее:

>

select * from user where 1=1 and name='forezp'

select * from user where 1=1 and id=1

использованная литература

woo woo woo.cn blog on.com/matching/arc Привет…

видео МООК

Загрузка исходного кода

GitHub.com/forephotos/Java…

Подпишитесь на мой публичный аккаунт

Захватывающий контент, который нельзя пропустить!

forezp.jpg
forezp.jpg