使用带有反射的弹簧BeanPostProcessor可以安全地更改bean中的私人字段值

发布于 2025-02-06 10:30:29 字数 1331 浏览 0 评论 0原文

我正在使用Springs BeanPostProcessor来循环浏览bean中传递的所有声明字段,如果其中任何一个具有特定的注释,那么我想以某种方式修改该字段。

执行此操作的代码(省略注释声明)看起来很像以下内容,并且似乎正确工作(到目前为止):

@Component
public class AnnotationProcessingBeanPostProcessor implements BeanPostProcessor {
    
    @Override
    public final Object postProcessAfterInitialization(final Object bean, final String beanName) {
        return bean;
    }

    @Override
    public final Object postProcessBeforeInitialization(Object bean, final String beanName) {
        Field[] fields = bean.getClass().getDeclaredFields();
        List<Field> fieldsWithAnno = new ArrayList<>();
        for (Field field : fields) {
            if (field.isAnnotationPresent(SomeAnno.class)) {
                try {
                    field.setAccessible(true);
                    field.set(bean, "HELLO WORLD!");
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }

        return bean;
    }
}

我担心的是,我相信bean本身被包裹在某种代理对象中,因此bean这里不是我特定豆的直接实例。

那么,这样做会导致一些不可预见的问题吗?

我实际上要实现的目标

我想用类似的内容注释字段:

@GetStringFromFile(fileName = "whatever.txt")
private String somePrivField;

然后,当我找到带有该注释的字段时,我会读取文件,并注入其字符串值,如果文件值不存在或不能正确读取,引发异常,然后阻止我的春季应用程序启动。

I am using Springs BeanPostProcessor to loop through all the declared fields for the passed in bean, and if any of them has a particular annotation, then I want to modify that fields value in some way.

The code to do this (omitting the annotation declaration) looks roughly like the below, and seems work correctly (so far):

@Component
public class AnnotationProcessingBeanPostProcessor implements BeanPostProcessor {
    
    @Override
    public final Object postProcessAfterInitialization(final Object bean, final String beanName) {
        return bean;
    }

    @Override
    public final Object postProcessBeforeInitialization(Object bean, final String beanName) {
        Field[] fields = bean.getClass().getDeclaredFields();
        List<Field> fieldsWithAnno = new ArrayList<>();
        for (Field field : fields) {
            if (field.isAnnotationPresent(SomeAnno.class)) {
                try {
                    field.setAccessible(true);
                    field.set(bean, "HELLO WORLD!");
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }

        return bean;
    }
}

My concern is, I believe the beans themselves are wrapped in some sort of proxy object, so the actual instance of the bean here is not a DIRECT instance of my particular bean.

So could doing this sort of thing cause some unforseen issue?

What I am ACTUALLY trying to achieve

I want to annotate fields with something like:

@GetStringFromFile(fileName = "whatever.txt")
private String somePrivField;

Then when I find a field with that annotation, I will read the file in, and inject it's String value, and if the file doesn't exist or can't be read properly, throw an exception, and stop my spring app from starting up.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文