如何扩展Spring Annotation @Transactional

tim*_*ner 7 java spring annotations transactional

我必须在我的webapp中使用3个不同的事务管理器.所以我根据Spring参考编写了自己的Annotation (第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{


}
Run Code Online (Sandbox Code Playgroud)

使用自定义的@CustomerTX注释注释我的服务层时,一切正常.但是我必须为我的注释提供更多选项,比如readonly = true,rollbackFor =等等.因为你不能"扩展"一个注释(我真的只需要从Spring扩展@Transactional注释),这是什么正确的实现?

Pit*_*elk 5

在春季 4 中,您可以这样做。如文档中所述

也可以组合元注释来创建组合注释。例如,Spring MVC 中的@RestController 注解就是由@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;

}
Run Code Online (Sandbox Code Playgroud)


Sea*_*oyd 4

恐怕您必须创建多个自定义注释,每个用例一个,并使用@Transactional您需要的确切注释对每个注释进行注释。

或者您必须在 AspectJ 中编写自己的方面(org.springframework.transaction.aspectj.AbstractTransactionAspect从 spring-aspects.jar 扩展)来创建您自己的事务逻辑。


更新:这是当时的正确答案,但从 Spring 4 及更高版本开始,CLS 的答案应该是首选