Как расширить аннотацию Spring @Transactional - PullRequest
7 голосов
/ 31 августа 2010

Мне нужно использовать 3 разных менеджера транзакций в моем веб-приложении. Поэтому я написал свою собственную аннотацию в соответствии со ссылкой Spring (раздел 10.5.6.3 Пользовательские аннотации ярлыков).

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

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import org.springframework.transaction.annotation.Transactional;

@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Transactional("customer")
public @interface CustomerTX{


}

Все работает нормально, когда аннотирую мой сервисный слой с помощью настроенной аннотации @CustomerTX. Но я должен предоставить больше вариантов для моей аннотации, например readonly = true, rollbackFor = и так далее. Поскольку вы не можете «расширять» аннотацию (мне действительно нужно просто расширить аннотацию @Transactional из Spring), какова правильная реализация для этого?

Ответы [ 2 ]

3 голосов
/ 31 августа 2010

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

Или вам придется написать свой собственный аспектв AspectJ (расширение org.springframework.transaction.aspectj.AbstractTransactionAspect из spring-aspect.jar) для создания собственной логики транзакций.

2 голосов
/ 05 марта 2018

Весной 4 вы можете сделать это.Как указано в документации

Мета-аннотации также могут быть объединены для создания составных аннотаций.Например, аннотация @RestController из Spring MVC состоит из @Controller и @ ResponseBody.

Кроме того, составные аннотации могут по желанию повторно декларировать атрибуты из метааннотаций, чтобы позволить пользовательскую настройку.Это может быть особенно полезно, когда вы хотите предоставить только подмножество атрибутов метааннотации.Например, аннотация Spring @SessionScope жестко кодирует имя области для сеанса, но все же позволяет настраивать proxyMode.

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Scope(WebApplicationContext.SCOPE_SESSION)
public @interface SessionScope {

    /**
     * Alias for {@link Scope#proxyMode}.
     * <p>Defaults to {@link ScopedProxyMode#TARGET_CLASS}.
     */
    @AliasFor(annotation = Scope.class)
    ScopedProxyMode proxyMode() default ScopedProxyMode.TARGET_CLASS;

}
...