Tuesday 16 May 2023

Micronaut: @EachBean, @EachProperty example

@EachBean allows to define beans from the presence of other bean definitions. In general, it is used in conjunciton with @EachProperty annotation.

 

For example,

@EachProperty(value = "app.datasource")
public class DataSourceConfiguration {

}

 

In the above example a new DataSourceConfiguration bean will be created for each item under the property key 'app.datasource' in application configuration. One can then drive the configuration of other beans with the @EachBean annotation.

@Factory
public class DatasourceFactory {

  @EachBean(DataSourceConfiguration.class)
  SqlDatasource dataSource(DataSourceConfiguration configuration) {
    return new SqlDatasource(configuration);
  }
}

The above example defines a bean Factory that creates instances of SqlDatasource.

 

The @EachBean annotation indicates that a new SqlDatasource bean will be created for each DataSourceConfiguration defined in the previous section. The DataSourceConfiguration instance is injected as a method argument and used to drive the configuration of each SqlDatasource.

 

Note that @EachBean requires that the parent bean has a @Named qualifier, since the qualifier is inherited by each bean created by @EachBean.

 

Find the below working application.

 

Step 1: Create new maven project ‘micronaut-each-property-each-bean-demo’.

 

Step 2: Update pom.xml with maven dependencies.

 

pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.sample.app</groupId>
  <artifactId>micronaut-each-property-each-bean-demo</artifactId>
  <version>1</version>

  <parent>
    <groupId>io.micronaut</groupId>
    <artifactId>micronaut-parent</artifactId>
    <version>3.7.3</version>
  </parent>


  <properties>
    <maven-compiler-plugin.version>3.8.1</maven-compiler-plugin.version>

    <maven.compiler.target>15</maven.compiler.target>
    <maven.compiler.source>15</maven.compiler.source>
  </properties>

  <dependencies>

    <dependency>
      <groupId>io.micronaut</groupId>
      <artifactId>micronaut-inject-java</artifactId>
    </dependency>

    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-api</artifactId>
    </dependency>
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-simple</artifactId>
    </dependency>

  </dependencies>

  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>${maven-compiler-plugin.version}</version>
        <configuration>
          <annotationProcessorPaths>
            <path>
              <groupId>io.micronaut</groupId>
              <artifactId>micronaut-inject-java</artifactId>
            </path>
          </annotationProcessorPaths>
        </configuration>
      </plugin>

      <plugin>
        <artifactId>maven-assembly-plugin</artifactId>
        <configuration>
          <archive>
            <manifest>
              <mainClass>com.sample.app.App</mainClass>
            </manifest>
          </archive>
          <descriptorRefs>
            <descriptorRef>jar-with-dependencies</descriptorRef>
          </descriptorRefs>
        </configuration>

        <executions>
          <execution>
            <id>make-assembly</id>
            <phase>package</phase>
            <goals>
              <goal>single</goal>
            </goals>
          </execution>
        </executions>
      </plugin>


    </plugins>
  </build>
</project>

Step 3: Create application.yml file under src/main/resources folder.

 

application.yml

app:   
  datasource:
    devSource:
      connection-timeout: 3000
      max-lifetime: 4000
      maximum-pool-size: 5
      url: jdbc:mysql://localhost/dev
    qaSource:
      connection-timeout: 5000
      max-lifetime: 6000
      maximum-pool-size: 6
      url: jdbc:mysql://localhost/qa
    prodSource:
      connection-timeout: 7000
      max-lifetime: 8000
      maximum-pool-size: 7
      url: jdbc:mysql://localhost/prod

Step 4: Define DataSourceConfiguration class.

 

DataSourceConfiguration.java

package com.sample.app.configuration;

import io.micronaut.context.annotation.EachProperty;
import io.micronaut.context.annotation.Parameter;

@EachProperty(value = "app.datasource")
public class DataSourceConfiguration {

  private Integer connectionTimeout;

  private Integer maxLifetime;

  private Integer maximumPoolSize;

  private String name;

  private String url;

  public DataSourceConfiguration(@Parameter String name) {
    this.name = name;
  }

  public Integer getConnectionTimeout() {
    return connectionTimeout;
  }

  public void setConnectionTimeout(Integer connectionTimeout) {
    this.connectionTimeout = connectionTimeout;
  }

  public Integer getMaxLifetime() {
    return maxLifetime;
  }

  public void setMaxLifetime(Integer maxLifetime) {
    this.maxLifetime = maxLifetime;
  }

  public Integer getMaximumPoolSize() {
    return maximumPoolSize;
  }

  public void setMaximumPoolSize(Integer maximumPoolSize) {
    this.maximumPoolSize = maximumPoolSize;
  }

  public String getName() {
    return name;
  }

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

  public String getUrl() {
    return url;
  }

  public void setUrl(String url) {
    this.url = url;
  }

  @Override
  public String toString() {
    return "DataSourceConfiguration [connectionTimeout=" + connectionTimeout + ", maxLifetime=" + maxLifetime
        + ", maximumPoolSize=" + maximumPoolSize + ", name=" + name + ", url=" + url + "]";
  }

}

Step 5: Define SqlDatasource class.

 

SqlDatasource.java

package com.sample.app.datasources;

import com.sample.app.configuration.DataSourceConfiguration;

public class SqlDatasource {

  private DataSourceConfiguration dataSourceConfiguration;

  public SqlDatasource(DataSourceConfiguration dataSourceConfiguration) {
    this.dataSourceConfiguration = dataSourceConfiguration;
  }

  @Override
  public String toString() {
    return "SqlDatasource [dataSourceConfiguration=" + dataSourceConfiguration + "]";
  }

}

Step 6: Define DatasourceFactory class.

 

DatasourceFactory.java

package com.sample.app.factory;

import com.sample.app.configuration.DataSourceConfiguration;
import com.sample.app.datasources.SqlDatasource;

import io.micronaut.context.annotation.EachBean;
import io.micronaut.context.annotation.Factory;

@Factory
public class DatasourceFactory {

  @EachBean(DataSourceConfiguration.class)
  SqlDatasource dataSource(DataSourceConfiguration configuration) {
    return new SqlDatasource(configuration);
  }
}

Step 7: Define main application class.

 

App.java

package com.sample.app;

import java.util.Collection;

import com.sample.app.datasources.SqlDatasource;

import io.micronaut.context.ApplicationContext;
import io.micronaut.inject.qualifiers.Qualifiers;

public class App {

  public static void main(String[] args) {

    try (ApplicationContext applicationContext = ApplicationContext.run()) {

      SqlDatasource devSource = applicationContext.getBean(SqlDatasource.class, Qualifiers.byName("dev-source"));
      SqlDatasource qaSource = applicationContext.getBean(SqlDatasource.class, Qualifiers.byName("dev-source"));
      SqlDatasource prodSource = applicationContext.getBean(SqlDatasource.class, Qualifiers.byName("dev-source"));

      System.out.println(devSource);
      System.out.println(qaSource);
      System.out.println(prodSource + "\n");

      Collection<SqlDatasource> datasources = applicationContext.getBeansOfType(SqlDatasource.class);

      for (SqlDatasource datasource : datasources) {
        System.out.println(datasource);
      }
    }

  }
}

Total project structure looks like below.




Build the project using mvn package command.

Navigate to the folder where pom.xml is located and execute the command ‘mvn package’.

 

Upon command successful execution, you can see the jar file ‘micronaut-each-property-each-bean-demo-1-jar-with-dependencies.jar’ in project target folder.

$ls ./target/
archive-tmp
classes
generated-sources
generated-test-sources
maven-archiver
maven-status
micronaut-each-property-each-bean-demo-1-jar-with-dependencies.jar
micronaut-each-property-each-bean-demo-1.jar
test-classes

Execute below command to run the application.

java -jar ./target/micronaut-each-property-each-bean-demo-1-jar-with-dependencies.jar
$java -jar ./target/micronaut-each-property-each-bean-demo-1-jar-with-dependencies.jar
SqlDatasource [dataSourceConfiguration=DataSourceConfiguration [connectionTimeout=3000, maxLifetime=4000, maximumPoolSize=5, name=dev-source, url=jdbc:mysql://localhost/dev]]
SqlDatasource [dataSourceConfiguration=DataSourceConfiguration [connectionTimeout=3000, maxLifetime=4000, maximumPoolSize=5, name=dev-source, url=jdbc:mysql://localhost/dev]]
SqlDatasource [dataSourceConfiguration=DataSourceConfiguration [connectionTimeout=3000, maxLifetime=4000, maximumPoolSize=5, name=dev-source, url=jdbc:mysql://localhost/dev]]

SqlDatasource [dataSourceConfiguration=DataSourceConfiguration [connectionTimeout=7000, maxLifetime=8000, maximumPoolSize=7, name=prod-source, url=jdbc:mysql://localhost/prod]]
SqlDatasource [dataSourceConfiguration=DataSourceConfiguration [connectionTimeout=5000, maxLifetime=6000, maximumPoolSize=6, name=qa-source, url=jdbc:mysql://localhost/qa]]
SqlDatasource [dataSourceConfiguration=DataSourceConfiguration [connectionTimeout=3000, maxLifetime=4000, maximumPoolSize=5, name=dev-source, url=jdbc:mysql://localhost/dev]]

You can download this application from this link.


Previous                                                    Next                                                    Home

No comments:

Post a Comment