如何扩展Spring注解@Transactional

发布于 2024-09-16 08:25:26 字数 798 浏览 5 评论 0原文

我必须在我的网络应用程序中使用 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= 等。由于您无法“扩展”注释(我实际上只需要从 Spring 扩展 @Transactional 注释),那么正确的实现是什么?

I have to use 3 different transaction managers in my webapp. So I wrote my own Annotation according to the Spring reference (Section 10.5.6.3 Custom shortcut annotations).

One annotation (for using one specific transactionmanager) looks like this:

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{


}

Everything is working fine when annotating my service layer with the customized @CustomerTX annotation. But I have to provide more options for my annotation, like readonly=true, rollbackFor= and so on. As you cannot "extend" an annotation (I really just need to extend the @Transactional annotation from Spring), whats the correct implementation for this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

韵柒 2024-09-23 08:25:26

在 Spring 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;

}

In spring 4 you can do that. As stated in the documentation

Meta-annotations can also be combined to create composed annotations. For example, the @RestController annotation from Spring MVC is composed of @Controller and @ResponseBody.

In addition, composed annotations may optionally redeclare attributes from meta-annotations to allow user customization. This can be particularly useful when you want to only expose a subset of the meta-annotation’s attributes. For example, Spring’s @SessionScope annotation hardcodes the scope name to session but still allows customization of the 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;

}
另类 2024-09-23 08:25:26

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

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


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

You will have to create several custom annotations, I'm afraid, one for every use case, annotating each with the exact @Transactional annotation you need.

Or you will have to write your own aspect in AspectJ ( extend org.springframework.transaction.aspectj.AbstractTransactionAspect from spring-aspects.jar ) to create your own transaction logic.


Update: this was the correct answer at the time, but as of Spring 4 and later, the answer by C.L.S should be preferred

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文