6

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

Techno
  • 91
  • 1
  • 1
  • 6
  • Does this help ? https://stackoverflow.com/questions/37671467/lombok-requiredargsconstructor-not-working 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 repository` – Sujitmohanty30 Aug 12 '20 at 16:46
  • 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 found – Techno Aug 12 '20 at 16:49
  • did you annotate the String variable as @NonNull ? – Sujitmohanty30 Aug 12 '20 at 16:50
  • 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, – Darren Forsythe Aug 12 '20 at 17:02
  • As of Spring 4.3 https://stackoverflow.com/questions/68538851/lombok-and-autowired/70653475#70653475 – Sergey Zh. Jan 11 '22 at 22:54

2 Answers2

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
}
Fede Garcia
  • 677
  • 11
  • 18
0

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)
Lennonry
  • 345
  • 1
  • 7