Value注解支持對象類型ConfigurationProperties功能
真實(shí)業(yè)務(wù)場景
(不希望配置類注冊為Bean 或 不希望聲明@ConfigurationProperties)
假設(shè)某一個(gè)jar包內(nèi)封裝了DataSourceProperties
@Configuration @ConfigurationProperties( prefix = "my.datasource" ) @Data public class DataSourceProperties { private List<String> suffix; private List<DataSourceDetailProperties> db; }
在jar包的Configuration中,某個(gè)@Bean的構(gòu)造過程中引用了這個(gè)DataSourceProperties
public JdbcTemplate buildJdbcTemplate(DataSourceProperties dataSourceProperties) { }
在某個(gè)業(yè)務(wù)場景中,同時(shí)存在兩個(gè)DataSourceProperties 會造成一個(gè)問題,注入的時(shí)候會提示有多個(gè)候選的bean 但是沒法去修改Jar包中的內(nèi)容
自己重復(fù)寫一個(gè)DataSourceProperties 不是很優(yōu)雅
這時(shí)候引出了一個(gè)需求,DataSourceProperties不希望注冊為Bean,但是能夠從配置文件讀取構(gòu)建對象
解決方案一
使用org.springframework.boot.context.properties.bind.Binder
從配置文件構(gòu)建配置對象
@Bean public JdbcTemplate buildJdbcTemplate(Environment environment) { Binder binder = Binder.get(environment); DataSourceProperties properties1 = binder.bind("my.datasource1", Bindable.of(DataSourceProperties.class)).get(), properties2 = binder.bind("my.datasource2", Bindable.of(DataSourceProperties.class)).get(); }
binder.bind("xxx", Bindable.of(type)).get() 似乎是重復(fù)的編碼方式?
解決方案二
使@Value
注解能夠支持自動調(diào)用這段代碼 binder.bind("xxx", Bindable.of(type)).get()
例如
@Bean public JdbcTemplate buildJdbcTemplate(@Value("my.datasource1") DataSourceProperties properties1, @Value("my.datasource2") DataSourceProperties properties2) { }
org.springframework.beans.factory.support.DefaultListableBeanFactory#doResolveDependency
最后會交由converter處理
Class<?> type = descriptor.getDependencyType(); Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor); if (value != null) { if (value instanceof String) { String strVal = resolveEmbeddedValue((String) value); BeanDefinition bd = (beanName != null && containsBean(beanName) ? getMergedBeanDefinition(beanName) : null); value = evaluateBeanDefinitionString(strVal, bd); } TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter()); try { return converter.convertIfNecessary(value, type, descriptor.getTypeDescriptor()); } catch (UnsupportedOperationException ex) { // A custom TypeConverter which does not support TypeDescriptor resolution... return (descriptor.getField() != null ? converter.convertIfNecessary(value, type, descriptor.getField()) : converter.convertIfNecessary(value, type, descriptor.getMethodParameter())); } }
項(xiàng)目啟動時(shí),添加String to Object的轉(zhuǎn)換器,支持@Value
并且 "bind:"開頭(防止影響@Value
原有功能)
package com.nuonuo.accounting.guiding.support.spring; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.context.properties.bind.Bindable; import org.springframework.boot.context.properties.bind.Binder; import org.springframework.boot.convert.ApplicationConversionService; import org.springframework.context.ApplicationContextInitializer; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.core.convert.TypeDescriptor; import org.springframework.core.convert.converter.ConditionalGenericConverter; import java.util.Set; import static java.util.Collections.singleton; /** * @author uhfun */ public class ValuePropertiesBindableAnnotationSupport implements ApplicationContextInitializer<ConfigurableApplicationContext> { private static final String PREFIX = "bind:"; @Override public void initialize(ConfigurableApplicationContext context) { Binder binder = Binder.get(context.getEnvironment()); ((ApplicationConversionService) context.getBeanFactory().getConversionService()).addConverter(new ConditionalGenericConverter() { @Override public boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType) { Value value = targetType.getAnnotation(Value.class); return value != null && value.value().startsWith(PREFIX); } @Override public Set<ConvertiblePair> getConvertibleTypes() { return singleton(new ConvertiblePair(String.class, Object.class)); } @Override public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { Value value = targetType.getAnnotation(Value.class); Class<?> type = targetType.getType(); assert value != null; return binder.bind(value.value().replace(PREFIX, ""), Bindable.of(type)).get(); } }); } }
轉(zhuǎn)換后代碼執(zhí)行 binder.bind(value.value().replace(PREFIX, ""), Bindable.of(type)).get();
目的就達(dá)成了
在META-INF/spring.factories
中添加注冊的Bean
# ApplicationContextInitializer org.springframework.context.ApplicationContextInitializer=\ com.nuonuo.accounting.guiding.support.spring.ValuePropertiesBindableAnnotationSupport,\
最終效果
@Bean public JdbcTemplate buildJdbcTemplate(@Value("bind:my.datasource1") DataSourceProperties properties1, @Value("bind:my.datasource2") DataSourceProperties properties2) { }
以上就是Value注解支持對象類型ConfigurationProperties功能的詳細(xì)內(nèi)容,更多關(guān)于Value支持對象類型的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
SpringBoot全局異常捕獲處理實(shí)現(xiàn)方案
這篇文章主要詳細(xì)介紹了SpringBoot全局異常捕獲處理實(shí)現(xiàn)方案,文章通過代碼示例給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下2024-02-02Java中spring boot 字符串判斷是否為空方法小結(jié)
這篇文章主要介紹了Java中spring boot字符串判斷是否為空,通過安裝依賴,結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2023-11-11java?9大性能優(yōu)化經(jīng)驗(yàn)總結(jié)
這篇文章主要介紹了java?9大性能優(yōu)化經(jīng)驗(yàn)總結(jié),包括:Java代碼優(yōu)化,數(shù)據(jù)庫優(yōu)化,分布式緩存,異步化,Web前段,搜索引擎優(yōu)化等需要的朋友可以參考下2023-02-02一文徹底弄懂零拷貝原理以及java實(shí)現(xiàn)
零拷貝(英語: Zero-copy) 技術(shù)是指計(jì)算機(jī)執(zhí)行操作時(shí),CPU不需要先將數(shù)據(jù)從某處內(nèi)存復(fù)制到另一個(gè)特定區(qū)域,下面這篇文章主要給大家介紹了關(guān)于零拷貝原理以及java實(shí)現(xiàn)的相關(guān)資料,需要的朋友可以參考下2021-08-08Java 反射調(diào)用靜態(tài)方法的簡單實(shí)例
下面小編就為大家?guī)硪黄狫ava 反射調(diào)用靜態(tài)方法的簡單實(shí)例。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2016-06-06關(guān)于eclipse安裝spring插件報(bào)錯(cuò)An error occurred while collecting item
這篇文章主要介紹了關(guān)于eclipse安裝spring插件報(bào)錯(cuò)An error occurred while collecting items to be installed...解決方案,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-08-08Java反射機(jī)制如何解決數(shù)據(jù)傳值為空的問題
這篇文章主要介紹了Java反射機(jī)制如何解決數(shù)據(jù)傳值為空的問題,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-03-03