`
raymond.chen
  • 浏览: 1443823 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

自定义EnableXXX注解类

 
阅读更多

该自定义注解类用到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-tx源码分析(2)_Import注解+ServiceLog进阶示例代码.zip

    在本压缩包中,我们主要探讨的是Spring框架中的`@Import`注解以及基于它的`EnableXxx`机制,同时还会涉及Spring Boot和Java的相关应用。`@Import`注解是Spring框架提供的一种强大功能,它允许我们方便地导入其他配置...

    190-一起来约苗系统源码.zip

    "com.config"目录则可能包含配置类,这些类通常会使用@Configuration或@EnableXXX注解,用于声明配置和启用Spring Boot的各种特性,比如数据源配置、定时任务配置、安全配置等。 综合以上分析,"190-一起来约苗系统...

    springboot.pdf

    处理过程包括使用代理类替换原始的注解类,以便在运行时动态地生成和管理bean。 `@Bean` 注解则用于在配置类中声明一个bean。当在`@Configuration` 类的方法上使用`@Bean` 时,Spring会把该方法的结果注册为一个...

    Spring注释包

    12. `@EnableXXX`:这类注解用于开启特定功能,如`@EnableWebMvc`启用Spring MVC,`@EnableAspectJAutoProxy`启用AOP代理等。 13. `@Profile`:允许你在不同环境下选择加载特定的Bean。例如,`@Profile("dev")`会在...

    @EnableAutoConfiguration原理

    要深入理解`@EnableAutoConfiguration`,还需了解Spring框架的模块装配机制,具体体现在各种`@EnableXXX`注解中。 ##### 3.1 模块装配示例 例如常见的`@EnableFeignClients`、`@EnableScheduling`、`@EnableAsync`...

    第二节.zip

    Spring框架广泛使用注解来简化配置,比如@Controller、@Service、@Repository和@EnableXXX等,这些注解使得代码更加简洁,同时也增强了可读性和可维护性。"02-ext"可能表示这是关于Spring扩展性的第二个主题,可能...

    Spring Boot引入swagger-ui 后swagger-ui.html无法访问404的问题

    接下来,创建一个配置类`Swagger2Config`,使用`@EnableSwagger2`注解开启Swagger功能,并通过`@Bean`方法定义一个Docket实例,来指定需要扫描的API路径: ```java @Configuration @EnableSwagger2 @Profile(...

    基于SIP开发软件电话的一些资源(转自YOUTOO)

    /usr/lib之类的目录下,c源程序里直接写#include &lt;xxx.h&gt;时,能直接去找到它们,在VC里,同样的,最简单的方法就是将oSIP2源码包中的Include目录下的 osipparser2目录直接拷到我们的Windows下...

Global site tag (gtag.js) - Google Analytics