我正在尝试编写代码来注释类中的字段,以便从配置文件中设置该字段的值。这实际上与Spring框架所具有的@Value属性相同,但出于我不会涉及的原因,我没有使用spring框架。通过注释的Java字段注入
我正在开发的项目是一个使用Jersey框架的Web应用程序。我对所有的前期信息道歉,但为了完整起见,这里是什么,我有一个基本设置:
这是主应用程序类:
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值文件到类myController的一个实例。
感谢您花时间阅读所有内容!任何帮助将不胜感激。
? – Guillaume
最初,我在MyApplication.getClasses()方法中调用了parse(),但它无法适当地设置值,因为在那时它只有类>而不是一个将值设置为(至少,我认为这是问题)。 parse()中的内容为:field.set(clazz,properties.getProperty(value));是问题。 – wbj
@wbj您调用的方式[Field#set](http://docs.oracle.com/javase/6/docs/api/java/lang/reflect/Field.html#set%28java.lang.Object, %20java.lang.Object%29)只有当字段为'static'时,才会成功设置该值,在这种情况下,obj参数'clazz'已过时,否则可能为'null'(如果该字段不是静态),你最终会得到一个'java.lang.IllegalArgumentException',除非你传递一个实例为'obj' – A4L