1.@AliasFor 提供了给注解中的属性定义别名的功能, attribute和value互为别名。
public @interface AliasFor {
@AliasFor("attribute")
String value() default "";
@AliasFor("value")
String attribute() default "";
Class<? extends Annotation> annotation() default Annotation.class;
}
//用法1:localtion和address互为别名
public @interface ParInterface{
@AliasFor("address")
String localtion() default "33";
@AliasFor("localtion")
String address() default "33";
}
//用法2:用子注解通过别名给父注解属性赋值;即通过SubInterface(subLocation="22")
//则利用AnnotatedElementUtils方法查看ParInterface.localtion/address="22"
//该用法很常见
@ParInterface
public @interface SubInterface {
@AliasFor(annotation = ParInterface.class,value = "localtion")
String subLocation() default 1";
}
2.@Conditional满足一定条件,就将bean注入ioc容器
// 可以看出@Conditional注解作用与类和方法上
// 其value是一个Condition接口数组,需要实现Condition的接口
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Conditional {
Class<? extends Condition>[] value();
}
// Condition接口,需要实现matches方法
// OnExpressionCondition.class 对应的注解@ConditionalOnExpression String默认值"true"
// OnPropertyCondition.class 对应注解@ConditionalOnProperty 默认是String数组
// ProfileCondition.class 对应注解@Profile 默认String数组
// OnClassCondition.class 对应注解@ConditionalOnClass/MissingClass 默认class数组
// OnBeanCondition.class 对应注解@ConditionalOnBean/MissingBean 默认class数组
@FunctionalInterface
public interface Condition {
boolean matches(ConditionContext var1, AnnotatedTypeMetadata var2);
}
3.@EnableConfigurationProperties
// 1. @Configuration
+@EnableConfigurationProperties({xxx1Properties.class,xxx2Properties.class)
// 2. 给xxx1Properties加注解@ConfigurationProperties(prefix = "xxx")
// @NestedConfigurationProperty 增加复杂类配置
// 该注解使用在类上,且需要EnableConfigurationPropertiesRegistrar类的bean注入IOC容器
// 该value为数组
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import({EnableConfigurationPropertiesRegistrar.class})
public @interface EnableConfigurationProperties {
String VALIDATOR_BEAN_NAME = "configurationPropertiesValidator";
Class<?>[] value() default {};
}
4.@PropertySource
//@PropertySource(value = {"classpath:xxx.properties"})
// 会将xxx.properties中的内容放到Environment对象中
// 该注解作用于类上
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Repeatable(PropertySources.class)
public @interface PropertySource {
String name() default "";
String[] value();
boolean ignoreResourceNotFound() default false;
String encoding() default "";
Class<? extends PropertySourceFactory> factory() default PropertySourceFactory.class;
}
5.@Import
// @Import({xxx.class}) 注入xxx.class对象到IOC容器
// 或实现ImportSelector接口中String[] selectImports()
// 实现ImportBeanDefinitionRegistrar接口中registerBeanDefinitions方法:向registry
// 注册bean(可以给bean起名字)
//
// 1.ConfigurationClassPostProcessor
// 2.ConfigurationClassParser.parse(BeanDefinitionHolder.AnnotatedGenericBeanDefinition
// 启动类)解析出很多ConfigurationClass。
// 在2步骤的过程中
// 自动配置原理@Import({AutoConfigurationImportSelector.class})
// AutoConfigurationImportSelector.selectImports()->{
// AutoConfigurationImportSelector.AutoConfigurationEntry autoConfigurationEntry = // this.getAutoConfigurationEntry(...)->{
// List<String> configurations =
// this.getCandidateConfigurations(annotationMetadata, attributes)->{
// //从SpringFactoriesLoader.cache中加载key为EnableAutoConfiguration.class
// // value为所有自动配置类
// List<String> configurations = SpringFactoriesLoader.loadFactoryNames(
// EnableAutoConfiguration.class,...)
// 3.ConfigurationClassBeanDefinitionReader.loadBeanDefinitionsloadBeanDefini
// tions(很多ConfigurationClass)->DefaultListableBea
// nFactory.registerBeanDefinition(单个ConfigurationClass)
//@Import({Registrar.class})
//public @interface AutoConfigurationPackage
// 向ioc容器注册单例bean对象AutoConfigurationPackages$BasePackages 属性List<String> //packages; packages[0]='AutoConfigurationPackage注解所在基包路径'
//该注解作用于类,默认class数组
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Import {
Class<?>[] value();
}
// @ImportResource(locations = "classpath:xxx.xml"),该注解作用于类
6.@ComponentScan
// 该注解作用于类 ,value和basePackages互为别名,MyTypeFilter类实现TypeFilter
// 接口match方法
// @ComponentScan(basePackages = "com.learn",includeFilters = {
// @Filter(type = FilterType.ASSIGNABLE_TYPE,classes = {Person.class}),
// @Filter(type = FilterType.CUSTOM,classes = {MyTypeFilter.class}),
// },useDefaultFilters = false)
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
@Documented
@Repeatable(ComponentScans.class)
public @interface ComponentScan {
@AliasFor("basePackages")
String[] value() default {};
@AliasFor("value")
String[] basePackages() default {};
Class<?>[] basePackageClasses() default {};
String resourcePattern() default "**/*.class";
// compoent/service/repository/controller注解自动检测
boolean useDefaultFilters() default true;
ComponentScan.Filter[] includeFilters() default {};
ComponentScan.Filter[] excludeFilters() default {};
boolean lazyInit() default false;
@Retention(RetentionPolicy.RUNTIME)
@Target({})
public @interface Filter {
FilterType type() default FilterType.ANNOTATION;
@AliasFor("classes")
Class<?>[] value() default {};
@AliasFor("value")
Class<?>[] classes() default {};
String[] pattern() default {};
}
}
7.@Autowired+@Qulifier或@Resource该注解作用于类、方法、字段。
8.@RequestMapping
// 该注解作用与类和方法
// value 可以是多个路径
// params={"param1","!param2","param3=value1","param4!=value2"}
// 请求参数必须携带param1和param3=value1和param4!=value2,不能携带param2,
// consumes 指定处理请求的提交类型Content-Type
// produces 指定返回的内容类型 Accept
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Mapping
public @interface RequestMapping {
String name() default "";
@AliasFor("path")
String[] value() default {};
@AliasFor("value")
String[] path() default {};
RequestMethod[] method() default {};
String[] params() default {};
String[] headers() default {};
String[] consumes() default {};
String[] produces() default {};
}