我正在嘗試編寫代碼來註釋類中的字段,以便從配置文件中設置該字段的值。這實際上與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