SpringBoot 中 AutoConfiguration的使用方法

 更新时间:2019年04月12日 11:00:21   作者:small_925_ant  
这篇文章主要介绍了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<String> configurations = this.getCandidateConfigurations(annotationMetadata, attributes); 

protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
    List<String> 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<URL> 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<String> 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呢

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

   <dependency>
      <groupId>com.fayayo</groupId>
      <artifactId>fim-registry-zookeeper</artifactId>
      <version>0.0.1-SNAPSHOT</version>
    </dependency>

    然后配置参数

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

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

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

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

完整代码

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

总结

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

相关文章

  • Java内存模型之happens-before概念详解

    Java内存模型之happens-before概念详解

    happens-before原则非常重要,它是判断数据是否存在竞争、线程是否安全的主要依据,依靠这个原则,我们解决在并发环境下两操作之间是否可能存在冲突的所有问题。下面我们就一个简单的例子稍微了解下happens-before知识,感兴趣的朋友一起看看吧
    2021-06-06
  • MyBatis游标Cursor的正确使用和百万数据传输的内存测试

    MyBatis游标Cursor的正确使用和百万数据传输的内存测试

    这篇文章主要介绍了MyBatis游标Cursor的正确使用和百万数据传输的内存测试,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-01-01
  • Java语言实现简单FTP软件 FTP软件远程窗口实现(6)

    Java语言实现简单FTP软件 FTP软件远程窗口实现(6)

    这篇文章主要为大家详细介绍了Java语言实现简单FTP软件,FTP软件远程窗口的实现方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-03-03
  • springboot 接收List 入参的几种方法

    springboot 接收List 入参的几种方法

    本文主要介绍了springboot 接收List 入参的几种方法,本文主要介绍了7种方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-03-03
  • Java利用Dijkstra和Floyd分别求取图的最短路径

    Java利用Dijkstra和Floyd分别求取图的最短路径

    本文主要介绍了图的最短路径的概念,并分别利用Dijkstra算法和Floyd算法求取最短路径,最后提供了基于邻接矩阵和邻接表的图对两种算法的Java实现。需要的可以参考一下
    2022-01-01
  • 5个步骤让你明白多线程和线程安全

    5个步骤让你明白多线程和线程安全

    本文详细讲解了多线程和线程安全的实现,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-12-12
  • SpringBoot中的Thymeleaf模板

    SpringBoot中的Thymeleaf模板

    Thymeleaf 的出现是为了取代 JSP,虽然 JSP 存在了很长时间,并在 Java Web 开发中无处不在,但是它也存在一些缺陷。在这篇文中给大家介绍了这些缺陷所存在问题,对spring boot thymeleaf 模板相关知识感兴趣的朋友跟随小编一起看看吧
    2018-10-10
  • Java 导出excel进行换行的案例

    Java 导出excel进行换行的案例

    这篇文章主要介绍了Java 导出excel进行换行的案例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-09-09
  • IO流概述分类字节流写数据三种方式及问题分析

    IO流概述分类字节流写数据三种方式及问题分析

    这篇文章主要为大家介绍了IO流概述分类字节流写数据三种方式及写数据问题分析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-12-12
  • springboot themaleaf 第一次进页面不加载css的问题

    springboot themaleaf 第一次进页面不加载css的问题

    这篇文章主要介绍了springboot themaleaf 第一次进页面不加载css的问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-10-10

最新评论