英文:
How to share the ArrayList across spring boot
问题
以下是您要的代码部分的翻译:
我有一个使用AWS Kinesis流的Java应用程序。
在应用程序中,我通过Kinesis流实时获取学生数据,然后根据学生ID执行某些操作。
我需要从数据库中查询一组学生,并需要检查Kinesis流中的每个学生是否在列表中。
然而,我希望只查询一次学生列表,因为这是要求之一。
此外,我希望在应用程序启动时尽快执行查询;这样,如果查询失败,我们也可以使应用程序失败。换句话说,如果查询不成功,应用程序不应运行。
这是我想要做的:
```groovy
@SpringBootApplication
@EnableScheduling
@EnableCaching
@Configuration
class Application implements CommandLineRunner {
  @Autowired
  RestTemplate restTemplate
  @Autowired
  List<Student> students
  static void main(String[] args) {
    SpringApplication app = new SpringApplication(Application)
    app.webApplicationType = WebApplicationType.NONE
    app.run(args)
  }
  @Override
  void run(String... args) throws Exception {
    try {
      // 发出请求
      List<Student> people = this.restTemplate.exchange("https://some.url.com", ...其他参数)
      this.students = people
      // 运行KCL工作者
      KclConsumer.kclWorker.run()
    } catch (Exception ex) {
      // ...
    }
  }
}
@Service
class SomeService {
  @Autowired
  RestTemplate restTemplate
  @Autowired
  List<Student> students
  void func(Student id) {
    this.students.each {
      if (id == it.id) {
        println("找到你了")
        return
      }
    }
    println("未找到")
  }
}
我尝试创建Bean并在整个项目中共享,但似乎不起作用...
class SomeConfig {
  @Bean
  List<Student> students() {
    return new ArrayList<>();
  }
}
我猜想我使用Bean的方式有问题。有人可以帮助我检查我的代码吗?
非常感谢!
<details>
<summary>英文:</summary>
I have a java application that uses aws kinesis stream. 
In the application, I get the student data in real time via kinesis stream and I have to make some action depending on the student id. 
There is a list of students that I need to query from the database, and the each student from kinesis stream needs a checking if the student is in the list or not. 
However I would like to query the list of students to the database only once, because that is one of the requirements. 
On top of that I would like to make the query as soon as the application starts; that way if the query fails we can also fail the application. In other words, if the query does not succeed the application should not run.
This is what I would like to do
```groovy
@SpringBootApplication
@EnabledScheduling
@EnableCaching
@Configuration
class Application implements CommandLineRuner {
  @Autowired
  RestTemplate restTemplate
  @Autowired
  List<Student> students
  static void main(String[] args) {
    SpringApplication app = new SpringApplication(Application);
    app.webApplicationType = WebApplicationType.NONE;
    app.run(args)
  }
  @Overrde
  void run(String... args) thows Exception {
    try {
      // make a request
      List<Student> people = this.restTemplate.exchange("https://some.url.com", ...other params)
      this.students = people
      // running kcl worker
      KclConsumer.kclWorker.run()
    } catch (Exception ex) {
      ....
    }
  }
}
@Service
class SomeService {
  @Autowired
  RestTemplate restTemplate
  @Autowired
  List<Student> students
  void func(Student id) {
    this.students.each {
      if(id == it.id) {
        println("found you")
        return;
      }
    }
    println("not found")
  }
}
I have tried creating the bean and share across the project as following but it does not seem to work...
class SomeConfig {
  @Bean
  List<Student> students() {
    return new ArrayList<>();
  }
}
I am guess how I am using bean is wrong.
Can someone help me with my code please?
Thank you in advance
答案1
得分: 0
In theory, providing it in a bean should work, but you should be sure to initialize its data in the bean.
@Bean
public List<Student> getStudents() {
RestTemplate restTemplate = new RestTemplate();
List<Student> people = restTemplate.exchange("https://some.url.com", ...other params);
return people;
}
This bean should be a singleton by default, so it should be the same list provided anywhere else a List<Student> is injected (either through constructor injection or with @Autowired).
If you are needing to use the RestTemplate in other places, you can make that a bean as well, which I believe you’ve already done, and inject it via constructor.
@Bean
public List<Student> getStudents(RestTemplate restTemplate) {
List<Student> people = restTemplate.exchange("https://some.url.com", ...other params);
return people.
}
Edit: I did a bit more research and it seems to make the list accessible, you may need to use @Resource instead of @Autowired as suggested here how to define a list bean in spring
英文:
In theory, providing it in a bean should work, but you should be sure to initialize its data in the bean.
@Bean
public List<Student> getStudents() {
    RestTemplate restTemplate = new RestTemplate();
    List<Student> people = restTemplate.exchange("https://some.url.com", ...other params);
    return people;
}
This bean should be a singleton by default, so it should be the same list provided anywhere else a List<Student> is injected (either through constructor injection or with @Autowired)
If you are needing to use the RestTemplate in other places, you can make that a bean as well, which I believe you’ve already done, and inject it via constructor.
@Bean
public List<Student> getStudents(RestTemplate restTemplate) {
    List<Student> people = restTemplate.exchange("https://some.url.com", ...other params);
    return people;
}
Edit: I did a bit more research and it seems to make the list accessible, you may need to use @Resource instead of @Autowired as suggested here
how to define a list bean in spring
答案2
得分: 0
不要制作List<Student>的bean。创建一个带有public List<Student> getStudents()方法的业务类 - 这个类应该是一个bean。
英文:
Don't make a bean of List<Student>. Make a business class with a public List<Student> getStudents() method - this class should be a bean.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论