栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

SpringBoot 中 AutoConfiguration的使用方法

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

SpringBoot 中 AutoConfiguration的使用方法

在SpringBoot中我们经常可以引入一些starter包来集成一些工具的使用,比如spring-boot-starter-data-redis。

使用起来很方便,那么是如何实现的呢?

代码分析

我们先看注解@SpringBootApplication,它里面包含一个@EnableAutoConfiguration

继续看@EnableAutoConfiguration注解

@import({AutoConfigurationimportSelector.class})

在这个类(AutoConfigurationimportSelector)里面实现了自动配置的加载

主要代码片段:

String[] selectimports(Annotationmetadata annotationmetadata)方法中

AutoConfigurationimportSelector.AutoConfigurationEntry autoConfigurationEntry = this.getAutoConfigurationEntry(autoConfigurationmetadata, annotationmetadata);

getAutoConfigurationEntry方法中: 

List configurations = this.getCandidateConfigurations(annotationmetadata, attributes); 

protected List getCandidateConfigurations(Annotationmetadata metadata, AnnotationAttributes attributes) {
    List configurations = SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.getBeanClassLoader());
    Assert.notEmpty(configurations, "No auto configuration classes found in meta-INF/spring.factories. If you are using a custom packaging, make sure that file is correct.");
    return configurations;
}

最后会通过SpringFactoriesLoader.loadSpringFactories去加载meta-INF/spring.factories

Enumeration urls = classLoader != null ? classLoader.getResources("meta-INF/spring.factories") : ClassLoader.getSystemResources("meta-INF/spring.factories");
 linkedMultiValueMap result = new linkedMultiValueMap();
    while(urls.hasMoreElements()) {
   URL url = (URL)urls.nextElement();
   UrlResource resource = new UrlResource(url);
   Properties properties = PropertiesLoaderUtils.loadProperties(resource);
   Iterator var6 = properties.entrySet().iterator();

   while(var6.hasNext()) {
     Entry entry = (Entry)var6.next();
     String factoryClassName = ((String)entry.getKey()).trim();
     String[] var9 = StringUtils.commaDelimitedListToStringArray((String)entry.getValue());
     int var10 = var9.length;

     for(int var11 = 0; var11 < var10; ++var11) {
String factoryName = var9[var11];
result.add(factoryClassName, factoryName.trim());
     }
   }
 }

ZookeeperAutoConfiguration

我们来实现一个ZK的AutoConfiguration    

首先定义一个ZookeeperAutoConfiguration类 

然后在meta-INF/spring.factories中加入

org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.fayayo.fim.zookeeper.ZookeeperAutoConfiguration

接下来我们看看具体的实现:

@ConfigurationProperties(prefix = "fim.register")
@Configuration
public class URLRegistry {
  private String address;
  private int timeout;
  private int sessionTimeout;
  public String getAddress() {
    if (address == null) {
      address = URLParam.ADDRESS;
    }
    return address;
  }
  public void setAddress(String address) {
    this.address = address;
  }
  public int getTimeout() {
    if (timeout == 0) {
      timeout = URLParam.CONNECTTIMEOUT;
    }
    return timeout;
  }
  public void setTimeout(int timeout) {
    this.timeout = timeout;
  }
  public int getSessionTimeout() {
    if (sessionTimeout == 0) {
      sessionTimeout = URLParam.REGISTRYSESSIONTIMEOUT;
    }
    return sessionTimeout;
  }
  public void setSessionTimeout(int sessionTimeout) {
    this.sessionTimeout = sessionTimeout;
  }
}
@Configuration
@EnableConfigurationProperties(URLRegistry.class)
@Slf4j
public class ZookeeperAutoConfiguration {
  @Autowired
  private URLRegistry url;
  @Bean(value = "registry")
  public Registry createRegistry() {
    try {
      String address = url.getAddress();
      int timeout = url.getTimeout();
      int sessionTimeout = url.getSessionTimeout();
      log.info("init ZookeeperRegistry,address[{}],sessionTimeout[{}],timeout[{}]", address, timeout, sessionTimeout);
      ZkClient zkClient = new ZkClient(address, sessionTimeout, timeout);
      return new ZookeeperRegistry(zkClient);
    } catch (ZkException e) {
      log.error("[ZookeeperRegistry] fail to connect zookeeper, cause: " + e.getMessage());
      throw e;
    }
  }
}

 ZookeeperRegistry部分实现:

public ZookeeperRegistry(ZkClient zkClient) {
    this.zkClient = zkClient;

    log.info("zk register success!");

    String parentPath = URLParam.ZOOKEEPER_REGISTRY_NAMESPACE;
    try {
      if (!zkClient.exists(parentPath)) {
 log.info("init zookeeper registry namespace");
 zkClient.createPersistent(parentPath, true);
      }
      //监听
      zkClient.subscribeChildChanges(parentPath, new IZkChildListener() {
 //对父节点添加监听子节点变化。
 @Override
 public void handleChildChange(String parentPath, List currentChilds) {
   log.info(String.format("[ZookeeperRegistry] service list change: path=%s, currentChilds=%s", parentPath, currentChilds.toString()));
   if(watchNotify!=null){
     watchNotify.notify(nodeChildsToUrls(currentChilds));
   }
 }
      });

      ShutDownHook.registerShutdownHook(this);

    } catch (Exception e) {
      e.printStackTrace();
      log.error("Failed to subscribe zookeeper");
    }
  }

具体使用

那么我们怎么使用自己写的ZookeeperAutoConfiguration呢

 首先要在需要使用的项目中引入依赖

   
      com.fayayo
      fim-registry-zookeeper
      0.0.1-SNAPSHOT
    

    然后配置参数

 fim:
   register:
    address: 192.168.88.129:2181
    timeout: 2000

   如果不配置会有默认的参数

    具体使用的时候只需要在Bean中注入就可以了,比如

@Autowired
  private Registry registry;
  public List getAll(){
    Listlist=cache.get(KEY);
    if(CollectionUtils.isEmpty(list)){
      list=registry.discover();
      cache.put(KEY,list);
    }
    return list;
  }

完整代码

https://github.com/lizu18xz/fim.git

总结

以上所述是小编给大家介绍的SpringBoot 中 AutoConfiguration的使用方法,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对考高分网网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/138396.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号