【问题标题】:Why spring boot does not load beans configuration in order?为什么spring boot不按顺序加载bean配置?
【发布时间】:2018-11-11 23:13:32
【问题描述】:

当我尝试运行一个 Spring Boot 项目时,它告诉我它无法自动装配一些在配置类中实例化的 bean。 我认为spring不能按顺序加载那些配置类。

堆栈跟踪:no bean found the be autowired Ignite<Long,MyEntity> myEntityCache in MyDao

这里是来源:

主类

@SpringBootApplication
// The beans in the IgniteConfig have to be loaded before dao, service, and Controller
@ComponentScan(basePackageClasses={IgniteConfig.class,AppConfig.class})
public class DemoIgnite {
   public static void main(String[] args) {
       SpringApplication.run(DemoIgnite .class, args);
   }
}

配置类 1

@Configuration
public class IgniteConfig {
@Bean
public SpringContext springContext() {
    return new SpringContext();
}

@Bean
public Ignite igniteInstance(@Autowired SpringContext springContext) {
IgniteConfiguration cfg = new IgniteConfiguration();
cfg.setIgniteInstanceName("instance");
List<CacheConfiguration> ccDas = new ArrayList<>();
CacheConfiguration cch = new CacheConfiguration<>("myEntitycache");
cch.setCacheMode(CacheMode.REPLICATED);
cch.setIndexedTypes(Long.class, myEntity.class);
ccDas.add(cch);
cfg.setCacheConfiguration( ccDas.toArray(new CacheConfiguration[0]));
SpringCacheManager springCacheManager = new SpringCacheManager();
springCacheManager.setConfiguration(cfg);
return Ignition.start(cfg);


}

@Bean
public IgniteCache<Long, MyEntity> myEntityCache(@Autowired Ignite igniteInstance) {
 return igniteInstance.cache("myEntitycache");
}

配置类 2

@Configuration
@ComponentScan({
"com.demo.repository",
"com.demo.service",
"com.demo.controller"
})
public class AppConfig {
}

道类

@Repository
public class MyDao{

@Autowired
private Ignite<Long,MyEntity> myEntityCache;
...

服务类:

@Service
public class MyService{

@Autowird
private MyDao dao;
...

控制器类:

@RestController
@RequestMapping
public class MyController{

@Autowired
private MyService service;
....

【问题讨论】:

  • 不要将它们作为参数,而是尝试在 myEntityCache() 中调用 igniteInstance(),然后从 igniteInstance() 中删除参数(因为它似乎不需要 SpringContext 来做任何事情.. Spring通常会先找到所有可能的 bean,然后再创建任何 - 所以声明的顺序应该无关紧要......(我认为,只要你没有循环,它就会根据需要对它们进行排序......)。

标签: spring spring-boot


【解决方案1】:

这意味着您的上下文中没有Ignite&lt;Long,MyEntity&gt; 类型的bean。此外,springContext bean 似乎是多余的,igniteInstance bean 没有使用它。正如moilejter 指出的那样,它可能应该是:

IgniteConfig

@Bean
public Ignite ignite() {
  ...
}

@Bean
public IgniteCache<Long, MyEntity> myEntityCache() {
  return ignite().cache("myEntitycache");
}

我的道

@Repository
public class MyDao {

  @Autowired
  private IgniteCache<Long, MyEntity> myEntityCache;

  ...
}

原则上,Spring 分几个阶段执行 bean 设置,如章节 1.3.2. Instantiating Beans docs 中所述:

  1. Bean 定义发现 - 扫描 @Configuration 类或 XML 文件等资源并收集 bean 签名。

  2. Eager bean 实例化,例如单例 - 来自第 1 点收集的定义,同时解决定义之间的依赖关系。这就是为什么没有明确的 bean 实例化顺序,因为该过程是由依赖关系驱动的。

  3. 惰性 bean 实例化,例如@Lazy 注释 - 当上下文已经启动时,只有在从代码访问时才会构造此 bean。

【讨论】:

  • 我认为这是正确的——客户要求Ignite&lt;Long,MyEntity&gt;,但配置定义了IgniteCache&lt;Long, MyEntity&gt;——这似乎是一种不同的类型......
  • @Karol Dowbecki:我仍然有同样的例外:字段 myEntityCache com.demo.dao.MyDao 需要一个找不到的 'org.apache.ignite.IgniteCache' 类型的 bean。如果我在 MyDao.class 中注释 IgniteCache 的依赖关系,Spring 启动并加载它。所以假设必须先加载IgniteConfig.class的配置,然后才能加载Appconfig.class
  • 我犯了一个错误:在我的道中:private Ignite myEntityCache;但在配置类中我有 private Ignite myEntityCache;所以不是同一类型(字符串与长),这就是为什么 spring 找不到 Bean igniteCache 问题已解决
猜你喜欢
  • 1970-01-01
  • 2016-07-05
  • 1970-01-01
  • 2021-09-02
  • 2015-07-25
  • 1970-01-01
  • 2017-11-03
  • 2015-02-24
相关资源
最近更新 更多