centos7导致的spring循环依赖


声明:本文转载自https://my.oschina.net/qixiaobo025/blog/1816340,转载目的在于传递更多信息,仅供学习交流之用。如有侵权行为,请联系我,我会及时删除。

背景

由于一些变化 公司jenkins发生了迁移 老的jenkins运行在centos6 而新的jenkins运行在centos7上

结果导致某一台服务完全起不来 出现了bean循环依赖

Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'sqlSessionFactoryBean' defined in class path resource [com/f6car/report/config/MybatisConfigurer.class]: Unsatisfied de      pendency expressed through method 'sqlSessionFactoryBean' parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSourceConfig1' defined in URL [jar:file:/hom      e/opt/f6-report-server-8079/report.jar!/BOOT-INF/classes!/com/f6car/report/config/DataSourceConfig1.class]: Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creat      ing bean with name 'dataSourceInitializer': Invocation of init method failed; nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'primaryDataSource': Requested       bean is currently in creation: Is there an unresolvable circular reference? 24760     at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:749) 24761     at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:467) 24762     at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1173) 24763     at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1067) 24764     at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:513) 24765     at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483) 24766     at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) 24767     at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) 24768     at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) 24769     at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202) 24770     at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:208) 24771     at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1138) 24772     at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1066) 24773     at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireByType(AbstractAutowireCapableBeanFactory.java:1342) 24774     ... 51 common frames omitted 24775 Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSourceConfig1' defined in URL [jar:file:/home/opt/f6-report-server-8079/report.jar!/BOOT-INF/classes!/com/f6car/report/confi      g/DataSourceConfig1.class]: Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSourceInitializer': Invocation of init method failed; ne      sted exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'primaryDataSource': Requested bean is currently in creation: Is there an unresolvable circular reference? 24776     at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:564) 24777     at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483) 24778     at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) 24779     at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) 24780     at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) 24781     at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) 24782     at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:372) 24783     at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1173) 24784     at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1067) 24785     at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:513) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:513) 24786     at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483) 24787     at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) 24788     at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) 24789     at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) 24790     at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202) 24791     at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:208) 24792     at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1138) 24793     at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1066) 24794     at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:835) 24795     at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:741) 24796     ... 64 common frames omitted 24797 Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSourceInitializer': Invocation of init method failed; nested exception is org.springframework.beans.factory.BeanCurrentlyInC      reationException: Error creating bean with name 'primaryDataSource': Requested bean is currently in creation: Is there an unresolvable circular reference? 24798     at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java:137) 24799     at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization(AbstractAutowireCapableBeanFactory.java:409) 24800     at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1620) 24801     at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:555) 24802     at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483) 24803     at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) 24804     at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) 24805     at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) 24806     at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:220) 24807     at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveNamedBean(DefaultListableBeanFactory.java:1018) 24808     at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:345) 24809     at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:340) 24810     at org.springframework.boot.autoconfigure.jdbc.DataSourceInitializerPostProcessor.postProcessAfterInitialization(DataSourceInitializerPostProcessor.java:62) 24811     at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsAfterInitialization(AbstractAutowireCapableBeanFactory.java:423) 24812     at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1633) 24813     at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:555) 24814     ... 83 common frames omitted

问题

由于代码完全没有修改过 因此考虑是否由于环境发生了变化导致【目前锁定在jenkins变化】

该项目使用了多数据源 很明显这是由于循环依赖导致出现的 首先来看一下数据源配置

@Configuration @ConfigurationProperties("spring.datasource") public class DataSourceConfig1 extends AbstractDataSourceConfig {     @Bean(PRIMARY_DATA_SOURCE_NAME)     @Primary     public DataSource dataSource1() {         return this;     } }

 

@Configuration @ConfigurationProperties("spring.datasource2") @Lazy @ConditionalOnProperty(name = "spring.datasource2.url", matchIfMissing = false)   public class DataSourceConfig2 extends AbstractDataSourceConfig {     @Bean(SECOND_DATA_SOURCE_NAME)     public DataSource dataSource2() {         return this;     } }

当我们spring正常启动时候我们知道根据bean注入的顺序会依次初始化对应bean

首先分析一下出现错误的场景

  1. spring初始化controller 发觉依赖service
  2. spring初始化service发觉依赖dao
  3. spring初始化dao发觉依赖sqlSession
  4. spring初始化sqlSession发觉依赖dataSource
  5. spring初始化dataSource(见上方代码)
  6. 此时由于dataSource需要执行processor DataSourceInitializerPostProcessor
  7. 该processor会在dataSource初始化完成后调用init方法 实质上 就是

    this.beanFactory.getBean(DataSourceInitializer.class);

     

  8. 上述代码可以看到需要初始化DataSourceInitializer 而该类的作用是用于dataSource初始化执行一些脚本

  9. 该类的方法如下使用

    @PostConstruct public void init() {    if (!this.properties.isInitialize()) {       logger.debug("Initialization disabled (not running DDL scripts)");       return;    }    if (this.applicationContext.getBeanNamesForType(DataSource.class, false,          false).length > 0) {       this.dataSource = this.applicationContext.getBean(DataSource.class);    }    if (this.dataSource == null) {       logger.debug("No DataSource found so not initializing");       return;    }    runSchemaScripts(); }

     

  10. 此时applicationContext.getBean(DataSource.class) 实质上会调用某个dataSource【如果有多个怎么办???】当存在多个的时候会选择含有primary的bean 对于本篇文章就是PRIMARY_DATA_SOURCE_NAME

  11. 那么如果当PRIMARY_DATA_SOURCE_NAME还在创建过程中就会出现此问题【在此处表现在sqlSession依赖PRIMARY_DATA_SOURCE_NAME】

 

那么为何在centos6上编译出现的jar没有此问题呢???

分析

从上述描述中我们可以看到当sqlSession依赖的dataSource导致出现此问题

那么出现了两个问题

  1. 为何其他服务迁移到新环境【新的jenkins编译】没有问题
  2. 为何该服务在以前环境编译没问题在新的环境出现了问题

首先解释第二个问题

我们看了上述的分析其实很容易将依赖循环打破===》

很简单 只要我们在sqlSessionBean初始化完成之前就可以完成dataSource的初始化即可!确实很简单 但是也是个好办法

 

那么我们来看一下两边bean的初始化顺序是否发生了变化

centos7

centos6

果然出现了问题 可以正常运行【即centos6编译产生的dataSource1在前面而centos7编译产生的dataSource不在第一页 很显然controller出现在前边那么就会出现上文的结论】

从上述可以看到似乎和多数据源没有太多关系【或者说和我们理解的多数据源没有太多关系】

从过往的学习中我们知道这个bean出现的位置和在BeanFactory中注册的位置有关

而注册的位置又和扫描主键的顺序有关【但是在Springboot我们通常配置即Application所在的包】

因此我们来看一下究竟是如何注册的

@Override public BeanDefinition parse(Element element, ParserContext parserContext) {    String basePackage = element.getAttribute(BASE_PACKAGE_ATTRIBUTE);    basePackage = parserContext.getReaderContext().getEnvironment().resolvePlaceholders(basePackage);    String[] basePackages = StringUtils.tokenizeToStringArray(basePackage,          ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS);      // Actually scan for bean definitions and register them.    ClassPathBeanDefinitionScanner scanner = configureScanner(parserContext, element);    Set<BeanDefinitionHolder> beanDefinitions = scanner.doScan(basePackages);    registerComponents(parserContext.getReaderContext(), beanDefinitions, element);      return null; }

我们看到了其实通过ClassPathBeanDefinitionScanner来注册的

/**  * Perform a scan within the specified base packages.  * @param basePackages the packages to check for annotated classes  * @return number of beans registered  */ public int scan(String... basePackages) {    int beanCountAtScanStart = this.registry.getBeanDefinitionCount();      doScan(basePackages);      // Register annotation config processors, if necessary.    if (this.includeAnnotationConfig) {       AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);    }      return (this.registry.getBeanDefinitionCount() - beanCountAtScanStart); }

 

/**  * Perform a scan within the specified base packages,  * returning the registered bean definitions.  * <p>This method does <i>not</i> register an annotation config processor  * but rather leaves this up to the caller.  * @param basePackages the packages to check for annotated classes  * @return set of beans registered if any for tooling registration purposes (never {@code null})  */ protected Set<BeanDefinitionHolder> doScan(String... basePackages) {    Assert.notEmpty(basePackages, "At least one base package must be specified");    Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet<BeanDefinitionHolder>();    for (String basePackage : basePackages) {       Set<BeanDefinition> candidates = findCandidateComponents(basePackage);       for (BeanDefinition candidate : candidates) {          ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate);          candidate.setScope(scopeMetadata.getScopeName());          String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry);          if (candidate instanceof AbstractBeanDefinition) {             postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName);          }          if (candidate instanceof AnnotatedBeanDefinition) {             AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate);          }          if (checkCandidate(beanName, candidate)) {             BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);             definitionHolder =                   AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);             beanDefinitions.add(definitionHolder);             registerBeanDefinition(definitionHolder, this.registry);          }       }    }    return beanDefinitions; }
/**  * Scan the class path for candidate components.  * @param basePackage the package to check for annotated classes  * @return a corresponding Set of autodetected bean definitions  */ public Set<BeanDefinition> findCandidateComponents(String basePackage) {    Set<BeanDefinition> candidates = new LinkedHashSet<BeanDefinition>();    try {       String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX +             resolveBasePackage(basePackage) + '/' + this.resourcePattern;       Resource[] resources = this.resourcePatternResolver.getResources(packageSearchPath);       boolean traceEnabled = logger.isTraceEnabled();       boolean debugEnabled = logger.isDebugEnabled();       for (Resource resource : resources) {          if (traceEnabled) {             logger.trace("Scanning " + resource);          }          if (resource.isReadable()) {             try {                MetadataReader metadataReader = this.metadataReaderFactory.getMetadataReader(resource);                if (isCandidateComponent(metadataReader)) {                   ScannedGenericBeanDefinition sbd = new ScannedGenericBeanDefinition(metadataReader);                   sbd.setResource(resource);                   sbd.setSource(resource);                   if (isCandidateComponent(sbd)) {                      if (debugEnabled) {                         logger.debug("Identified candidate component class: " + resource);                      }                      candidates.add(sbd);                   }                   else {                      if (debugEnabled) {                         logger.debug("Ignored because not a concrete top-level class: " + resource);                      }                   }                }                else {                   if (traceEnabled) {                      logger.trace("Ignored because not matching any filter: " + resource);                   }                }             }             catch (Throwable ex) {                throw new BeanDefinitionStoreException(                      "Failed to read candidate component class: " + resource, ex);             }          }          else {             if (traceEnabled) {                logger.trace("Ignored because not readable: " + resource);             }          }       }    }    catch (IOException ex) {       throw new BeanDefinitionStoreException("I/O failure during classpath scanning", ex);    }    return candidates; }

 

其实整句的关键在于this.resourcePatternResolver.getResources(packageSearchPath); 这个返回的结果决定了顺序

@Override public Resource[] getResources(String locationPattern) throws IOException {    Assert.notNull(locationPattern, "Location pattern must not be null");    if (locationPattern.startsWith(CLASSPATH_ALL_URL_PREFIX)) {       // a class path resource (multiple resources for same name possible)       if (getPathMatcher().isPattern(locationPattern.substring(CLASSPATH_ALL_URL_PREFIX.length()))) {          // a class path resource pattern          return findPathMatchingResources(locationPattern);       }       else {          // all class path resources with the given name          return findAllClassPathResources(locationPattern.substring(CLASSPATH_ALL_URL_PREFIX.length()));       }    }    else {       // Generally only look for a pattern after a prefix here,       // and on Tomcat only after the "*/" separator for its "war:" protocol.       int prefixEnd = (locationPattern.startsWith("war:") ? locationPattern.indexOf("*/") + 1 :             locationPattern.indexOf(":") + 1);       if (getPathMatcher().isPattern(locationPattern.substring(prefixEnd))) {          // a file pattern          return findPathMatchingResources(locationPattern);       }       else {          // a single resource with the given name          return new Resource[] {getResourceLoader().getResource(locationPattern)};       }    } }
/**  * Find all resources that match the given location pattern via the  * Ant-style PathMatcher. Supports resources in jar files and zip files  * and in the file system.  * @param locationPattern the location pattern to match  * @return the result as Resource array  * @throws IOException in case of I/O errors  * @see #doFindPathMatchingJarResources  * @see #doFindPathMatchingFileResources  * @see org.springframework.util.PathMatcher  */ protected Resource[] findPathMatchingResources(String locationPattern) throws IOException {    String rootDirPath = determineRootDir(locationPattern);    String subPattern = locationPattern.substring(rootDirPath.length());    Resource[] rootDirResources = getResources(rootDirPath);    Set<Resource> result = new LinkedHashSet<Resource>(16);    for (Resource rootDirResource : rootDirResources) {       rootDirResource = resolveRootDirResource(rootDirResource);       URL rootDirURL = rootDirResource.getURL();       if (equinoxResolveMethod != null) {          if (rootDirURL.getProtocol().startsWith("bundle")) {             rootDirURL = (URL) ReflectionUtils.invokeMethod(equinoxResolveMethod, null, rootDirURL);             rootDirResource = new UrlResource(rootDirURL);          }       }       if (rootDirURL.getProtocol().startsWith(ResourceUtils.URL_PROTOCOL_VFS)) {          result.addAll(VfsResourceMatchingDelegate.findMatchingResources(rootDirURL, subPattern, getPathMatcher()));       }       else if (ResourceUtils.isJarURL(rootDirURL) || isJarResource(rootDirResource)) {          result.addAll(doFindPathMatchingJarResources(rootDirResource, rootDirURL, subPattern));       }       else {          result.addAll(doFindPathMatchingFileResources(rootDirResource, subPattern));       }    }    if (logger.isDebugEnabled()) {       logger.debug("Resolved location pattern [" + locationPattern + "] to resources " + result);    }    return result.toArray(new Resource[result.size()]); }

 

可以看到由于我们是jar运行那么最终都走到了

result.addAll(doFindPathMatchingJarResources(rootDirResource, rootDirURL, subPattern));

我们知道jar本质上都是zip 只不过是不同的拓展名

for (Enumeration<JarEntry> entries = jarFile.entries(); entries.hasMoreElements();) {    JarEntry entry = entries.nextElement();    String entryPath = entry.getName();    if (entryPath.startsWith(rootEntryPath)) {       String relativePath = entryPath.substring(rootEntryPath.length());       if (getPathMatcher().match(subPattern, relativePath)) {          result.add(rootDirResource.createRelative(relativePath));       }    } }

因此可以看到最终的顺序其实就是jar中的顺序 而jar的顺序其实是在写入的时候就已经固定了!

我们可以使用unzip命令查看

Archive:  /data/jenkins/workspace/f6-local-test-report-server/report-web/target/report.jar.original   Length      Date    Time    Name ---------  ---------- -----   ----         0  05-03-2018 13:46   META-INF/       376  05-03-2018 13:46   META-INF/MANIFEST.MF         0  05-03-2018 13:46   j2cache/         0  05-03-2018 13:46   com/         0  05-03-2018 13:46   com/f6car/         0  05-03-2018 13:46   com/f6car/report/         0  05-03-2018 13:46   com/f6car/report/controller/         0  05-03-2018 13:46   com/f6car/report/controller/base/         0  05-03-2018 13:46   com/f6car/report/controller/part/         0  05-03-2018 13:46   com/f6car/report/controller/maintain/         0  05-03-2018 13:46   com/f6car/report/controller/finance/         0  05-03-2018 13:46   com/f6car/report/controller/custom/         0  05-03-2018 13:46   com/f6car/report/controller/item/         0  05-03-2018 13:46   com/f6car/report/controller/saPerformance/         0  05-03-2018 13:46   com/f6car/report/config/         0  05-03-2018 13:46   com/f6car/report/jwt/         0  05-03-2018 13:46   com/f6car/report/web/         0  05-03-2018 13:46   com/f6car/report/web/converter/         0  05-03-2018 13:46   com/f6car/report/web/interceptor/         0  05-03-2018 13:46   com/f6car/report/web/json/         0  05-03-2018 13:46   com/f6car/report/web/shiro/         0  05-03-2018 13:46   com/f6car/report/callback/      1749  05-03-2018 13:46   j2cache/application-unit-test.properties      1765  05-03-2018 13:46   j2cache/j2cache-local-test.properties      1796  05-03-2018 13:46   j2cache/j2cache-prod-trial.properties      1977  05-03-2018 13:46   j2cache/j2cache-dev.properties      1784  05-03-2018 13:46   j2cache/j2cache-prod.properties      1748  05-03-2018 13:46   j2cache/j2cache-re.properties      1506  05-03-2018 13:46   application-prod.properties      1196  05-03-2018 13:46   application-re.properties      1204  05-03-2018 13:46   application-local-test.properties      1093  05-03-2018 13:46   application-unit-test.properties      1859  05-03-2018 13:46   application-prod-trial.properties       991  05-03-2018 13:46   application-dev.properties      4692  05-03-2018 13:46   application.properties      5242  05-03-2018 13:46   ehcache.xml      7683  05-03-2018 13:46   logback-spring.xml      1530  05-03-2018 13:46   banner.txt     32989  05-03-2018 13:46   META-INF/spring-configuration-metadata.json      1413  05-03-2018 13:46   com/f6car/report/controller/base/SystemController.class      1433  05-03-2018 13:46   com/f6car/report/controller/base/BaseController$1.class      3150  05-03-2018 13:46   com/f6car/report/controller/base/BaseController$2.class      1834  05-03-2018 13:46   com/f6car/report/controller/base/BaseController$3.class     16088  05-03-2018 13:46   com/f6car/report/controller/base/BaseController.class      1181  05-03-2018 13:46   com/f6car/report/controller/base/DisableSwaggerUiController.class      5647  05-03-2018 13:46   com/f6car/report/controller/base/AuthController.class     11801  05-03-2018 13:46   com/f6car/report/controller/part/PartController.class      5992  05-03-2018 13:46   com/f6car/report/controller/maintain/MaintainBusinessController.class      4139  05-03-2018 13:46   com/f6car/report/controller/finance/FinanceSummaryController.class     17110  05-03-2018 13:46   com/f6car/report/controller/finance/FinanceDetailController.class      2612  05-03-2018 13:46   com/f6car/report/controller/custom/DailyCustomReportController.class     10714  05-03-2018 13:46   com/f6car/report/controller/item/ItemController.class      2215  05-03-2018 13:46   com/f6car/report/controller/saPerformance/SaCashPerformanceController.class       895  05-03-2018 13:46   com/f6car/report/config/DataSourceConfig2.class       367  05-03-2018 13:46   com/f6car/report/config/AbstractDataSourceConfig.class      2468  05-03-2018 13:46   com/f6car/report/config/ReportStatisticConfig.class      1688  05-03-2018 13:46   com/f6car/report/config/CacheConfig.class       599  05-03-2018 13:46   com/f6car/report/config/SSOConfig.class      2270  05-03-2018 13:46   com/f6car/report/config/SSO.class       804  05-03-2018 13:46   com/f6car/report/config/DataSourceConfig1.class       689  05-03-2018 13:46   com/f6car/report/config/AfterCommitConfig.class       771  05-03-2018 13:46   com/f6car/report/config/ResourceHandler.class      3750  05-03-2018 13:46   com/f6car/report/config/WebMvcConfigurer$1.class     13698  05-03-2018 13:46   com/f6car/report/config/WebMvcConfigurer.class      1064  05-03-2018 13:46   com/f6car/report/config/ResourceHandlerConfig.class      2376  05-03-2018 13:46   com/f6car/report/config/SwaggerConfig.class      4472  05-03-2018 13:46   com/f6car/report/config/ShiroConfig.class       189  05-03-2018 13:46   com/f6car/report/jwt/TokenExtractor.class      3862  05-03-2018 13:46   com/f6car/report/jwt/JwtTokenFactory.class      2429  05-03-2018 13:46   com/f6car/report/jwt/RefreshToken.class      2026  05-03-2018 13:46   com/f6car/report/jwt/RawAccessJwtToken.class      1761  05-03-2018 13:46   com/f6car/report/jwt/JwtConfig.class      1766  05-03-2018 13:46   com/f6car/report/jwt/UserContext.class       809  05-03-2018 13:46   com/f6car/report/jwt/AccessJwtToken.class       935  05-03-2018 13:46   com/f6car/report/jwt/BloomTokenVerifier.class       343  05-03-2018 13:46   com/f6car/report/jwt/TokenVerifier.class      1249  05-03-2018 13:46   com/f6car/report/jwt/Scopes.class      1532  05-03-2018 13:46   com/f6car/report/jwt/AlgTokenVerifier.class      1460  05-03-2018 13:46   com/f6car/report/jwt/DefaultTokenExtractor.class      1409  05-03-2018 13:46   com/f6car/report/jwt/IssueTokenVerifier.class       746  05-03-2018 13:46   com/f6car/report/jwt/JwtConfiguar.class      1440  05-03-2018 13:46   com/f6car/report/web/converter/MapWorkBookHandler$1.class      2852  05-03-2018 13:46   com/f6car/report/web/converter/MapWorkBookHandler.class      2137  05-03-2018 13:46   com/f6car/report/web/converter/AbstractWorkBookHandler$1.class      6726  05-03-2018 13:46   com/f6car/report/web/converter/AbstractWorkBookHandler.class       467  05-03-2018 13:46   com/f6car/report/web/converter/WorkBookHandler.class      9165  05-03-2018 13:46   com/f6car/report/web/converter/ExcelHttpMessageConverter.class      2147  05-03-2018 13:46   com/f6car/report/web/converter/NormalWorkBookHandler.class      4080  05-03-2018 13:46   com/f6car/report/web/interceptor/CleanInterceptor.class       682  05-03-2018 13:46   com/f6car/report/web/interceptor/AbstractExcludeInterceptor.class       251  05-03-2018 13:46   com/f6car/report/web/interceptor/ExcludePathable.class       735  05-03-2018 13:46   com/f6car/report/web/interceptor/SSOInterceptor.class      3245  05-03-2018 13:46   com/f6car/report/web/interceptor/CSRFInterceptor.class      5019  05-03-2018 13:46   com/f6car/report/web/interceptor/JWTTokenAuthInterceptor.class      4335  05-03-2018 13:46   com/f6car/report/web/interceptor/KissoShiroInterceptor.class       751  05-03-2018 13:46   com/f6car/report/web/json/BigIntegerValueFilter.class      2167  05-03-2018 13:46   com/f6car/report/web/shiro/ReturnUrlParamFilter.class      1530  05-03-2018 13:46   com/f6car/report/ApplicationRefreshedListener.class       910  05-03-2018 13:46   com/f6car/report/Application.class      5080  05-03-2018 13:46   com/f6car/report/callback/CustomCallback.class         0  05-03-2018 13:46   META-INF/maven/         0  05-03-2018 13:46   META-INF/maven/com.f6car.report/         0  05-03-2018 13:46   META-INF/maven/com.f6car.report/report-web/      6013  05-03-2018 13:45   META-INF/maven/com.f6car.report/report-web/pom.xml       127  05-03-2018 13:46   META-INF/maven/com.f6car.report/report-web/pom.properties ---------                     -------    272795                     105 files

果然可以看到controller出现在前面

而正常的环境下都是

Archive:  report.jar.original   Length      Date    Time    Name ---------  ---------- -----   ----         0  04-27-2018 19:52   META-INF/       376  04-27-2018 19:52   META-INF/MANIFEST.MF         0  04-27-2018 19:52   j2cache/         0  04-27-2018 19:52   com/         0  04-27-2018 19:52   com/f6car/         0  04-27-2018 19:52   com/f6car/report/         0  04-27-2018 19:52   com/f6car/report/config/         0  04-27-2018 19:52   com/f6car/report/web/         0  04-27-2018 19:52   com/f6car/report/web/converter/         0  04-27-2018 19:52   com/f6car/report/web/shiro/         0  04-27-2018 19:52   com/f6car/report/web/json/         0  04-27-2018 19:52   com/f6car/report/web/interceptor/         0  04-27-2018 19:52   com/f6car/report/controller/         0  04-27-2018 19:52   com/f6car/report/controller/saPerformance/         0  04-27-2018 19:52   com/f6car/report/controller/item/         0  04-27-2018 19:52   com/f6car/report/controller/base/         0  04-27-2018 19:52   com/f6car/report/controller/custom/         0  04-27-2018 19:52   com/f6car/report/controller/maintain/         0  04-27-2018 19:52   com/f6car/report/controller/part/         0  04-27-2018 19:52   com/f6car/report/controller/finance/         0  04-27-2018 19:52   com/f6car/report/callback/         0  04-27-2018 19:52   com/f6car/report/jwt/       991  04-27-2018 19:52   application-dev.properties      7683  04-27-2018 19:52   logback-spring.xml      1796  04-27-2018 19:52   j2cache/j2cache-prod-trial.properties      1748  04-27-2018 19:52   j2cache/j2cache-re.properties      1784  04-27-2018 19:52   j2cache/j2cache-prod.properties      1749  04-27-2018 19:52   j2cache/application-unit-test.properties      1977  04-27-2018 19:52   j2cache/j2cache-dev.properties      1765  04-27-2018 19:52   j2cache/j2cache-local-test.properties      1204  04-27-2018 19:52   application-local-test.properties      5242  04-27-2018 19:52   ehcache.xml      1093  04-27-2018 19:52   application-unit-test.properties      1530  04-27-2018 19:52   banner.txt      1064  04-27-2018 19:52   com/f6car/report/config/ResourceHandlerConfig.class      1688  04-27-2018 19:52   com/f6car/report/config/CacheConfig.class       367  04-27-2018 19:52   com/f6car/report/config/AbstractDataSourceConfig.class       771  04-27-2018 19:52   com/f6car/report/config/ResourceHandler.class      2468  04-27-2018 19:52   com/f6car/report/config/ReportStatisticConfig.class      2270  04-27-2018 19:52   com/f6car/report/config/SSO.class       895  04-27-2018 19:52   com/f6car/report/config/DataSourceConfig2.class       804  04-27-2018 19:52   com/f6car/report/config/DataSourceConfig1.class      2376  04-27-2018 19:52   com/f6car/report/config/SwaggerConfig.class       689  04-27-2018 19:52   com/f6car/report/config/AfterCommitConfig.class     13698  04-27-2018 19:52   com/f6car/report/config/WebMvcConfigurer.class      4472  04-27-2018 19:52   com/f6car/report/config/ShiroConfig.class      3750  04-27-2018 19:52   com/f6car/report/config/WebMvcConfigurer$1.class       599  04-27-2018 19:52   com/f6car/report/config/SSOConfig.class      2147  04-27-2018 19:52   com/f6car/report/web/converter/NormalWorkBookHandler.class      9165  04-27-2018 19:52   com/f6car/report/web/converter/ExcelHttpMessageConverter.class      1440  04-27-2018 19:52   com/f6car/report/web/converter/MapWorkBookHandler$1.class      2852  04-27-2018 19:52   com/f6car/report/web/converter/MapWorkBookHandler.class      2137  04-27-2018 19:52   com/f6car/report/web/converter/AbstractWorkBookHandler$1.class       467  04-27-2018 19:52   com/f6car/report/web/converter/WorkBookHandler.class      6726  04-27-2018 19:52   com/f6car/report/web/converter/AbstractWorkBookHandler.class      2167  04-27-2018 19:52   com/f6car/report/web/shiro/ReturnUrlParamFilter.class       751  04-27-2018 19:52   com/f6car/report/web/json/BigIntegerValueFilter.class      4335  04-27-2018 19:52   com/f6car/report/web/interceptor/KissoShiroInterceptor.class      3245  04-27-2018 19:52   com/f6car/report/web/interceptor/CSRFInterceptor.class       251  04-27-2018 19:52   com/f6car/report/web/interceptor/ExcludePathable.class       735  04-27-2018 19:52   com/f6car/report/web/interceptor/SSOInterceptor.class       682  04-27-2018 19:52   com/f6car/report/web/interceptor/AbstractExcludeInterceptor.class      5019  04-27-2018 19:52   com/f6car/report/web/interceptor/JWTTokenAuthInterceptor.class      4080  04-27-2018 19:52   com/f6car/report/web/interceptor/CleanInterceptor.class      2215  04-27-2018 19:52   com/f6car/report/controller/saPerformance/SaCashPerformanceController.class     10714  04-27-2018 19:52   com/f6car/report/controller/item/ItemController.class      5647  04-27-2018 19:52   com/f6car/report/controller/base/AuthController.class      1181  04-27-2018 19:52   com/f6car/report/controller/base/DisableSwaggerUiController.class      3150  04-27-2018 19:52   com/f6car/report/controller/base/BaseController$2.class      1413  04-27-2018 19:52   com/f6car/report/controller/base/SystemController.class     16088  04-27-2018 19:52   com/f6car/report/controller/base/BaseController.class      1834  04-27-2018 19:52   com/f6car/report/controller/base/BaseController$3.class      1433  04-27-2018 19:52   com/f6car/report/controller/base/BaseController$1.class      2612  04-27-2018 19:52   com/f6car/report/controller/custom/DailyCustomReportController.class      5992  04-27-2018 19:52   com/f6car/report/controller/maintain/MaintainBusinessController.class     11801  04-27-2018 19:52   com/f6car/report/controller/part/PartController.class      4139  04-27-2018 19:52   com/f6car/report/controller/finance/FinanceSummaryController.class     16621  04-27-2018 19:52   com/f6car/report/controller/finance/FinanceDetailController.class      5080  04-27-2018 19:52   com/f6car/report/callback/CustomCallback.class      1761  04-27-2018 19:52   com/f6car/report/jwt/JwtConfig.class       809  04-27-2018 19:52   com/f6car/report/jwt/AccessJwtToken.class      2026  04-27-2018 19:52   com/f6car/report/jwt/RawAccessJwtToken.class      1766  04-27-2018 19:52   com/f6car/report/jwt/UserContext.class       343  04-27-2018 19:52   com/f6car/report/jwt/TokenVerifier.class      2429  04-27-2018 19:52   com/f6car/report/jwt/RefreshToken.class      3862  04-27-2018 19:52   com/f6car/report/jwt/JwtTokenFactory.class      1532  04-27-2018 19:52   com/f6car/report/jwt/AlgTokenVerifier.class      1249  04-27-2018 19:52   com/f6car/report/jwt/Scopes.class      1409  04-27-2018 19:52   com/f6car/report/jwt/IssueTokenVerifier.class       935  04-27-2018 19:52   com/f6car/report/jwt/BloomTokenVerifier.class      1460  04-27-2018 19:52   com/f6car/report/jwt/DefaultTokenExtractor.class       189  04-27-2018 19:52   com/f6car/report/jwt/TokenExtractor.class       746  04-27-2018 19:52   com/f6car/report/jwt/JwtConfiguar.class      1530  04-27-2018 19:52   com/f6car/report/ApplicationRefreshedListener.class       910  04-27-2018 19:52   com/f6car/report/Application.class      1859  04-27-2018 19:52   application-prod-trial.properties      4692  04-27-2018 19:52   application.properties      1196  04-27-2018 19:52   application-re.properties      1506  04-27-2018 19:52   application-prod.properties     32989  04-27-2018 19:52   META-INF/spring-configuration-metadata.json         0  04-27-2018 19:52   META-INF/maven/         0  04-27-2018 19:52   META-INF/maven/com.f6car.report/         0  04-27-2018 19:52   META-INF/maven/com.f6car.report/report-web/      6013  03-22-2018 18:37   META-INF/maven/com.f6car.report/report-web/pom.xml       127  04-27-2018 19:52   META-INF/maven/com.f6car.report/report-web/pom.properties ---------                     -------    272306                     105 files

看来问题就在于这里不同的环境打包的结果【顺序】出现了些许异常

我们来查看【中间省略N步骤】我们在该jenkins机器上执行对应的File.list

groovy:000> new File("/data/jenkins/workspace/f6-local-test-report-server/report-web/target/classes/com/f6car/report").list() ===> [controller, config, jwt, web, ApplicationRefreshedListener.class, Application.class, callback] groovy:000> new File("/data/jenkins/workspace/f6-local-test-open-api/web/target/classes/com/f6car/openapi/").list() ===> [config, controller, web, jwt, callback, Application.class, converter] 

看起来这个比较特殊导致

/**  * Returns an array of strings naming the files and directories in the  * directory denoted by this abstract pathname.  *  * <p> If this abstract pathname does not denote a directory, then this  * method returns {@code null}.  Otherwise an array of strings is  * returned, one for each file or directory in the directory.  Names  * denoting the directory itself and the directory's parent directory are  * not included in the result.  Each string is a file name rather than a  * complete path.  *  * <p> There is no guarantee that the name strings in the resulting array  * will appear in any specific order; they are not, in particular,  * guaranteed to appear in alphabetical order.  *  * <p> Note that the {@link java.nio.file.Files} class defines the {@link  * java.nio.file.Files#newDirectoryStream(Path) newDirectoryStream} method to  * open a directory and iterate over the names of the files in the directory.  * This may use less resources when working with very large directories, and  * may be more responsive when working with remote directories.  *  * @return  An array of strings naming the files and directories in the  *          directory denoted by this abstract pathname.  The array will be  *          empty if the directory is empty.  Returns {@code null} if  *          this abstract pathname does not denote a directory, or if an  *          I/O error occurs.  *  * @throws  SecurityException  *          If a security manager exists and its {@link  *          SecurityManager#checkRead(String)} method denies read access to  *          the directory  */ public String[] list() {     SecurityManager security = System.getSecurityManager();     if (security != null) {         security.checkRead(path);     }     return fs.list(this); }

很明显注释也说明确实没有顺序的保证!

解决

  1. 修改dataSource依赖

    @Configuration(PRIMARY_DATA_SOURCE_NAME) @Primary @ConfigurationProperties("spring.datasource") public class DataSourceConfig1 extends AbstractDataSourceConfig { }

     

  2. 这样自然会第一个初始化成功而不至于出现循环依赖!这种改法推荐【当时设计的目的是为了可以自定义设置一些没有暴露出来的参数看来这种有概率导致循环依赖】

  3. 增加参数 由于DataSourceInitializer只有在init参数为true才会执行我们【我们不需要执行sql脚本】自然可以将该参数改为false

  4. spring.datasource.initialize=false

     

 

本文发表于2018年05月22日 10:00
(c)注:本文转载自https://my.oschina.net/qixiaobo025/blog/1816340,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责。如有侵权行为,请联系我们,我们会及时删除.

阅读 2975 讨论 1 喜欢 1

抢先体验

扫码体验
趣味小程序
文字表情生成器

闪念胶囊

你要过得好哇,这样我才能恨你啊,你要是过得不好,我都不知道该恨你还是拥抱你啊。

直抵黄龙府,与诸君痛饮尔。

那时陪伴我的人啊,你们如今在何方。

不出意外的话,我们再也不会见了,祝你前程似锦。

这世界真好,吃野东西也要留出这条命来看看

快捷链接
网站地图
提交友链
Copyright © 2016 - 2021 Cion.
All Rights Reserved.
京ICP备2021004668号-1