2016-08-03 52 views
3

我有一個簡單的彈簧啓動應用程序,其中我有一個jpa庫對象,我想在類似下面的@Configuration類中自動裝配。springboot autowiring @Repository裏面的@Configuration不起作用

@Configuration 
public class Appconfig { 

    @Bean 
    @Autowired 
    public PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer(OctopusPropertiesRepository repo) { 
     PropertySourcesPlaceholderConfigurer property = new PropertySourcesPlaceholderConfigurer(); 
     Map<String,Object> props = new ConcurrentHashMap<>(); 
     List<OctopusProperties> loadedSettings = repo.findAll(); 
     loadedSettings.forEach(entry -> props.put(entry.getKey(), entry.getValue())); 
     MutablePropertySources mutablePropertySources = new MutablePropertySources(); 
     mutablePropertySources.addFirst(new MapPropertySource("custom", props)); 
     property.setPropertySources(mutablePropertySources); 
     return property; 
    } 
} 

這裏是@Repository

@Repository 
public interface OctopusPropertiesRepository extends JpaRepository<OctopusProperties, Long> { 
} 

,我得到以下異常。

Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.example.app.OctopusPropertiesRepository] 

如果我沒有使配置和啓動應用程序成功,我從執行器中看到bean是可用的。這裏有什麼問題?爲什麼我不能在@Configuration內部連線@Repository

P.S.這兩個java文件位於同一文件夾下:com.example.app

P.P.S.我的項目 Eclipse視圖:

enter image description here

+1

包括正在掃描組件的類。還請在列表中包含軟件包。可能是主班? – luboskrnac

+0

主類在根包中,並且所有其他類都在同一個包中。我認爲它與時間有些相關,因爲如果我不使用這個配置,spring會生成這個bean。 – cacert

+0

如果你在Spring配置類中添加一個簡單的成員,如下所示,Spring是否會找到它?@Autowired OctopusPropertiesRepository octopusPropertiesRepository –

回答

1

使用@PostConstruct。

@Autowired PropertySourcesPlaceholderConfigurer property; 


@Autowired OctopusPropertiesRepository repo; 


    @PostConstruct 
    public void onInit() { 

     Map<String,Object> props = new ConcurrentHashMap<>(); 
     List<OctopusProperties> loadedSettings = repo.findAll(); 
     loadedSettings.forEach(entry -> props.put(entry.getKey(), entry.getValue())); 
     MutablePropertySources mutablePropertySources = new MutablePropertySources(); 
     mutablePropertySources.addFirst(new MapPropertySource("custom", props)); 
     property.setPropertySources(mutablePropertySources); 

    } 
+0

不要你的意思是@PostConstruct? – gybandi

+1

是@PostConstruct抱歉,我感到心臟編碼... –

+0

我不知道是否需要手動創建PropertySourcesPlaceholderConfigurer Bean實例,或者如果Spring引導自動創建它。 –

0

類似的問題在this問題

討論是否允許更改AppConfig類這樣的嗎?

@Configuration 
public class Appconfig { 

    @Autowired 
    private OctopusPropertiesRepository repo; 

    @Bean 
    public PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() { 
     PropertySourcesPlaceholderConfigurer property = new PropertySourcesPlaceholderConfigurer(); 
     Map<String,Object> props = new ConcurrentHashMap<>(); 
     List<OctopusProperties> loadedSettings = repo.findAll(); 
     loadedSettings.forEach(entry -> props.put(entry.getKey(), entry.getValue())); 
     MutablePropertySources mutablePropertySources = new MutablePropertySources(); 
     mutablePropertySources.addFirst(new MapPropertySource("custom", props)); 
     property.setPropertySources(mutablePropertySources); 
     return property; 
    } 
} 

如果此解決方案工作與否,還可以恢復。

+0

我試過但同樣的例外:( – cacert

1

按照@Bean的javadoc:

BeanFactoryPostProcessor-returning @Bean methods 
Special consideration must be taken for @Bean methods that return Spring 
BeanFactoryPostProcessor (BFPP) types. Because BFPP objects must be  
instantiated very early in the container lifecycle, they can interfere with 
processing of annotations such as @Autowired, @Value, and @PostConstruct 
within @Configuration classes. To avoid these lifecycle issues, mark BFPP 
returning @Bean methods as static. For example: 

@Bean 
public static PropertyPlaceholderConfigurer ppc() { 
    // instantiate, configure and return ppc ... 
} 


By marking this method as static, it can be invoked without causing 
instantiation of its declaring @Configuration class, thus avoiding the above- 
mentioned lifecycle conflicts. Note however that static @Bean methods will not 
be enhanced for scoping and AOP semantics as mentioned above. This works out 
in BFPP cases, as they are not typically referenced by other @Bean methods. As 
a reminder, a WARN-level log message will be issued for any non-static @Bean 
methods having a return type assignable to BeanFactoryPostProcessor. 

所以根據這一點,你應該propertySourcesPlaceholderConfigurer()是靜態的。

編輯: 對不起,後期編輯。 我不認爲你可以在這裏使用Hibernate倉庫,因爲BeanFactoryPostProcessor在hibernate和jpa需要任何依賴之前得到實例化。 也許你可以在這裏使用的JdbcTemplate,至少爲我工作:

@Configuration 
public class Appconfig { 

    @Bean 
    public PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() { 
     PropertySourcesPlaceholderConfigurer property = new PropertySourcesPlaceholderConfigurer(); 
     Map<String, Object> props = new ConcurrentHashMap<>(); 
     List<OctopusProperties> loadedSettings = getAll(); 
     loadedSettings.forEach(entry -> props.put(entry.getKey(), entry.getValue())); 
     MutablePropertySources mutablePropertySources = new MutablePropertySources(); 
     mutablePropertySources.addFirst(new MapPropertySource("custom", props)); 
     property.setPropertySources(mutablePropertySources); 
     return property; 
    } 

    @Bean 
    public static DataSource dataSource() { 
     DriverManagerDataSource dataSource = new DriverManagerDataSource(); 
     dataSource.setDriverClassName("com.mysql.jdbc.Driver"); 
     dataSource.setUrl("jdbc:mysql://localhost:3306/test"); 
     dataSource.setUsername("root"); 
     dataSource.setPassword("root"); 

     return dataSource; 
    } 

    private List<OctopusProperties> getAll() { 
     JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource()); 
     List<OctopusProperties> all = jdbcTemplate.query("select id,key_column,value_column from octopus_properties", 
       new RowMapper<OctopusProperties>() { 
        @Override 
        public OctopusProperties mapRow(final ResultSet rs, final int rowNum) throws SQLException { 
         OctopusProperties op = new OctopusProperties(); 
         op.setId(rs.getLong("id")); 
         op.setKey(rs.getString("key_column")); 
         op.setValue(rs.getString("value_column")); 
         return op; 
        } 
       }); 
     return all; 
    } 

} 

請注意,我用的MySQL在這裏,所以數據源被相應地配置。

+1

好點,我不知道提到的部分和希望,但仍然相同錯誤:( – cacert

+0

是啊,試了一下也同樣的錯誤,我爲好,讓我investage一點,我會盡快給您 – gybandi

相關問題