关于通过 @Inject 实现注入配置文件属性到Java字段

背景,将配置文件中的属性注入到Java字段中,与spring中的@Value("#{key}") 类似。通过继承ProxyFactory 来实现。

第一步骤,定义Value 注解。

@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Value {
    /**
     * The actual value expression: e.g. "#{systemProperties}".
     */
    String value();
}

第二步:

继承ProxyFactory类,并重写  public <T> T get(Class<T> target) 方法


public class SelfProxyFactory extends ProxyFactory {
    /***
     * 表单时前缀
     */
    private final String prefix = "#{";
    /***
     * 表达式后缀
     */
    private final String suffix = "}";


    @Override
    public <T> T get(Class<T> target) {
        try {
            Class<T> ret = (Class<T>) cache.get(target);
            T result = null;
            if (ret != null) {
                result = (T) ret.newInstance();
            } else {
                result = getProxyClass(target).newInstance();
            }
            Class<?> resultClass = result.getClass();


            Field[] fields = resultClass.getDeclaredFields();
            for (Field field : fields) {
                Value annotation = field.getAnnotation(Value.class);
                if (annotation != null) {
                    // 表达式
                    String expr = annotation.value();
                    if (StrUtil.startWith(expr, prefix) && StrUtil.endWith(expr, suffix)) {
                        // application.properties 中的key
                        String key = StrUtil.removeSuffix(StrUtil.removePrefix(expr, prefix), suffix);
                        String keyValue = PropertiesKit.get(key, null);
                        field.setAccessible(true);
                        if (field.getType() == Byte.class) {
                            field.set(result, Byte.valueOf(keyValue));
                        } else if (field.getType() == Short.class) {
                            field.set(result, Short.valueOf(keyValue));
                        } else if (field.getType() == Integer.class) {
                            field.set(result, Integer.valueOf(keyValue));
                        } else if (field.getType() == Long.class) {
                            field.set(result, Long.valueOf(keyValue));
                        } else if (field.getType() == Double.class) {
                            field.set(result, Double.valueOf(keyValue));
                        } else if (field.getType() == Float.class) {
                            field.set(result, Float.valueOf(keyValue));
                        } else if (field.getType() == String.class) {
                            field.set(result, keyValue);
                        }
                    }
                }

            }
            return result;
        } catch (ReflectiveOperationException e) {
            throw new RuntimeException(e);
        }
    }
}


第三步,在config中配置为自己实现的ProxyFactory

constants.setProxyFactory(new SelfProxyFactory());


第四步,使用方式,例如:

public class TestBean {

    @Value("${jwtKey}")
    private String name;

    @Value("#{jwtExpire}")
    private String id;

}
// 具体使用方式,如下

@Inject
private TestBean testBean;


评论区

山东小木

2019-12-17 07:22

点赞

cs3230524

2019-12-17 21:40

可以把Field引用的哪个包发一下吗

HingLo

2019-12-18 08:54

@cs3230524 JDK自带的啊

tamdan

2020-03-16 11:03

学习了

热门分享

扫码入社