简体   繁体   English

春天的简单示例:在JavaConfig中的何处创建bean列表?

[英]Spring simple example: where create list of beans in JavaConfig?

I'm learning Spring but I don't understand where I have to fill my structure... for example, I want a list of Teams where each team have a list of players. 我正在学习Spring,但是我不知道该在哪里填充我的结构……例如,我想要一个团队列表 ,每个团队都有一个球员列表。

This is the code, i have my TeamApplication: 这是代码,我有我的TeamApplication:

@SpringBootApplication
public class TeamApplication {

    public static void main(String[] args) {
        SpringApplication.run(TeamApplication.class, args);

        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);

        Team team = context.getBean(Team.class);
        Player player = context.getBean(Player.class);
    }
}

then I have AppConfig: 然后我有AppConfig:

@Configuration
public class AppConfig {
    @Bean
    public Team team() {
        return new Team();
    }

    @Bean
    public Player player() {
        return new Player();
    }
}

so Player is: 所以播放器是:

public class Player {
    private static final Logger LOG = LoggerFactory.getLogger(Player.class);

    private String name;
    private int age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @PostConstruct
    public void init() {
        LOG.info("Player PostConstruct");
    }

    @PreDestroy
    public void destroy() {
        LOG.info("Player PreDestroy");
    }

}

and Team is: 团队是:

public class Team {
    private static final Logger LOG = LoggerFactory.getLogger(Team.class);

    private String name;
    private List<Player> listPlayer;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public List<Player> getListPlayer() {
        return listPlayer;
    }

    public void setListPlayer(List<Player> listPlayer) {
        this.listPlayer = listPlayer;
    }

    @PostConstruct
    public void init() {
        LOG.info("Team PostConstruct");
    }

    @PreDestroy
    public void destroy() {
        LOG.info("Team PreDestroy");
    }

}

Now: - Where I have to fill those lists? 现在:-我必须在哪里填写这些清单? in PostConstruct? 在PostConstruct中? But in this way i have always the same datas... in an simple Java application I first create players: 但是通过这种方式,我总是拥有相同的数据...在一个简单的Java应用程序中,我首先创建了播放器:

Player p1 = new Player();
p1.setName("A");
p1.setAge(20);
Player p2 = new Player();
p1.setName("B");
p1.setAge(21);
Player p3 = new Player();
p1.setName("C");
p1.setAge(22);

Then I create my teams: 然后,我创建我的团队:

List<Person> l1 = new LinkedList<>();
l1.add(p1);
l1.add(p2);
Team t1 = new Team();
t1.setListPlayer(l1);

List<Person> l2 = new LinkedList<>();
l2.add(p3);
Team t2 = new Team();
t1.setListPlayer(l2);

so... in Spring: 所以...在春天:

  • Where can I init my players (in PostConstruct I will get always the same name/age)? 我在哪里可以初始化我的玩家 (在PostConstruct中,我将始终获得相同的姓名/年龄)?
  • Where have I to create my listTeam ? 我在哪里创建我的listTeam After getBean in TeamApplication? 在TeamApplication中使用getBean之后?

Kind regards! 亲切的问候!

Spring isn't really meant for defining beans like your Player and Team class, where they are basically POJOs that will likely be different in each instance. Spring并不是真正用于定义诸如Player和Team类之类的bean,它们基本上是POJO,在每个实例中可能有所不同。 Where Spring beans really shine are in defining singletons that will be injected int other beans or components, such as a Controller, a service, or similar. Spring bean真正发挥作用的地方在于定义单例,这些单例将注入到其他bean或组件中,例如Controller,service或类似组件。

That said, it is possible to define beans that are not singletons. 也就是说,可以定义非单例的bean。 Just change the scope of the bean to prototype, like so: 只需将bean的范围更改为原型,如下所示:

@Bean
@Scope("prototype")
public Team team() {
    return new Team();
}

I've created a quick example project on GitHub. 我已经在GitHub上创建了一个快速的示例项目。 I need to emphasize that this is not a production ready code and you shouldn't follow it's patterns for I did't refactor it to be pretty but understandable and simple instead. 我需要强调的是,这不是生产准备就绪的代码,您不应遵循它的模式,因为我没有将其重构为漂亮但易于理解和简单的代码。

First you don't have to define the set of teams and players. 首先,您不必定义团队和球员的集合。 As you said the data will be loaded from DB, so let the users do this work. 正如您所说的,数据将从数据库中加载,因此让用户来完成这项工作。 :) Instead, you need to define the services (as spring beans) which contain the business logic for the users to do their task. :)相反,您需要定义服务(作为spring Bean),其中包含用于用户执行其任务的业务逻辑。

How does Spring know my db table structure and the DB table <-> Java object mapping? Spring如何知道我的数据库表结构和数据库表<-> Java对象映射? If you want to persist your teams and players some DB, you should mark them with annotations for Spring. 如果您想让您的团队和玩家保持某些数据库,则应使用Spring的注释来标记他们。 In the example project I put the @Entity annotation to them so Spring will know it has to store them. 在示例项目中,我给它们添加了@Entity批注,以便Spring知道它必须存储它们。 Spring use convention over configuration so if I don't define any db table names, Spring will generate some from the entity class names, in this case PLAYER , TEAM and TEAM_PLAYERS . Spring在配置上使用约定,因此,如果我没有定义任何数据库表名称,Spring将从实体类名称中生成一些名称,在本例中为PLAYERTEAMTEAM_PLAYERS Also I annotated the Java class field I wanted to store with the following annotations: 我还用以下注释注释了要存储的Java类字段:

  • @Column : this field will be stored in a DB column. @Column :此字段将存储在数据库列中。 Without any further config Spring will generate the name of it's column. 没有任何进一步的配置,Spring将生成其列的名称。
  • @Id and @GeneratedValue : Spring will auto generate the id of the persisted entities and store it's value in this annotated field. @Id@GeneratedValue :Spring将自动生成持久化实体的ID并将其值存储在此带注释的字段中。
  • @OneToMany : this annotation tells Spring to create a relation between two entities. @OneToMany :这个注释告诉Spring在两个实体之间创建一个关系。 Spring will create the TEAM_PLAYERS join table because of this annotation, and store the team-player id pairs in it. Spring会因为此注释而创建TEAM_PLAYERS连接表,并在其中存储团队球员ID对。

How does Spring know the database's URL? Spring如何知道数据库的URL? As I imported H2 db in maven's pom.xml Spring will use it, and without any configuration it'll store data in memory (which will lost between app restarts). 当我在Maven的pom.xml中导入H2 db时,Spring将使用它,并且无需任何配置即可将数据存储在内存中(在应用程序重启之间丢失)。 If you look at the application.yaml you can find the configuration for the DB, and Spring'll do the same. 如果查看application.yaml ,则可以找到数据库的配置,Spring会做同样的事情。 If you uncomment the commented lines Spring'll store your data under your home directory. 如果您取消注释注释行,Spring会将数据存储在主目录下。

How does Spring sync these entities to the DB? Spring如何将这些实体同步到数据库? I've created two repositories and Spring'll use them to save, delete and find data. 我创建了两个存储库,Spring将使用它们来保存,删除和查找数据。 They're interfaces ( PlayerRepository and TeamRepository ) and they extend CrudRepository interface which gives them some basic CRUD operations without any further work. 它们是接口( PlayerRepositoryTeamRepository ),并且扩展了CrudRepository接口,这使他们可以进行一些基本的CRUD操作,而无需任何进一步的工作。

So far so good, but how can the users use these services? 到目前为止,一切都很好,但是用户如何使用这些服务? I've published these functionalities through HTTP endpoints ( PlayerController and TeamController ). 我已经通过HTTP端点( PlayerControllerTeamController )发布了这些功能。 I marked them as @RestController s, so spring will map some HTTP queries to them. 我将它们标记为@RestController ,因此spring会将一些HTTP查询映射到它们。 Through them users can create, delete, find players and teams, and assign players to teams or remove one player from a team. 通过它们,用户可以创建,删除,查找球员和球队,以及将球员分配到球队或从球队中删除一名球员。

You can try this example if you build and start it with maven, and send some queries to these endpoints by curl or by navigating to http://localhost:8080/swagger-ui.html page. 如果您使用maven进行构建和启动,可以尝试使用此示例,然后通过curl或导航到http:// localhost:8080 / swagger-ui.html页面向这些端点发送一些查询。

I've done some more configuration for this project but those are not relevant from the aspect of your question. 我已经对该项目进行了更多配置,但是从您的问题角度来看,这些配置均不相关。 I haven't explained the project deeper but you can make some investigation about my solutions and you can find documentations on Spring's site. 我没有更深入地解释该项目,但是您可以对我的解决方案进行一些调查,并且可以在Spring的站点上找到文档。

Conclusion: 结论:

  • My Spring managed classes are: 我的Spring托管类是:

    • @Entity : Player , Team @EntityPlayerTeam
    • Repository : PlayerRepository , TeamRepository RepositoryPlayerRepositoryTeamRepository
    • @RestController : PlayerController , TeamController @RestControllerPlayerControllerTeamController
  • The flow of a call: User -(HTTP)-> @RestController -> Repository(Entity) -> DB 调用流程: User -(HTTP)-> @RestController > Repository(Entity) -> DB

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM