将 Spring Data Rest 存储库注入实用程序 class

Injecting a Spring Data Rest repository into a utility class

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

这是我的应用程序上下文(取自 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>

我的主要 class 在以下位置绘制此上下文:

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

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

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

有没有人看出该方法的基本缺陷?

提前致谢。

问题是您在使用 repository 之前 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 配置