lombok @RequiredArgsConstructor how to inject value to the constructor spring boot
Asked Answered
I

2

7

I have a class with lombok @RequiredArgsConstructor:

@RequiredArgsConstructor
@Service
public class Test{

private final String str;
private String str5;

// more code

}

In non-spring boot we provide in xml as:

<bean id="Test" class="com.abc.Test">
        <constructor-arg index="0" value="${xyz}"/>
    </bean>

how to achieve same from spring boot may be via application.properties but how to inject

Ish answered 12/8, 2020 at 16:5 Comment(5)
Does this help ? #37671967 and if you want to inject already available beans withing spring context e.g. any repository just making them final will inject them. private final SomeRepository repositoryChlorohydrin
In this case its not compiling. In my case it gives error as: Parameter 0 of constructor in com.abc.Test required a bean of type 'java.lang.String' that could not be foundIsh
did you annotate the String variable as @NonNull ?Chlorohydrin
Don't add Lombok for this. It's expecting a String bean, not a value to be injected from properties. Use @Value("${xyz"}) on the constructor paramter. You can use lombok, but it gets really messy to apply annotations to the consturctor. See onConstructor documentation,Attalie
As of Spring 4.3 https://mcmap.net/q/717988/-lombok-and-autowired/…Adultery
C
1

The @Service annotation needs to be removed and the bean must be created in a @Configuration class with a @Bean annotated method returning that class type.

//Test.java
package com.abc;

import lombok.RequiredArgsConstructor;
import lombok.ToString;

@RequiredArgsConstructor
@ToString
public class Test {

private final String str;
private String str5;

}
//DemoApplication.java
package com.abc;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;

@SpringBootApplication
public class DemoApplication {

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

    @Bean
    Test buildTest(@Value("${xyz}") String value) {
        return new Test(value);
    }

}

note: @SpringBootApplication implies @Configuration

//DemoApplicationTests.java
package com.abc;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
class DemoApplicationTests {

    @Autowired
    com.abc.Test test;

    @Test
    void contextLoads() {
        System.out.println(test);
    }

}
#application.properties
xyz=print me

Result:

Test(str=print me, str5=null)
Cupp answered 27/8, 2020 at 21:14 Comment(0)
S
1

In this case I think you are better off either annotating the field :

@Service
public class Test{

    @Value("${xyz}")
    private String str;

    private String str5;

    // more code
}

or defining explicitly the constructor with an annotated parameter:

@Service
public class Test{

    private final String str;

    private String str5;

    public Test(@Value("${xyz}") String str) {
        this.str = str;
    }
    // more code
}

And if you have other final fields you can combine lombok constructor generation with field annotation like this as noted in Best practice for @Value fields, Lombok, and Constructor Injection?

@RequiredArgsConstructor
@Service
public class Test{

    @Value("${xyz}")
    private String str;

    private final String str5;

    // more code
}
Stinking answered 29/10, 2020 at 14:3 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.