该自定义注解类用到ImportSelector接口类,它用于判断被@Configuration注解修饰的类是否应该被导入。处理ImportSelector接口时,bean定义已经被加载,但是bean还没有被实例化。
DeferredImportSelector接口类:继承于ImportSelector接口类,延迟选择性导入类,在所有被@Configuration注解修饰的类处理完成后才运行。DeferredImportSelector用在处理@Conditional相关的导入时特别有用。
EnableXXX >> @Import >> ImportSelector or ImportBeanDefinitionRegistrar >> 注册BeanDefinition
1、创建一个配置类
@Configuration public class SeasyImportSelectorConfig { @Bean public ServiceConfig serviceConfig(){ ServiceConfig config = new ServiceConfig(); config.setName("userService"); config.setDescription(""); return config; } }
2、创建ImportSelector的子类
/** * ImportSelector:有条件的选择被@Configuration注解标注的类进行导入 */ public class SeasyImportSelector implements ImportSelector, BeanFactoryAware { public static final String ANNOTATION_CLASS_NAME = EnableSeasy.class.getName(); private BeanFactory beanFactory; /** * 返回被选中的全限定类名的数组 * * @param annotationMetadata 自定义Enable注解类所在类中包含的所有注解类元数据 */ @Override public String[] selectImports(AnnotationMetadata annotationMetadata) { //获取注解类的所有属性 MultiValueMap<String, Object> allAnnotationAttributes = annotationMetadata.getAllAnnotationAttributes(ANNOTATION_CLASS_NAME, true); for(Iterator<String> it=allAnnotationAttributes.keySet().iterator(); it.hasNext();){ String key = it.next(); List<Object> list = allAnnotationAttributes.get(key); Object value = list.get(0); if(value instanceof String[] || value.getClass().isArray()){ System.out.println(key + "=" + Arrays.toString((String[])value)); }else{ System.out.println(key + "=" + value); } } //获取注解类所在类的所有注解类 annotationMetadata.getAnnotationTypes().forEach(System.out::println); //InterfaceNames Stream.of(annotationMetadata.getInterfaceNames()).forEach(System.out::println); //MemberClassNames Stream.of(annotationMetadata.getMemberClassNames()).forEach(System.out::println); //MetaAnnotationTypes annotationMetadata.getMetaAnnotationTypes(ANNOTATION_CLASS_NAME).forEach(System.out::println); System.out.println("ClassName: " + annotationMetadata.getClassName()); return new String[]{SeasyImportSelectorConfig.class.getName()}; } @Override public void setBeanFactory(BeanFactory beanFactory) throws BeansException { this.beanFactory = beanFactory; } }
3、创建自定义注解类
@Documented @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) //@Import注解类:表示将ImportSelector选中返回的类导入到容器中 @Import(SeasyImportSelector.class) public @interface EnableSeasy { }
4、创建一个测试用的配置类,并加入自定义 @EnableSeasy 注解类
@Configuration @EnableSeasy @ComponentScan public class EnableSeasyConfig { }
5、测试代码
public class EnableSeasyTest { public static void main(String[] args) { AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(EnableSeasyConfig.class); ServiceConfig serviceConfig = applicationContext.getBean(ServiceConfig.class); System.out.println(serviceConfig.getName()); } }
相关推荐
在本压缩包中,我们主要探讨的是Spring框架中的`@Import`注解以及基于它的`EnableXxx`机制,同时还会涉及Spring Boot和Java的相关应用。`@Import`注解是Spring框架提供的一种强大功能,它允许我们方便地导入其他配置...
"com.config"目录则可能包含配置类,这些类通常会使用@Configuration或@EnableXXX注解,用于声明配置和启用Spring Boot的各种特性,比如数据源配置、定时任务配置、安全配置等。 综合以上分析,"190-一起来约苗系统...
处理过程包括使用代理类替换原始的注解类,以便在运行时动态地生成和管理bean。 `@Bean` 注解则用于在配置类中声明一个bean。当在`@Configuration` 类的方法上使用`@Bean` 时,Spring会把该方法的结果注册为一个...
12. `@EnableXXX`:这类注解用于开启特定功能,如`@EnableWebMvc`启用Spring MVC,`@EnableAspectJAutoProxy`启用AOP代理等。 13. `@Profile`:允许你在不同环境下选择加载特定的Bean。例如,`@Profile("dev")`会在...
要深入理解`@EnableAutoConfiguration`,还需了解Spring框架的模块装配机制,具体体现在各种`@EnableXXX`注解中。 ##### 3.1 模块装配示例 例如常见的`@EnableFeignClients`、`@EnableScheduling`、`@EnableAsync`...
Spring框架广泛使用注解来简化配置,比如@Controller、@Service、@Repository和@EnableXXX等,这些注解使得代码更加简洁,同时也增强了可读性和可维护性。"02-ext"可能表示这是关于Spring扩展性的第二个主题,可能...
接下来,创建一个配置类`Swagger2Config`,使用`@EnableSwagger2`注解开启Swagger功能,并通过`@Bean`方法定义一个Docket实例,来指定需要扫描的API路径: ```java @Configuration @EnableSwagger2 @Profile(...
/usr/lib之类的目录下,c源程序里直接写#include <xxx.h>时,能直接去找到它们,在VC里,同样的,最简单的方法就是将oSIP2源码包中的Include目录下的 osipparser2目录直接拷到我们的Windows下...