enable作为模块驱动在Spring Farmework、Spring Boot、Spring Cloud使用,都是通过注解的形式以@enable作为前缀,一些常用注解如

| 框架 | 注解 | 模块 |
| --- | --- | --- |
| Spring Framework | @EnableWebMvc | Web MVC模块 |
| Spring Framework | @EnableTransactionmanagement | Web MVC模块 |
| Spring Framework | @EnableCacheing | Cacheing模块 |
| Spring Framework | @EnableMBeanExport | JMX模块 |
| Spring Framework | @EnableWebFlux | Web Flux模块 |
| Spring Framework | @EnableAspectJAutoProxy | AspectJ模块 |
| Spring Boot | @EnableAutoConfiguration | 自动装配模块 |
| Spring Boot | @EnableWebManagementContext | Actuator模块 |
| Spring Boot | @EnableConfigurationProperties | 配置属性绑定模块 |
| Spring Boot | @EnableOauth2Sso | OAuth2单独登录模块 |
| Spring Cloud | @EnableEurekaServer | eureka服务模块 |
| Spring Cloud | @EnableConfigServer | 配置服务器模块 |
| Spring Cloud | @EnableFeignClients | Feign客户端模块 |
| Spring Cloud | @EnableZuulProxy | 服务网关zuul模块 |
| Spring Cloud | @EnableCircuitBreaker | 服务熔断模块 |

## 如何自定义enable开发?
### 基于ImportSelector实现注解驱动
#### 自定义接入类型
Access为接入类型的接口,下文的RPC接入和REST接入基于这个实现,定义两个接口,一个为启动,一个停止,内部嵌套一个枚举用于标识是哪一种接入
```
public interface Access {
/**
* 初始化配置
*/
void start();

/**
* 销毁配置
*/
void stop();

enum Type{
REST,
RPC
}
}

```
#### 定义RPC和REST的实现
REST实现,只是简单的打印方法
```
public class RestAccess implements Access{
@Override
public void start() {
System.out.println("rest接入配置");
}

@Override
public void stop() {
System.out.println("rest接入销毁配置");
}
}

```
RPC实现
```
public class RpcAccess implements Access{
@Override
public void start() {
System.out.println("rpc接入配置");
}

@Override
public void stop() {
System.out.println("rpc接入销毁配置");
}
}

```
#### 自定义注解EnableAccess
接入类型为RPC或者REST,AccessImportSelector在下一步骤实现
```
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Import(AccessImportSelector.class)
public @interface EnableAccess {
/**
* 接入类型
* @return
*/
Access.Type type();
}

```
#### 实现ImportSelector
定义AccessImportSelector实现ImportSelector,分别获取注解信息,根据注解获取接入类型,根据接入类型选择不同的接入类型
```
public class AccessImportSelector implements ImportSelector{
@Override
public String[] selectImports(AnnotationMetadata annotationMetadata) {
//读取EnableAccess中所有的属性方法
Map annotationAttributes = annotationMetadata.getAnnotationAttributes(EnableAccess.class.getName());
//获取属性为type的属性方法
Access.Type type = (Access.Type )annotationAttributes.get("type");
//导入的类名称数组
String [] importClassName = new String[0];
switch (type){
case RPC:
//设置为RPC,返回RpcAccess组件
importClassName = new String[]{RpcAccess.class.getName()};
break;
case REST:
//设置为REST,返回RestAccess组件
importClassName = new String[]{RestAccess.class.getName()};
}
return importClassName;
}
}
```
#### 使用
在primarySource也就是这里的DemoApplication上使用注解EnableAccess,选择接入方式,就会初始化不通的接入组件
```
@SpringBootApplication
@EnableAccess(type=Access.Type.REST)
public class DemoApplication {

public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(DemoApplication.class, args);
Access access = context.getBean(Access.class);
access.start();
access.stop();
}

}
```
### 基于ImportBeanDefinitionRegistrar实现注解驱动
这里其它步骤一样,主要区别是注解里面Import的类变了,这里是基于基于ImportBeanDefinitionRegistrar实现注解驱动实现
#### 自定义ImportBeanDefinitionRegistrar
```
public class AccessImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanDefinitionRegistry beanDefinitionRegistry) {
ImportSelector importSelector = new AccessImportSelector();
//筛选class名称集合
String[] selectedClassNames = importSelector.selectImports(annotationMetadata);
Stream.of(selectedClassNames)
.map(BeanDefinitionBuilder::genericBeanDefinition)
.map(BeanDefinitionBuilder::getBeanDefinition)
.forEach(beanDefinition ->{
//注册beanDefinition到beanDefinitionRegistry
BeanDefinitionReaderUtils.registerWithGeneratedName(beanDefinition,beanDefinitionRegistry);
});
}
}

```
#### EnableAccess注解变更
这里import导入了AccessImportBeanDefinitionRegistrar
```
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Import(AccessImportBeanDefinitionRegistrar.class)
public @interface EnableAccess {
/**
* 接入类型
* @return
*/
Access.Type type();
}

```
### 实现
#### RPC接入
type=Access.Type.RPC
```
@SpringBootApplication
@EnableAccess(type=Access.Type.RPC)
public class DemoApplication {

public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(DemoApplication.class, args);
Access access = context.getBean(Access.class);
access.start();
access.stop();
}

}
```
![file](https://img2018.cnblogs.com/blog/1747067/201909/1747067-20190910091130214-1566835043.jpg)
#### REST接入
type=Access.Type.REST
```
@SpringBootApplication
@EnableAccess(type=Access.Type.REST)
public class DemoApplication {

public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(DemoApplication.class, args);
Access access = context.getBean(Access.class);
access.start();
access.stop();
}

}
```
![file](https://img2018.cnblogs.com/blog/1747067/201909/1747067-20190910091130769-2137286790.jpg)

最新文章

  1. position为absolute的元素如何实现居中
  2. java依赖注入
  3. 基于socket、多线程的客户端服务器端聊天程序
  4. Swift3.0 进制转换
  5. fedora yum 清缓存
  6. android中文件操作的四种枚举
  7. JavaScript 字符串处理详解【转自:http://www.cnblogs.com/mondLei/p/4096855.html】
  8. 排序算法FOUR:堆排序HeapSort
  9. 如何安装chrome扩展,以json-handle
  10. PHP - 递归函数
  11. sql笔试题
  12. line-gradient 之渐变角度
  13. 需求规格说明书(SRS)特点
  14. 使用 dom4j 处理 xml (1)
  15. C++结束进程 并能显示其父进程
  16. 在C#中对枚举进行位运算--枚举组合
  17. JavaScript -基础- 函数与对象(二)String
  18. 三个Linux权限
  19. hadoop学习---运行第一个hadoop实例
  20. 找到SVN版本机上项目的地址

热门文章

  1. 记一次paramiko远程连接遇到的坑
  2. LR有的JMeter也有之三“集合点”
  3. codeforces1088D_Ehab and another another xor problem交互题
  4. 从原理层面掌握@RequestAttribute、@SessionAttribute的使用【一起学Spring MVC】
  5. Spark 系列(七)—— 基于 ZooKeeper 搭建 Spark 高可用集群
  6. 初识JavaScript和面向对象
  7. Mysql-巧用join来优化sql
  8. git语句(后续补充)
  9. 从头开始制作OJ-在线IDE的搭建
  10. 配置Windows Server 2008环境