借助于postProcessBeforeInitialization实现自定义注解对bean中属性的注入
postProcessAfterInitialization也可以,使用AopUtils判断代理类型并取得对应的代理对象,按需使用
使用ConvertUtils动态转化String为其他类型(支持列表查一下此工具类)
/**
* @Description: 使用@Dict注解对Bean中String、List<String>和List<DictModel>类型对字段进行属性注入
* 使用举例三种如下:
* <span>
* @Dict(dicCode = "oa_duty_status", dicText = "发布")
* String dictValue / ? value; // value: "1"
* </span>
* <span>
* @Dict(dicCode = "oa_duty_status")
* List<String> / List<?> dictValueList; // value: ["0", "1"]
* </span>
* <span>
* @Dict(dicCode = "oa_duty_status")
* List<DictModel> dictModelList; value : [{value: "1", text: "发布"}, {value: "0", text: "暂存"}]
* </span>
* @author: xufeixiang
* @date: 2022年01月10日 3:31 PM
*/
@Slf4j
@Component
public class DictItemsInjectProcessor extends InstantiationAwareBeanPostProcessorAdapter {
@Autowired
private CommonAPI commonAPI;
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
injectDictItems(bean);
return super.postProcessBeforeInitialization(bean, beanName);
}
private void injectDictItems(Object bean) {
Class<?> beanClass = bean.getClass();
List<Field> injectFieldList = FieldUtils.getFieldsListWithAnnotation(beanClass, Dict.class);
for (Field field : injectFieldList) {
Dict dictAnnotation = field.getAnnotation(Dict.class);
String dicCode = dictAnnotation.dicCode();
String dicText = dictAnnotation.dicText();
List<DictModel> dictModelList = commonAPI.queryDictItemsByCode(dicCode);
if (dictModelList.size() == 0) {
continue;
}
if (StringUtils.isNotEmpty(dicText)) {
List<String> dicTextList = Arrays.asList(StringUtils.split(dicText, StringPool.COMMA));
dictModelList = dictModelList.stream()
.filter(x -> dicTextList.contains(x.getText()))
.collect(Collectors.toList());
}
boolean accessible = field.isAccessible();
String targetTypeName = field.getType().getSimpleName(), targetRealType = targetTypeName;
Object fieldValue;
try {
switch (targetTypeName) {
case "List":
Class<?> subTypeOfList = (Class<?>) ((ParameterizedType) field.getGenericType()).getActualTypeArguments()[0];
boolean isDictModelClass = StringUtils.equals(subTypeOfList.getName(), DictModel.class.getName());
fieldValue = dictModelList.stream()
.map(x -> isDictModelClass ? x : ConvertUtils.convert(x.getValue(), subTypeOfList))
.collect(Collectors.toList());
targetRealType += '<' + subTypeOfList.getSimpleName() + '>';
break;
case "Map":
Type[] typeArguments = ((ParameterizedType) field.getGenericType()).getActualTypeArguments();
Class<?> keyTypeOfMap = (Class<?>) typeArguments[0];
Class<?> valTypeOfMap = (Class<?>) typeArguments[1];
fieldValue = dictModelList.stream()
.collect(Collectors.toMap(x -> ConvertUtils.convert(x.getValue(), keyTypeOfMap),
x -> ConvertUtils.convert(x.getText(), valTypeOfMap)));
targetRealType += '<' + keyTypeOfMap.getSimpleName() + ',' + valTypeOfMap.getSimpleName() + '>';
break;
case "String":
fieldValue = dictModelList.stream().map(DictModel::getValue).collect(Collectors.joining(StringPool.COMMA));
break;
default:
fieldValue = dictModelList.stream().map(DictModel::getValue).findAny().orElse(null);
fieldValue = ConvertUtils.convert(fieldValue, field.getType());
break;
}
if (!accessible) {
field.setAccessible(true);
}
field.set(bean, fieldValue);
log.info("dictItems inject {}({}) for \"{}\" in \"{}\"", fieldValue, targetRealType, field.getName(), beanClass.getName());
} catch (Exception e) {
log.error("injectDictItems Exception", e);
} finally {
field.setAccessible(accessible);
}
}
}
}