【问题标题】:How to inject property values into Spring Boot component如何将属性值注入 Spring Boot 组件
【发布时间】:2017-03-18 19:26:10
【问题描述】:

在我的 Spring Boot 应用程序中,我使用调用存储过程的方法实现了以下类。

@Component
@ConfigurationProperties(prefix = "spring")
public class FmTrfUtil {
    static int returnVal;
    @Value("${spring.datasource.url}")
    static String url;

    public static int insertFmTrfs(List<String> trfs, String source) {
        System.out.println(url);
        EntityManager em = Persistence.createEntityManagerFactory("RIStore_FM").createEntityManager();
        Session session = em.unwrap( Session.class );
        final String[] trfArray = trfs.toArray(new String[trfs.size()]);
        final String src = source;

        session.doWork( new Work(){
            public void execute(Connection conn) throws SQLException {
                CallableStatement stmt = null;               
                OracleConnection oraCon = conn.unwrap(OracleConnection.class);
                Array array = oraCon.createARRAY("VARCHAR2_TAB_T", trfArray);
                stmt = conn.prepareCall("{? = call FM_TRF_UTIL.process_fm_trf(?,?)}");
                stmt.registerOutParameter(1, Types.INTEGER);
                stmt.setArray(2, array);
                stmt.setString(3, src);
                stmt.execute();
                returnVal = stmt.getInt(1);
            }
        });
        return returnVal;
    }
}

由于调用存储过程需要连接数据库,我需要从application.properties中加载这些对应的属性值:

spring.profiles.active=dev
spring.datasource.url=jdbc:oracle:thin:@ldap://xxx:389/risdev3, cn=OracleContext,dc=x,dc=net
spring.datasource.username=owner
spring.datasource.password=owner987

基于以下关于类似问题的文章Spring boot - custom variables in Application.propertiesUsing Spring-Boot configuration properties in your own classesSpring Boot @ConfigurationProperties example,我为我的类@ConfigurationProperties(prefix = "spring") 添加了这个注释(db 连接的属性都以“spring”作为前缀)。但是,当我使用如下测试类运行它时,出现错误“应用程序必须提供 JDBC 连接”,这意味着 application.properties 中的属性未被拾取。

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = RistoreWebApplication.class, initializers = ConfigFileApplicationContextInitializer.class)
public class FmTrfUtilTest {
    @Test
    public void test() {
        List<String> trfs = new ArrayList<String>();
        trfs.add("TRF000001");
        trfs.add("TRF000002");
        int ret = FmTrfUtil.insertFmTrfs(trfs, "SARC");
        assertTrue(ret > 0);
    }
}

为了让@ConfigurationProperties 工作,我也添加了maven 依赖spring-boot-configuration-processor。为什么它仍然不起作用?我错过了什么?

【问题讨论】:

    标签: jdbc spring-boot configuration spring-properties


    【解决方案1】:

    这里有一些问题:

    • @Value 不适用于静态字段
    • @ConfigurationProperties 用于将来自application.propertiesapplication.yml 的字段绑定到Java 对象。查看 Spring Boot 本身中的任何 @ConfigurationProperties 注释类,以轻松了解应该如何使用它。
    • 你不应该使用自己的 @ConfigurationProperties 前缀 spring 因为它已经被 Spring Boot 本身使用了
    • spring-boot-configuration-processor 仅用于在您的 IDE 中更好地完成代码。你不需要这个。

    如果您想利用 Spring Boot 配置属性进行数据库连接,而不是像您那样创建 EntityManager

    EntityManager em = Persistence.createEntityManagerFactory("RIStore_FM").createEntityManager();
    

    假设你的依赖列表中有 Spring Data JPA Starter,你应该只注入它。

    我看到你使用了很多 static 方法和字段。这不适用于Spring。改用依赖注入并自动装配你需要的东西。

    【讨论】:

    • 我应该如何注射它们?我试图在方法上方用@PersistenceContext(unitName = "RIStore_FM") static EntityManager em; 注入EntityManager,但得到Persistence annotations are not supported on static fields 错误。如果我取出static,它不会编译说方法中的em必须声明为static
    • 方法和字段都不应该是静态的。查看 Spring Data 示例项目和参考。如果您以 Spring 方式使用 JPA 和 Spring 非常简单。
    猜你喜欢
    • 2018-10-15
    • 1970-01-01
    • 1970-01-01
    • 2019-03-18
    • 2019-06-04
    • 2020-02-07
    • 1970-01-01
    • 2015-12-26
    • 2021-11-24
    相关资源
    最近更新 更多