How to Define a List Bean in Spring

How to define a List bean in Spring?

Import the spring util namespace. Then you can define a list bean as follows:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util-2.5.xsd">

<util:list id="myList" value-type="java.lang.String">
<value>foo</value>
<value>bar</value>
</util:list>

The value-type is the generics type to be used, and is optional. You can also specify the list implementation class using the attribute list-class.

Define list of a list bean in a spring?

<list>
<value>
<list>...</list>
</value>
<value>
<list>...</list>
</value>
<value>
<list>...</list>
</value>
</list>

How to define a property of type ListE in a Spring Bean?

You can do, for example, something like:

<property name="genders" type="java.util.List<com.your.package.data.GenderData>"/>

In your example, you would end up with

<bean class="my.package.MyPojoListHolder">
<property name="myPojoList" type="java.util.List<my.package.MyPojo>"></property>
</bean>

Make List of Spring Bean

Spring could autowire all beans that implement the same interface into the list like this

@Autowired
private List<Event> events;

By default, the autowiring fails whenever zero candidate beans are available; the default behavior is to treat annotated methods, constructors, and fields as indicating required dependencies. This behavior can be changed as demonstrated below. To avoid that you need to pass addtitonal parameter to annotation like this:

@Autowired(required = false)
private List<Event> events;

Here is the link to Spring documentation: https://docs.spring.io/spring/docs/current/spring-framework-reference/core.html#beans-autowired-annotation

Spring: How to programmatically fill a list of bean references in a list property on a BeanDefinition?

Once you have registered the singleton beans to the BeanFactory , you can autowire the same to any Bean as follows

@Autowired
List<Worker> workers;

Spring Container would automatically provide you the list of beans of matching type to this List reference.

From reference

With byType or constructor autowiring mode, you can wire arrays and
typed collections. In such cases, all autowire candidates within the
container that match the expected type are provided to satisfy the
dependency

If you are trying to avoid @Autowired annotation , following from BeanFactoryPostProcessor would also work . Assuming you have already added the following field to a bean named company

List<Worker> workers;

within BeanFactoryPostProcessor

List<Object> workers = new ArrayList<Object>();
workers.add(beanFactory.getBean("worker1"));
workers.add(beanFactory.getBean("worker2"));

beanFactory.getBeanDefinition("company").getPropertyValues().addPropertyValue("workers",workers);

How to contribute to a list property of a bean using Spring?

I think that code should not know about Spring if it is not really needed. Therefore I would do all initialization in Spring config.

We can use bean definition inheritance and property overriding to do it.

Framework class

public class Manager {

private List<AnInterface> theList;

public void init() {
// here we use list initialized by product
}

}

Framework context

<bean id="manager"
init-method="init"
abstract="true"
class="Manager">
<property name="theList">
<list/> <!-- this will be overriden or extnded -->
</property>
</bean>

Product A context

<bean id="managerA"
parent="manager"
scope="singleton"
lazy-init="false">
<property name="theList">
<list>
<ref bean="impl1"/>
<ref bean="impl2"/>
</list>
</property>
</bean>

Watch out for parent and child properties in such configuration. Not all are inherited from parent. Spring documentation specifies:

The remaining settings are always taken from the child definition: depends on, autowire mode, dependency check, singleton, scope, lazy init.

Moreover, there is also collection merging in Spring so by specifing in child bean

<list merge="true">

you can merge parent and child lists.


I have observed this pattern in a number of projects and some extendable Web frameworks based on Spring.

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

I've created a quick example project on 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.

How does Spring know my db table structure and the DB table <-> Java object mapping? If you want to persist your teams and players some DB, you should mark them with annotations for Spring. In the example project I put the @Entity annotation to them so Spring will know it has to store them. 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. Also I annotated the Java class field I wanted to store with the following annotations:

  • @Column: this field will be stored in a DB column. Without any further config Spring will generate the name of it's column.
  • @Id and @GeneratedValue: Spring will auto generate the id of the persisted entities and store it's value in this annotated field.
  • @OneToMany: this annotation tells Spring to create a relation between two entities. Spring will create the TEAM_PLAYERS join table because of this annotation, and store the team-player id pairs in it.

How does Spring know the database's 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). If you look at the application.yaml you can find the configuration for the DB, and Spring'll do the same. If you uncomment the commented lines Spring'll store your data under your home directory.

How does Spring sync these entities to the DB? I've created two repositories and Spring'll use them to save, delete and find data. They're interfaces (PlayerRepository and TeamRepository) and they extend CrudRepository interface which gives them some basic CRUD operations without any further work.

So far so good, but how can the users use these services? I've published these functionalities through HTTP endpoints (PlayerController and TeamController). I marked them as @RestControllers, so spring will map some HTTP queries to them. 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.

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.

Conclusion:

  • My Spring managed classes are:

    • @Entity: Player, Team
    • Repository: PlayerRepository, TeamRepository
    • @RestController: PlayerController, TeamController
  • The flow of a call: User -(HTTP)-> @RestController -> Repository(Entity) -> DB



Related Topics



Leave a reply



Submit