При перепечатке просьба указывать источник:
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 Привет…
видео МООК
Загрузка исходного кода
Подпишитесь на мой публичный аккаунт
Захватывающий контент, который нельзя пропустить!