【问题标题】:Injecting a Spring Data Rest repository into a utility class将 Spring Data Rest 存储库注入实用程序类
【发布时间】:2015-01-01 04:35:15
【问题描述】:

在搜索了一天之后,尝试了所有配置(应用程序上下文)和注释(自动装配、注入、组件等),我似乎无法让我的 pojo 类成功地注入一个工作存储库——该值始终为空。 我开始怀疑除了控制器之外的任何东西注入是否与 spring data rest 的架构相反。

这是我的应用程序上下文(取自 spring 文档):

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:jpa="http://www.springframework.org/schema/data/jpa"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
     http://www.springframework.org/schema/beans/spring-beans.xsd
     http://www.springframework.org/schema/data/jpa
     http://www.springframework.org/schema/data/jpa/spring-jpa.xsd">

    <jpa:repositories base-package="com.test.springservice"/>

</beans>

我的主要类在:

package com.test.springservice;

import ...

@Configuration
@ComponentScan
@EnableJpaRepositories
@Import(RepositoryRestMvcConfiguration.class)
@ImportResource("classpath:WEB-INF/applicationContext.xml")
@EnableAutoConfiguration
@PropertySource("application.properties")
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

我的工作存储库和模型:

package com.test.springservice.greek;

import ...

@RepositoryRestResource
public interface GreekLetterRepository extends CrudRepository<GreekLetter, Integer> {
    @Query("SELECT l FROM GreekLetter l WHERE l.translit Like :translit% ORDER BY length(l.translit) Desc")
    public List<GreekLetter> findByTranslitStartsWith(@Param("translit") String translit);

}

package com.test.springservice.greek.model;

import ....

@Entity
@Table(name="letters", catalog="greek")
public class GreekLetter extends Letter {
    public GreekLetter() {}
    public GreekLetter(String name, String translit, String present, String types) { super(name,translit,present,types); }
}

最后,我无法将存储库注入的类:

package com.test.springservice.greek.model;

import ...

public class GreekString extends Letters {

    @Autowired
    public GreekLetterRepository repository; // this is null (class not managed by container)

    public GreekString(String str) {
        super();
        setTranslit(str);
        if (this.getTranslit().equals(this.getPresent())) { setPresent(str); }
    }
    public void setTranslit(String str) { // litterates from str as translit
        List<Letter> lets = new ArrayList<Letter>();
        for (int i = 0; i < str.length(); i++) {
            String partialWord = str.substring(i);
            String partialWord0 = partialWord.substring(0,1);
            List<GreekLetter> potentialMatches = repository.findByTranslitStartsWith(partialWord0);
            ....
        }
        ....        
    }
    ....
}

有没有人看到这种方法的基本缺陷?

提前致谢。

【问题讨论】:

    标签: spring dependency-injection spring-boot spring-data-rest


    【解决方案1】:

    问题是您使用 repository BEFORE Spring 有机会通过 @Autowired 注释将其注入。

    一种解决方法是使用基于构造函数的 GreekLetterRepository 接线:

    public GreekString(String str, GreekLetterRepository greekLetterRepository)

    我看不到你在哪里实例化这个 bean,但如果它在 java 配置中,你可以这样做:

    @Bean
    public GreekString something(GreekLetterRepository greekLetterRepository) {
        return GreekString("something", greekLetterRepository);
    }
    

    现在它应该可以正常工作了。

    但是,我建议不要立即在构造函数中使用存储库,使用依赖 bean 的更好地方是在整个 bean 干净初始化之后,您可以使用 @PostConstruct 注释一个方法,以便在 bean 被调用时调用完全初始化,这样:

    public class GreekString extends Letters {
    
        @Autowired
        public GreekLetterRepository repository; 
    
        public GreekString(String str) {
            super();
    
        }
       .....
    
        @PostConstruct   
        public void init() {
           setTranslit(str);
           ...
        }
    }
    

    还有一点:

    @EnableJpaRepositories("com.test.springservice:) 和 xml jpa:repositories 作用相同,您可以继续删除 xml 配置

    【讨论】:

    • 更好的是,他使用 Spring Boot 他可以完全删除它,同样适用于@PropertySource@Import(RepositoryRestMvcConfiguration.class)。只会留下@Configuration@ComponentScan@EnableAutoConfiguration,可以用@SpringBootApplication 替换(如果使用的是Spring Boot 1.2.0 版本)。
    • 尚未接受答案,因为即使进行了更改,我仍然在注入的存储库中得到空值。
    • 如果您可以在 github 存储库中分享您的代码,我可以向您发送修复程序。很难看出问题可能来自于 sn-ps。
    • 你没有在任何地方将GreekString定义为Spring bean,这就是问题所在,Spring只有在它们知道的情况下才能自动装配bean,如果你使用new GreekString()绕过Spring,那么它对 Spring 根本不可见,因此无法自动装配。就像一个演示一样,我在这里制作了 GreekString 一个 Spring bean 并看到 @PostConstructafterPropertiesSet 被调用 - github.com/bijukunjummen/clovis/tree/fixgreekstring
    • 克隆了您的 GitHub 存储库,使用 maven 构建并启动了容器(使用 startcontainer.sh),当我点击 localhost:8080/greekWords/1 Strange 时,仍然没有看到 PostConstruct 或 afterPropertiesSet 被调用
    猜你喜欢
    • 1970-01-01
    • 2017-12-02
    • 2017-04-30
    • 2014-06-21
    • 2017-10-18
    • 1970-01-01
    • 2018-05-25
    • 2015-07-26
    • 2016-07-06
    相关资源
    最近更新 更多