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

时间:2015-01-01 04:35:15

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

在搜索了一天之后,尝试了所有配置(应用程序上下文)和注释(autowire,注入,组件等),我似乎无法使我的pojo类成功注入一个工作存储库 - 值始终为null。 我开始怀疑是否注入除了控制器之外的任何东西都违背了弹簧数据休息的架构。

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

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

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

提前致谢。

1 个答案:

答案 0 :(得分:3)

问题是你正在使用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配置