【问题标题】:lombok @RequiredArgsConstructor how to inject value to the constructor spring bootlombok @RequiredArgsConstructor 如何将值注入构造函数spring boot
【发布时间】:2020-12-02 10:27:21
【问题描述】:

我有一个带有 lombok @RequiredArgsConstructor 的课程:

@RequiredArgsConstructor
@Service
public class Test{

private final String str;
private String str5;

// more code

}

在非弹簧启动中,我们在 xml 中提供:

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

如何通过 spring boot 实现相同的功能可能是通过 application.properties 但如何注入

【问题讨论】:

  • 这有帮助吗? stackoverflow.com/questions/37671467/… 并且如果您想在 spring 上下文中注入已经可用的 bean,例如任何使它们成为最终版本的存储库都会注入它们。 private final SomeRepository repository
  • 在这种情况下,它不会编译。在我的情况下,它给出的错误是:com.abc.Test 中的构造函数的参数 0 需要一个找不到的“java.lang.String”类型的 bean
  • 您是否将 String 变量注释为 @NonNull ?
  • 不要为此添加 Lombok。它期待一个字符串 bean,而不是从属性注入的值。在构造函数参数上使用@Value("${xyz"})。您可以使用lombok,但是将注释应用于构造函数会变得非常混乱。请参阅onConstructor 文档,

标签: java spring-boot lombok constructor-injection


【解决方案1】:

@Service 注释需要被移除,并且 bean 必须在 @Configuration 类中创建,并带有返回该类类型的 @Bean 注释方法。

//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);
    }

}

注意:@SpringBootApplication 暗示 @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

结果:

Test(str=print me, str5=null)

【讨论】:

    【解决方案2】:

    在这种情况下,我认为您最好对字段进行注释:

    @Service
    public class Test{
    
        @Value("${xyz}")
        private String str;
    
        private String str5;
    
        // more code
    }
    

    或使用带注释的参数显式定义构造函数:

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

    如果您有其他 final 字段,您可以将 lombok 构造函数生成与字段注释相结合,如 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
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-01-02
      • 2020-07-26
      • 1970-01-01
      • 1970-01-01
      • 2022-01-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多