7

I am creating my own custom shortcut annotation, as described in Spring Documentation:

@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Transactional(value = "Custom", readOnly = true)
public @interface CustomTransactional {
}

Is it possible, that with my custom annotation I could be also able to set any other attributes, which are available in @Transactional? I would like to able use my annotation, for example, like this:

@CustomTransactional(propagation = Propagation.REQUIRED)
public class MyClass {

}
Laimoncijus
  • 8,615
  • 10
  • 58
  • 81

3 Answers3

4

No, that will not work, if you want additional attributes that will have to be set on your custom annotation itself this way:

@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Transactional(value = "Custom", readOnly = true, propagation = Propagation.REQUIRED)
public @interface CustomTransactional {
}

A solution (bad one :-) ) could be to define multiple annotations with the base set of cases that you see for your scenario:

@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Transactional(value = "Custom", readOnly = true, propagation = Propagation.REQUIRED)
public @interface CustomTransactionalWithRequired {
}

@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Transactional(value = "Custom", readOnly = true, propagation = Propagation.SUPPORTED)
public @interface CustomTransactionalWithSupported {
}
Biju Kunjummen
  • 49,138
  • 14
  • 112
  • 125
  • Yes, I thought of such scenario, but then I would end up with MANY annotation - for each sensible attribute combination ;) – Laimoncijus Jan 04 '13 at 13:34
  • 1
    Yes, I thought so, that is the reason why I put it as a bad solution :-) . don't see any other option than using `@Transactional` itself if that is the case, custom stereotype annotations will help if you have a fixed set of attributes for your annotations. – Biju Kunjummen Jan 04 '13 at 13:43
2

In (at least) Spring 4, you can do this by specifying the element inside the annotation, e.g.:

@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Transactional(value = "Custom", readOnly = true)
public @interface CustomTransactional {
    Propagation propagation() default Propagation.SUPPORTED;
}

Source: http://docs.spring.io/spring/docs/current/spring-framework-reference/html/beans.html#beans-meta-annotations

ahawtho
  • 704
  • 7
  • 8
0

As of Spring Framework 4.2, @AliasFor annotation can be used to declare aliases for annotation attributes.

@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Transactional
public @interface CustomTransactional {
  @AliasFor(annotation = Transactional.class, attribute = "propagation")
  Propagation propagation() default Propagation.REQUIRED;
}
Toni
  • 3,296
  • 2
  • 13
  • 34