日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術(shù)文章
文章詳情頁

SpringBoot2.動(dòng)態(tài)@Value的實(shí)現(xiàn)方式

瀏覽:111日期:2023-02-27 09:36:10

title: SpringBoot2.動(dòng)態(tài)@Value實(shí)現(xiàn)

前言

前面文章有詳細(xì)描述過各個(gè)不同階段對于bean的擴(kuò)展接口

所以今天就基于BeanPostProcessor實(shí)現(xiàn)Spring中的@Value注解值動(dòng)態(tài)變化

基于上面也可以實(shí)現(xiàn)一個(gè)配置中心,比如說Apollo

具體的實(shí)現(xiàn)步驟分為如下幾步

1.通過BeanPostProcessor取得有使用@Value注解的bean,并存儲(chǔ)到map中

2.動(dòng)態(tài)修改map中的bean字段的值

獲取bean

首先寫一個(gè)類實(shí)現(xiàn)BeanPostProcessor接口,只需要使用其中的一個(gè)函數(shù)就可以。前后都可以用來實(shí)現(xiàn),并不影響最終的使用,因?yàn)樵蹅冎皇切枰猙ean的實(shí)例。

接下來看一下具體實(shí)現(xiàn)代碼

package com.allen.apollo;import org.springframework.beans.BeansException;import org.springframework.beans.factory.annotation.Value;import org.springframework.beans.factory.config.BeanPostProcessor;import org.springframework.context.annotation.Configuration;import org.springframework.util.ReflectionUtils;import java.lang.reflect.Field;import java.util.LinkedList;import java.util.List;import java.util.Set;@Configurationpublic class SpringValueProcessor implements BeanPostProcessor { private final PlaceholderHelper placeholderHelper = new PlaceholderHelper(); @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {if (beanName.equals('springValueController')) { Class obj = bean.getClass(); List<Field> fields = findAllField(obj); for (Field field : fields) {Value value = field.getAnnotation(Value.class);if (value != null) { Set<String> keys = placeholderHelper.extractPlaceholderKeys(value.value()); for (String key : keys) {SpringValue springValue = new SpringValue(key, value.value(), bean, beanName, field, false);SpringValueCacheMap.map.put(key, springValue); }} }}return bean; } private List<Field> findAllField(Class clazz) {final List<Field> res = new LinkedList<>();ReflectionUtils.doWithFields(clazz, new ReflectionUtils.FieldCallback() { @Override public void doWith(Field field) throws IllegalArgumentException, IllegalAccessException {res.add(field); }});return res; }}

上面的代碼咱們就已經(jīng)拿到了SpringValueController這個(gè)實(shí)例bean并存儲(chǔ)到了map當(dāng)中,下面看一下測試代碼

/** * cache field,存儲(chǔ)bean 字段 */package com.allen.apollo;import com.google.common.collect.LinkedListMultimap;import com.google.common.collect.Multimap;public class SpringValueCacheMap { public static final Multimap<String, SpringValue> map = LinkedListMultimap.create();}

package com.allen.apollo;import java.lang.ref.WeakReference;import java.lang.reflect.Field;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;import java.lang.reflect.Type;import org.springframework.core.MethodParameter;public class SpringValue { private MethodParameter methodParameter; private Field field; private WeakReference<Object> beanRef; private String beanName; private String key; private String placeholder; private Class<?> targetType; private Type genericType; private boolean isJson; public SpringValue(String key, String placeholder, Object bean, String beanName, Field field, boolean isJson) {this.beanRef = new WeakReference<>(bean);this.beanName = beanName;this.field = field;this.key = key;this.placeholder = placeholder;this.targetType = field.getType();this.isJson = isJson;if (isJson) { this.genericType = field.getGenericType();} } public SpringValue(String key, String placeholder, Object bean, String beanName, Method method, boolean isJson) {this.beanRef = new WeakReference<>(bean);this.beanName = beanName;this.methodParameter = new MethodParameter(method, 0);this.key = key;this.placeholder = placeholder;Class<?>[] paramTps = method.getParameterTypes();this.targetType = paramTps[0];this.isJson = isJson;if (isJson) { this.genericType = method.getGenericParameterTypes()[0];} } public void update(Object newVal) throws IllegalAccessException, InvocationTargetException {if (isField()) { injectField(newVal);} else { injectMethod(newVal);} } private void injectField(Object newVal) throws IllegalAccessException {Object bean = beanRef.get();if (bean == null) { return;}boolean accessible = field.isAccessible();field.setAccessible(true);field.set(bean, newVal);field.setAccessible(accessible); } private void injectMethod(Object newVal) throws InvocationTargetException, IllegalAccessException {Object bean = beanRef.get();if (bean == null) { return;}methodParameter.getMethod().invoke(bean, newVal); } public String getBeanName() {return beanName; } public Class<?> getTargetType() {return targetType; } public String getPlaceholder() {return this.placeholder; } public MethodParameter getMethodParameter() {return methodParameter; } public boolean isField() {return this.field != null; } public Field getField() {return field; } public Type getGenericType() {return genericType; } public boolean isJson() {return isJson; } boolean isTargetBeanValid() {return beanRef.get() != null; } @Override public String toString() {Object bean = beanRef.get();if (bean == null) { return '';}if (isField()) { return String .format('key: %s, beanName: %s, field: %s.%s', key, beanName, bean.getClass().getName(), field.getName());}return String.format('key: %s, beanName: %s, method: %s.%s', key, beanName, bean.getClass().getName(),methodParameter.getMethod().getName()); }}

package com.allen.apollo;import com.google.common.base.Strings;import com.google.common.collect.Sets;import org.springframework.beans.factory.config.BeanDefinition;import org.springframework.beans.factory.config.BeanExpressionContext;import org.springframework.beans.factory.config.ConfigurableBeanFactory;import org.springframework.beans.factory.config.Scope;import org.springframework.util.StringUtils;import java.util.Set;import java.util.Stack;/** * Placeholder helper functions. */public class PlaceholderHelper { private static final String PLACEHOLDER_PREFIX = '${'; private static final String PLACEHOLDER_SUFFIX = '}'; private static final String VALUE_SEPARATOR = ':'; private static final String SIMPLE_PLACEHOLDER_PREFIX = '{'; private static final String EXPRESSION_PREFIX = '#{'; private static final String EXPRESSION_SUFFIX = '}'; /** * Resolve placeholder property values, e.g. * <br /> * <br /> * '${somePropertyValue}' -> 'the actual property value' */ public Object resolvePropertyValue(ConfigurableBeanFactory beanFactory, String beanName, String placeholder) { // resolve string value String strVal = beanFactory.resolveEmbeddedValue(placeholder); BeanDefinition bd = (beanFactory.containsBean(beanName) ? beanFactory.getMergedBeanDefinition(beanName) : null); // resolve expressions like '#{systemProperties.myProp}' return evaluateBeanDefinitionString(beanFactory, strVal, bd); } private Object evaluateBeanDefinitionString(ConfigurableBeanFactory beanFactory, String value, BeanDefinition beanDefinition) { if (beanFactory.getBeanExpressionResolver() == null) { return value; } Scope scope = (beanDefinition != null ? beanFactory.getRegisteredScope(beanDefinition.getScope()) : null); return beanFactory.getBeanExpressionResolver().evaluate(value, new BeanExpressionContext(beanFactory, scope)); } /** * Extract keys from placeholder, e.g. * <ul> * <li>${some.key} => 'some.key'</li> * <li>${some.key:${some.other.key:100}} => 'some.key', 'some.other.key'</li> * <li>${${some.key}} => 'some.key'</li> * <li>${${some.key:other.key}} => 'some.key'</li> * <li>${${some.key}:${another.key}} => 'some.key', 'another.key'</li> * <li>#{new java.text.SimpleDateFormat(’${some.key}’).parse(’${another.key}’)} => 'some.key', 'another.key'</li> * </ul> */ public Set<String> extractPlaceholderKeys(String propertyString) { Set<String> placeholderKeys = Sets.newHashSet(); if (!isNormalizedPlaceholder(propertyString) && !isExpressionWithPlaceholder(propertyString)) { return placeholderKeys; } Stack<String> stack = new Stack<>(); stack.push(propertyString); while (!stack.isEmpty()) { String strVal = stack.pop(); int startIndex = strVal.indexOf(PLACEHOLDER_PREFIX); if (startIndex == -1) {placeholderKeys.add(strVal);continue; } int endIndex = findPlaceholderEndIndex(strVal, startIndex); if (endIndex == -1) {// invalid placeholder?continue; } String placeholderCandidate = strVal.substring(startIndex + PLACEHOLDER_PREFIX.length(), endIndex); // ${some.key:other.key} if (placeholderCandidate.startsWith(PLACEHOLDER_PREFIX)) {stack.push(placeholderCandidate); } else {// some.key:${some.other.key:100}int separatorIndex = placeholderCandidate.indexOf(VALUE_SEPARATOR);if (separatorIndex == -1) { stack.push(placeholderCandidate);} else { stack.push(placeholderCandidate.substring(0, separatorIndex)); String defaultValuePart = normalizeToPlaceholder(placeholderCandidate.substring(separatorIndex + VALUE_SEPARATOR.length())); if (!Strings.isNullOrEmpty(defaultValuePart)) { stack.push(defaultValuePart); }} } // has remaining part, e.g. ${a}.${b} if (endIndex + PLACEHOLDER_SUFFIX.length() < strVal.length() - 1) {String remainingPart = normalizeToPlaceholder(strVal.substring(endIndex + PLACEHOLDER_SUFFIX.length()));if (!Strings.isNullOrEmpty(remainingPart)) { stack.push(remainingPart);} } } return placeholderKeys; } private boolean isNormalizedPlaceholder(String propertyString) { return propertyString.startsWith(PLACEHOLDER_PREFIX) && propertyString.endsWith(PLACEHOLDER_SUFFIX); } private boolean isExpressionWithPlaceholder(String propertyString) { return propertyString.startsWith(EXPRESSION_PREFIX) && propertyString.endsWith(EXPRESSION_SUFFIX)&& propertyString.contains(PLACEHOLDER_PREFIX); } private String normalizeToPlaceholder(String strVal) { int startIndex = strVal.indexOf(PLACEHOLDER_PREFIX); if (startIndex == -1) { return null; } int endIndex = strVal.lastIndexOf(PLACEHOLDER_SUFFIX); if (endIndex == -1) { return null; } return strVal.substring(startIndex, endIndex + PLACEHOLDER_SUFFIX.length()); } private int findPlaceholderEndIndex(CharSequence buf, int startIndex) { int index = startIndex + PLACEHOLDER_PREFIX.length(); int withinNestedPlaceholder = 0; while (index < buf.length()) { if (StringUtils.substringMatch(buf, index, PLACEHOLDER_SUFFIX)) {if (withinNestedPlaceholder > 0) { withinNestedPlaceholder--; index = index + PLACEHOLDER_SUFFIX.length();} else { return index;} } else if (StringUtils.substringMatch(buf, index, SIMPLE_PLACEHOLDER_PREFIX)) {withinNestedPlaceholder++;index = index + SIMPLE_PLACEHOLDER_PREFIX.length(); } else {index++; } } return -1; }}

package com.allen.apollo;import lombok.extern.slf4j.Slf4j;import org.springframework.beans.factory.annotation.Value;import org.springframework.util.StringUtils;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.RestController;import java.lang.reflect.InvocationTargetException;@RestController@Slf4jpublic class SpringValueController { @Value('${test:123}') public String zax; @Value('${test:123}') public String test; @Value(('${zed:zed}')) public String zed; @GetMapping('/test') public String test(String a, String b) {if (!StringUtils.isEmpty(a)) { try {for (SpringValue springValue : SpringValueCacheMap.map.get('test')) { springValue.update(a);}for (SpringValue springValue : SpringValueCacheMap.map.get('zed')) { springValue.update(b);} } catch (IllegalAccessException | InvocationTargetException e) {e.printStackTrace(); }}return String.format('test: %s, zax: %s, zed: %s', test, zax, zed); }}

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持好吧啦網(wǎng)。

標(biāo)簽: Spring
相關(guān)文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
亚洲人成亚洲精品| 蜜乳av另类精品一区二区| 日韩天堂av| 欧美日韩国产高清| 99国产精品一区二区| 国产精品国产一区| 成人在线超碰| 国产精品亚洲产品| 你懂的国产精品永久在线| 麻豆成人综合网| 岛国精品一区| 日韩成人亚洲| 欧美福利专区| 亚洲女同中文字幕| 日韩中文字幕1| 欧美一级二区| 水蜜桃久久夜色精品一区| 日韩一区电影| 夜夜嗨一区二区| 日韩欧乱色一区二区三区在线| 日韩高清二区| 成人午夜网址| 久久成人精品| 国产激情一区| 日韩免费福利视频| 美女精品在线| 国产极品模特精品一二| 久久精品国产大片免费观看| 亚洲国产不卡| 国产探花一区二区| 成人精品视频| 日韩精品一卡二卡三卡四卡无卡| 日韩不卡手机在线v区| 精品入口麻豆88视频| 午夜久久黄色| 国产极品模特精品一二| 国产高清久久| 欧美激情 亚洲a∨综合| 欧洲激情综合| 老牛国内精品亚洲成av人片 | 精品丝袜久久| 亚洲影视一区二区三区| 成人黄色av| 日本午夜精品| 99成人超碰| 精品国产欧美日韩一区二区三区| 夜久久久久久| 久久中文字幕av| 成人一区而且| 老色鬼精品视频在线观看播放| 免费观看在线综合| 91九色精品| 欧美日韩精品一区二区视频| 精品免费视频| 麻豆高清免费国产一区| 国产精品日本| 影音先锋久久| 中国女人久久久| 精品欧美激情在线观看| av资源中文在线| 精品视频一区二区三区在线观看| 欧美一级二级视频| 日韩精品免费视频一区二区三区 | 国产综合婷婷| 999国产精品视频| 国产91一区| 国产盗摄——sm在线视频| 免费亚洲一区| 国产精品久久久久久久久久10秀| 国产精品一区二区精品| 欧美日韩一区二区国产 | 97国产成人高清在线观看| 国产精品一区二区av日韩在线| 91嫩草精品| 国产精品一页| 国产一区精品福利| 久久电影tv| 一区在线免费| 亚洲人成在线影院| 麻豆国产一区| 国产va在线视频| 亚洲综合电影一区二区三区| 日韩不卡手机在线v区| 日韩av在线播放网址| 欧美日韩国产免费观看视频| 日韩精品福利一区二区三区| 麻豆久久一区二区| 久久高清免费| 色婷婷成人网| 久久久一二三| 91精品国产自产观看在线 | 精品久久久久久久| 婷婷中文字幕一区| 日本不卡一区二区三区| 日韩av一二三| 亚洲精品在线影院| 日韩不卡免费高清视频| 亚洲精品进入| 精品美女久久| 日韩一区二区久久| 日本强好片久久久久久aaa| 欧美日韩视频网站| 亚洲综合五月| 色爱综合网欧美| 在线综合亚洲| 成人午夜网址| 国产调教一区二区三区| 欧美日韩激情| 麻豆成人av在线| 日韩av首页| 日本不卡一区二区三区| 合欧美一区二区三区| 欧美另类中文字幕| 亚洲一本视频| 美女高潮久久久| 久久成人国产| 日韩精品欧美激情一区二区| 国产一区二区三区视频在线| 一级欧美视频| 亚洲特级毛片| 久久亚洲人体| 无码日韩精品一区二区免费| 石原莉奈在线亚洲二区| 色婷婷色综合| 婷婷精品在线| 91九色精品| 欧美一级鲁丝片| 亚洲福利一区| 欧美69视频| 日韩一区二区中文| 老牛国内精品亚洲成av人片| 日本免费新一区视频| 国产亚洲精品久久久久婷婷瑜伽| 91亚洲一区| 久久精品av麻豆的观看方式| 一区二区三区四区精品视频| 老牛影视精品| 精品久久电影| 国产欧美69| 国产色播av在线| 日韩精品麻豆| 亚洲成人不卡| 日韩精品一区二区三区免费观看| 精品视频自拍| 中文字幕一区二区av| 欧美一区成人| 国产精品1区| 97精品国产一区二区三区| 国产精品99久久免费观看| 国产成人免费视频网站视频社区| 久久亚洲国产精品尤物| 91亚洲一区| 日韩一区二区免费看| 蜜臀91精品一区二区三区| 日韩激情一二三区| 久久精品99久久久| 欧美激情久久久久久久久久久| 综合色一区二区| а√天堂8资源在线| 久久中文视频| 亚洲色图综合| 精品久久一区| 四虎8848精品成人免费网站| 国产亚洲高清视频| 青青国产91久久久久久| 丁香婷婷久久| 欧美日韩精品免费观看视频完整| 亚洲一区二区三区高清| 日韩av在线免费观看不卡| 视频在线观看一区| av综合电影网站| 欧美日韩视频免费看| 日韩成人精品一区二区| 午夜宅男久久久| 成人午夜在线| 日本免费在线视频不卡一不卡二| 国产91在线精品| 亚洲免费一区三区| 国产精品成人国产| 亚洲精品电影| 亚洲午夜久久久久久尤物| 欧美一级二区| 日韩精品一级二级| 国产一区二区三区探花| 亚洲成人av观看| 国产欧美高清视频在线| 九九久久婷婷| 久久一区欧美| 亚洲人www| 欧美精品一二| 亚洲精品一区二区在线看| 国产一区二区三区不卡av | 日韩成人av影视| 精品欧美激情在线观看| 国产精品久久久网站| 欧美日韩一区二区国产| 蜜臀av一区二区三区| 91久久中文| 久久99精品久久久野外观看| 日韩二区三区在线观看|