总结记录 Spring
官方对如何使用、开发注解的介绍
即注释在注解上的注解,比如 @Component
之于 @Service
,也称 @Service
被 @Component
元注解了(meta-annotated
)
定义一个组件 角色
的注解,比如:
@Component
表明一个由 Spring
管理的组件@Controller
控制层角色组件@Service
业务层角色组件被一个或多个注解元注解的注解,最常见的比如 @RestController
,相当于 @Controller
+ @ResponseBody
被元注解的注解,其属性是元注解 同名
属性的 隐式复写
被元注解的注解,其某个属性被 @AliasFor
显示指定为元注解其他属性的别名,这种情况就是注解属性的 显式复写
举例,注解 @One
的属性 A
显式复写注解 @Two
的属性 B
,而注解 @Two
的属性 B
显式复写注解 @Three
的属性 C
,则 A
传递显式复写了 C
一个注解内的两个属性 通过 @AliasFor
互相声明为别名,比如:
public @interface ContextConfiguration {
@AliasFor("locations")
String[] value() default {};
@AliasFor("value")
String[] locations() default {};
// ...
}
一个注解中的两个或多个属性通过 @AliasFor
声明为 元注解
中 同一个
属性的 显式复写
,则它们互为 隐式别名
一个注解中的两个或多个属性通过 @AliasFor
声明为 元注解
属性的 显式复写
,而这些注解又 复写
了元注解的 同一属性
,则这些属性互为 传递隐式别名
组合注解可以使用 @AliasFor
注解的属性复写、别名来整合多个注解的功能,比如
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@RequestMapping(method = RequestMethod.GET)
public @interface GetMapping {
/**
* Alias for {@link RequestMapping#name}.
*/
@AliasFor(annotation = RequestMapping.class)
String name() default "";
/**
* Alias for {@link RequestMapping#value}.
*/
@AliasFor(annotation = RequestMapping.class)
String[] value() default {};
/**
* Alias for {@link RequestMapping#path}.
*/
@AliasFor(annotation = RequestMapping.class)
String[] path() default {};
// ...
}
使用这种模式,可以自定义各种组合注解,有一个专门的工程 spring-composed
供大家设计各种组合注解,还有可能被 Spring
官方采纳,项目中的注解示例如:
@Scope(SCOPE_SESSION)
@Target({ TYPE, METHOD })
@Retention(RUNTIME)
@Documented
public @interface SessionScope {
/**
* Alias for {@link Scope#proxyMode}.
* Defaults to {@link ScopedProxyMode#TARGET_CLASS}.
*/
@AliasFor(annotation = Scope.class)
ScopedProxyMode proxyMode() default ScopedProxyMode.TARGET_CLASS;
}
该注解可以用来指定作用于为 Session
的 bean
实例,这个注解好像在 Spring
官方文档中介绍 Scope
章节也有举例提到
@Transactional
@Service
@Target(TYPE)
@Retention(RUNTIME)
@Documented
public @interface TransactionalService {
/**
* @see Service#value
*/
String value() default "";
@AliasFor(annotation = Transactional.class, attribute = "transactionManager")
String transactionManager() default "";
@AliasFor(annotation = Transactional.class, attribute = "propagation")
Propagation propagation() default Propagation.REQUIRED;
@AliasFor(annotation = Transactional.class, attribute = "isolation")
Isolation isolation() default Isolation.DEFAULT;
@AliasFor(annotation = Transactional.class, attribute = "timeout")
int timeout() default TransactionDefinition.TIMEOUT_DEFAULT;
@AliasFor(annotation = Transactional.class, attribute = "readOnly")
boolean readOnly() default false;
@AliasFor(annotation = Transactional.class, attribute = "rollbackFor")
Class<? extends Throwable>[] rollbackFor() default {};
@AliasFor(annotation = Transactional.class, attribute = "rollbackForClassName")
String[] rollbackForClassName() default {};
@AliasFor(annotation = Transactional.class, attribute = "noRollbackFor")
Class<? extends Throwable>[] noRollbackFor() default {};
@AliasFor(annotation = Transactional.class, attribute = "noRollbackForClassName")
String[] noRollbackForClassName() default {};
}
这个注解相当于 @Transactional
+ @Service
,我觉得这是个很有用的注解,不知道官方为什么还没采用
同样还有一个有意思的项目 [Spring Polyglot](https://github.com/sbrannen/spring-polyglot),比如设计一个德语版的注解类
本文即 Spring
注解编程模型的介绍
https://github.com/spring-projects/spring-framework/wiki/Spring-Annotation-Programming-Model