enable的用法?Enable模块原理解析
luoboai
|这篇文章给大家聊聊关于enable的用法,以及Enable模块原理解析对应的知识点,希望对各位有所帮助,不要忘了收藏本站哦。
1、Spring或SpringBoot中我们经常会用到很多@EnableXXX注解,加上这些注解之后我们就可以‘启用’某一个功能,或者可以使用某些Bean,比如:
2、@EnableTransactionManagement启用事务、
3、@EnableAutoConfiguration开启自动装配
4、等等,那么你知道背后的原理是什么样的吗?本文简要窥探一下。
5、无论是Spring内建的,还是我们自定义的@Enable模块,基本就3种实现方式,其目标都是将指定的类定位为SpringBean:
6、引导类为@Configuration,声明Enable注解
7、@Target(ElementType.TYPE)\n@Retention(RetentionPolicy.RUNTIME)\n@Documented\n@Import(HelloworldConfiguration.class)\npublic@interfaceEnableHelloWorld{\n}
@ConfigurationClass中定义Bean
8、publicclassHelloworldConfiguration{
9、开启EnableHelloWorld注解,获取helloWorldBean
10、@Configuration@EnableHelloWorldpublicclassEnableHelloWorldBootstrap{\n\npublicstaticvoidmain(String[]args){\nAnnotationConfigApplicationContextcontext=newAnnotationConfigApplicationContext();\n//注册当前引导类(被@Configuration标注)到Spring上下文\ncontext.register(EnableHelloWorldBootstrap.class);\n//启动上下文\ncontext.refresh();\n//获取Bean\nStringhelloWorld=context.getBean("helloWorld",String.class);\nSystem.out.printf("helloWorld=%s\\n",helloWorld);\n//关闭上下文\ncontext.close();\n}\n}
执行结果:
11、实例2:导入类为ImportSelector实现
12、publicinterfaceServer{\n\nvoidstart();\nvoidclose();\nenumServerType{HTTP,TCP}\n}
@Target(ElementType.TYPE)\n@Retention(RetentionPolicy.RUNTIME)\n@Documented\n@Import(ServerImportSelector.class)\npublic@interfaceEnableServer{\nServer.ServerTypetype();\n}
根据注解属性,选择要定义的Bean
13、publicclassServerImportSelectorimplementsImportSelector{\n@OverridepublicString[]selectImports(AnnotationMetadataannotationMetadata){\nMap<String,Object>attributes=annotationMetadata.getAnnotationAttributes(EnableServer.class.getName());\nServer.ServerTypeserverType=(Server.ServerType)attributes.get("type");\nString[]importClassNames=newString[0];\nswitch(serverType){\ncaseHTTP:\nimportClassNames=newString[]{HttpServer.class.getName()};\nbreak;\ncaseTCP:\nimportClassNames=newString[]{TcpServer.class.getName()};\nbreak;\n}\nreturnimportClassNames;\n}\n}
启用Server,获取对应的功能:
14、@Configuration\n@EnableServer(type=Server.ServerType.TCP)\npublicclassEnableServerBootsrap{\npublicstaticvoidmain(String[]args){\nAnnotationConfigApplicationContextcontext=newAnnotationConfigApplicationContext();\ncontext.register(EnableServerBootsrap.class);\ncontext.refresh();\n//获取Bean\nServerserver=context.getBean(Server.class);\n//启用功能\nserver.start();\nserver.close();\ncontext.close();\n}\n}
执行结果:
15、导入类为ImportBeanDefinitionRegistrar实现
16、@Target(ElementType.TYPE)\n@Retention(RetentionPolicy.RUNTIME)\n@Documented\n@Import(ServerImportBeanDefinitionRegistrar.class)\npublic@interfaceEnableServer{\nServer.ServerTypetype();\n}
注册Bean
17、publicclassServerImportBeanDefinitionRegistrarimplementsImportBeanDefinitionRegistrar{\n@OverridepublicvoidregisterBeanDefinitions(AnnotationMetadataimportingClassMetadata,BeanDefinitionRegistryregistry){\nImportSelectorimportSelector=newServerImportSelector();//筛选Class名称集合String[]selectedClassNames=importSelector.selectImports(importingClassMetadata);//创建Bean定义Stream.of(selectedClassNames)\n//转化为BeanDefinitionBuilder对象.map(BeanDefinitionBuilder::genericBeanDefinition)\n//转化为BeanDefinition.map(BeanDefinitionBuilder::getBeanDefinition)\n.forEach(beanDefinition->{\n//注册BeanDefinition到BeanDefinitionRegistryBeanDefinitionReaderUtils.registerWithGeneratedName(beanDefinition,registry);});}\n}
启用Server,获取对应的功能:见实例2。
18、@Target(ElementType.TYPE)\n@Retention(RetentionPolicy.RUNTIME)\n@Documented\n@Import(AsyncConfigurationSelector.class)\npublic@interfaceEnableAsync{\n}
Dubbo内建模块
19、@Target({ElementType.TYPE})\n@Retention(RetentionPolicy.RUNTIME)\n@Inherited@Documented\n@Import(DubboConfigConfigurationRegistrar.class)\npublic@interfaceEnableDubboConfig{\n}
具体实现可以看下源码,都是相同的原理。
关于enable的用法,Enable模块原理解析的介绍到此结束,希望对大家有所帮助。








