Статьи

Шаблоны для использования пользовательских аннотаций

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

аннотирование

Локальная аннотация

Ваши инструменты должны принимать любые аннотации, если их единственное имя (без префиксного префикса) является ожидаемым. Например, com.acme.NotNull и net.companyname.NotNull будут считаться одинаковыми. Это позволяет использовать ваши собственные аннотации, а не те, которые упакованы с инструментами, чтобы не зависеть от них.

Пример в документации Guice :

Guice распознает любую аннотацию @Nullable, например, edu.umd.cs.findbugs.annotations.Nullable или javax.annotation.Nullable .

Составленные аннотации

Аннотации могут иметь аннотации в качестве значений. Это учитывает некоторые сложные и древовидные конфигурации, такие как отображения из одного формата в другой (из / в XML, JSon, RDBM).

Вот довольно простой пример из документации по аннотациям Hibernate :

    @AssociationOverride( 
name="propulsion",
joinColumns = @JoinColumn(name="fld_propulsion_fk")
)

Кратность Обертка

Java не позволяет использовать несколько раз одну и ту же аннотацию для данной цели.

Чтобы обойти это ограничение, вы можете создать специальную аннотацию, которая ожидает коллекцию значений желаемого типа аннотации. Например, вы хотите несколько раз применить аннотацию @Advantage , поэтому вы создаете аннотацию Multiplicity Wrapper: @Advantages (преимущества = {@Advantage}) .

Как правило, оболочка множественности названа в честь формы множественного числа ее вложенных элементов.

Пример в документации аннотаций Hibernate :

@AttributeOverrides( {
@AttributeOverride(name="iso2", column = @Column(name="bornIso2") ),
@AttributeOverride(name="name", column = @Column(name="bornCountryName") )
} )

 

annotationbis

Мета-наследование

В Java невозможно, чтобы аннотации происходили друг от друга. Чтобы обойти это, идея состоит в том, чтобы просто аннотировать вашу новую аннотацию «супер» аннотацией, которая становится метааннотацией.

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

Этот тип мета-наследования помогает централизовать связь с внешней аннотацией в одном месте, делая семантику вашей собственной аннотации более точной и значимой.

Пример в аннотациях Spring, с аннотацией @Component , но также работает с аннотацией @Qualifier :

Создайте собственную нестандартную аннотацию стереотипа, которая сама будет аннотирована @Component:

@Component
public @interface MyComponent {
String value() default "";
}

@MyComponent
public class MyClass...

Другой пример в Guice с обязательной аннотацией :

@BindingAnnotation
@Target({ FIELD, PARAMETER, METHOD })
@Retention(RUNTIME)
public @interface PayPal {}

// Then use it
public class RealBillingService implements BillingService {
@Inject
public RealBillingService(@PayPal CreditCardProcessor processor,
TransactionLog transactionLog) {
...
}

Refactoring-proof значения

Предпочитайте значения, которые являются устойчивыми к рефакторингу, а не к строковым буквам. MyClass.class лучше, чем «com.acme.MyClass», и перечисления также приветствуются.

Пример в документации аннотаций Hibernate :

    @ManyToOne( cascade = {CascadeType.PERSIST, CascadeType.MERGE}, targetEntity=CompanyImpl.class )

И еще один пример в документации Guice :

@ImplementedBy(PayPalCreditCardProcessor.class) 

Правило приоритета конфигурации

Соглашение о конфигурации и разумные значения по умолчанию — это два существующих шаблона, которые имеют большой смысл в отношении использования аннотаций как части стратегии конфигурации. Отсутствие необходимости аннотировать намного лучше, чем аннотирование за небольшую ценность.

Аннотации по своей природе встроены в код, поэтому они не подходят для каждого случая конфигурации, в частности, когда речь идет о конфигурации, специфичной для развертывания. Конечно, решение состоит в том, чтобы смешать аннотации с другими механизмами и использовать каждый из них там, где они более уместны.

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

Значение по умолчанию <Аннотация <XML <программная конфигурация

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

Этот принцип распространен (Spring, Java 6 EE среди других), например, в JPA:

Концепция конфигурации за исключением является центральной в спецификации JPA.

Вывод

Этот пост в основном представляет собой блокнот с различными шаблонами использования аннотаций, например, при создании инструментов для обработки аннотаций, таких как Инструменты обработки аннотаций в Java 5 и Сменные процессоры аннотаций в Java 6.

Не стесняйтесь вносить лучшие названия моделей, дополнительные шаблоны и другие примеры использования.

С http://cyrille.martraire.com/2010/07/patterns-for-using-annotations/