通过注解注入(inject) Java 字段

标签 java reflection annotations code-injection

我正在尝试编写代码来注释类中的字段,以便从配置文件中设置该字段的值。这实际上与 spring 框架具有的 @Value 属性相同,但由于我不会深入讨论的原因,我没有使用 spring 框架。

我正在做的项目是一个使用 Jersey 框架的网络应用程序。对于所有前期信息,我深表歉意,但为了完整起见,这里是我所拥有的基本设置:

这是主要的应用程序类:

package com.ttrr.myservice;

import com.ttrr.myservice.controllers.MyController;

import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;
import java.util.HashSet;
import java.util.Set;

@ApplicationPath("/")
public class MyApplication extends Application {
    @Override
    public Set<Class<?>> getClasses() {
        final Set<Class<?>> classes = new HashSet<Class<?>>();
        // register root resources            
        classes.add(MyController.class);

        return classes;
    }
}

这是 MyController 类,我希望注释可以在其中工作:
package com.ttrr.myservice.controllers;

import com.ttrr.myservice.annotations.Property;

import javax.servlet.ServletContext;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;

@Path("test")
public class MyController {

    @Property("my.value.from.config")
    private String myValue;

    @GET
    @Produces("text/html")
    @Path("/testPage")
    public String testPage(@Context ServletContext context) {        

        return "<p>" + myValue + "</p>";
    }
}

我的注释界面非常简单:
package com.ttrr.myservice.annotations;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Property {
    String value() default "";
}

我有一个注释解析器类:
package com.ttrr.myservice.annotations;

import java.io.IOException;
import java.lang.reflect.Field;
import java.util.Properties;

public class PropertyParser {

    public static Properties properties;

    static {
        properties = new Properties();
        try {
            Property.class.getClassLoader();

            Properties defaults = new Properties();
            defaults.load(Property.class.getClassLoader().getResourceAsStream("application.properties"));

            for(Object key : defaults.keySet()) {
                properties.put(key, defaults.get(key));
            }

        } catch (IOException e) {
            //in this case do nothing, properties will simply be empty
        }
    }

    public void parse(Class<?> clazz) throws Exception {

        Field[] fields = clazz.getDeclaredFields();

        for (Field field : fields) {
            if (field.isAnnotationPresent(Property.class)) {
                Property property = field.getAnnotation(Property.class);
                String value = property.value();

                if (!"".equals(value)) {
                    field.set(clazz, properties.getProperty(value));
                }
            }
        }
    }
}

我真正苦苦挣扎的地方是将它们放在一起,并将我的 application.properties 文件中的值放入 M​​yController 类的实例中。

感谢您花时间阅读所有内容!任何帮助将不胜感激。

最佳答案

您尝试设置值的方式不正确,因为您需要一个实例来设置值。

field.set(clazz, properties.getProperty(value));

应该:
field.set(instance, properties.getProperty(value));

你应该为你的 parse 方法添加一个参数:
public void parse(Class<?> clazz, Object instance) throws Exception {

关于通过注解注入(inject) Java 字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16820349/

相关文章:

java - 将评级栏的值传递给下一个 Activity/Intent

java - "css"在Spring MVC元素中如何使用 "jsp"?

java - J2ME 中的人脸检测

java - 如何以可移植的方式从 java 运行 JMeter?

java - 如何使用反射自动注册spring bean

java - @SessionAttributes 给出 HttpSessionRequiredException

java - 尝试使用 JPA 注释保存具有复合键和基本值的映射

c# - 将 C# 反射代码移植到 Metro-Ui

java - 在 Java 中,如何将类型列表中的所有静态字段作为其类的对象(而不是 Field 实例)?

mysql - 我需要哪种 MySQL 类型来存储常规字符串和哈希值?