Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using @ConfigurationProperties in a @Scheduled annotation by referencing the bean name

I'm using @ConfigurationProperties to configure the delay of a background task in Spring boot and I'm trying to use this value from a @Scheduled annotation on another component. However, in order to make it work I must use the full name given to the bean by Spring.

The configuration properties class is as follows:

@ConfigurationProperties("some")
class SomeProperties {
    private int millis; //the property is some.millis

    public int getMillis() {
        return millis;
    }

    public void setMillis(int millis) {
         this.millis = millis;
    }
}

And I'm using the value as follows in the scheduled method:

@Component
class BackgroundTasks {

    @Scheduled(fixedDelayString = "#{@'some-com.example.demo.SomeProperties'.millis}") //this works.
    public void sayHello(){
        System.out.println("hello");
    }
}

Is it possible to reference the value without having to use the full name of the bean? This answer suggests it is possible but I haven't been able to make it work.

like image 351
sbaldrich Avatar asked Feb 28 '18 16:02

sbaldrich


People also ask

Does @ConfigurationProperties create a bean?

You could extend the DataSource class multiple times for each seperate database and add the @ConfigurationProperties to each one, Or you could create a bean for each one with the appropriate property prefix. e.g. ( @ConfigurationProperties(prefix="spring. datasource.

What is the use of @configuration in spring boot?

Spring @Configuration annotation is part of the spring core framework. Spring Configuration annotation indicates that the class has @Bean definition methods. So Spring container can process the class and generate Spring Beans to be used in the application.

What is @scheduled in spring boot?

The @EnableScheduling annotation is used to enable the scheduler for your application. This annotation should be added into the main Spring Boot application class file. @SpringBootApplication @EnableScheduling public class DemoApplication { public static void main(String[] args) { SpringApplication.

What is @EnableConfigurationProperties?

@EnableConfigurationProperties annotation is strictly connected to @ConfiguratonProperties. It enables support for @ConfigurationProperties annotated classes in our application. However, it's worth to point out that the Spring Boot documentation says, every project automatically includes @EnableConfigurationProperties.


2 Answers

Using @Componenton the properties class allows to access the property as "#{@someProperties.persistence.delay}.

More info in the spring boot documentation.

like image 132
sbaldrich Avatar answered Sep 20 '22 12:09

sbaldrich


SomePrperties.java

package com.example.demo;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

@ConfigurationProperties("some")
@Component("someProperties")
public class SomeProperties {

    private int millis; // the property is some.millis

    public int getMillis() {
        return millis;
    }

    public void setMillis(int millis) {
        this.millis = millis;
    }

}

BackgroundTasks.java

package com.example.demo;

import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

@Component
public class BackgroundTasks {

    /**
     * 
     * Approach1: We can inject/access the property some.millis directly in @Value
     * fashion even though we have configured it to bind with SomeProperties class
     * using @ConfigurationProperties.
     * 
     * 
     */
    @Scheduled(fixedRateString = "${some.millis}")
    public void fromDirectInjection() {

        System.out.println("Hi, I'm  from DirectInjection method");

    }

    /**
     * 
     * Approach2: Add @Component on SomeProperties and access the bean bean's
     * property millis like below using Spring Expression language
     * 
     * 
     */
    @Scheduled(fixedRateString = "#{@someProperties.millis}")
    public void fromConfigurationProperty() {
        System.out.println("Hi, I'm from ConfigurationProperty method");

    }

}

DemoApplication.java

package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;

@SpringBootApplication
@EnableScheduling
public class DemoApplication {

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

}

application.properties

some.millis=2000

Version Used

 SpringBoot 2.6.0

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<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>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.6.0-SNAPSHOT</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>demo</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>11</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
    <repositories>
        <repository>
            <id>spring-milestones</id>
            <name>Spring Milestones</name>
            <url>https://repo.spring.io/milestone</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </repository>
        <repository>
            <id>spring-snapshots</id>
            <name>Spring Snapshots</name>
            <url>https://repo.spring.io/snapshot</url>
            <releases>
                <enabled>false</enabled>
            </releases>
        </repository>
    </repositories>
    <pluginRepositories>
        <pluginRepository>
            <id>spring-milestones</id>
            <name>Spring Milestones</name>
            <url>https://repo.spring.io/milestone</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </pluginRepository>
        <pluginRepository>
            <id>spring-snapshots</id>
            <name>Spring Snapshots</name>
            <url>https://repo.spring.io/snapshot</url>
            <releases>
                <enabled>false</enabled>
            </releases>
        </pluginRepository>
    </pluginRepositories>

</project>

Output:

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::       (v2.6.0-SNAPSHOT)

2021-10-08 08:38:03.342  INFO 8092 --- [           main] com.example.demo.DemoApplication         : Starting DemoApplication using Java 14.0.2 on TO-GZ9M403-L with PID 8092 (D:\workspaces\configprop\demo (1)\demo\target\classes started by D1 in D:\workspaces\configprop\demo (1)\demo)
2021-10-08 08:38:03.345  INFO 8092 --- [           main] com.example.demo.DemoApplication         : No active profile set, falling back to default profiles: default
2021-10-08 08:38:04.884  INFO 8092 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8080 (http)
2021-10-08 08:38:04.902  INFO 8092 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2021-10-08 08:38:04.902  INFO 8092 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet engine: [Apache Tomcat/9.0.53]
2021-10-08 08:38:05.050  INFO 8092 --- [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2021-10-08 08:38:05.050  INFO 8092 --- [           main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 1631 ms
2021-10-08 08:38:05.644  INFO 8092 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8080 (http) with context path ''
Hi, I'm  from DirectInjection method
Hi, I'm from ConfigurationProperty method
2021-10-08 08:38:05.662  INFO 8092 --- [           main] com.example.demo.DemoApplication         : Started DemoApplication in 2.995 seconds (JVM running for 3.712)
Hi, I'm  from DirectInjection method
Hi, I'm from ConfigurationProperty method
Hi, I'm  from DirectInjection method
Hi, I'm from ConfigurationProperty method
Hi, I'm  from DirectInjection method
Hi, I'm from ConfigurationProperty method
like image 40
Arun Sai Avatar answered Sep 19 '22 12:09

Arun Sai