我有一个我要通过反射实例化的跟随类,然后自动实例化它的字段'databaseService'
@Controller
public class BaseController {
@AutoInstantiate
private DatabaseService databaseService;
@AfterSetup
public void initialize() {
System.out.println("Testing " + databaseService.getEntry());
}
}
我正在尝试自动实例化的简单类
public class DatabaseService {
public DatabaseService() {}
public String getEntry() {
return "I'm working! ";
}
}
我要做什么
public class Instantiator {
private static void start() {
Reflections reflections = new Reflections("com");
Class<?> clazz = reflections.getTypesAnnotatedWith(Controller.class)[0];
//Assume 'clazz' is 'BaseController' (the parent class of DatabaseService)
for(Field field : clazz.getDeclaredFields()) {
if(field.isAnnotationPresent(AutoInstantiate.class)) {
try {
field.setAccessible(true);
Object autowiredObject = field.getType().newInstance();
//HERES WHERE IT ALWAYS FAILS
field.set(clazz, autowiredObject);
}
catch(Exception e) {
logger.severe("Failure invoking class " + clazz.getName() + " Problem : " + e.getMessage());
}
}
}
}
}
和简单的主线
public class App {
public static void main(String[] args) throws Exception {
Instantiator.start();
}
}
问题 严重:调用类com.controller.BaseController失败问题:无法将com.service.DatabaseService字段com.controller.BaseController.databaseService设置为java.lang.Class
总体问题: 我不确定如何将实例化的类Object(DatabaseService)设置回其父类(BaseController)
答案 0 :(得分:1)
这是您遇到的问题:
field.set(autowiredObject.getClass(), autowiredObject);
看看documentation中Field.set(Object, Object)
方法的参数。我引用了一部分:
参数:
obj-应该修改其字段的对象
value-要修改的obj字段的新值
(如果该字段是静态的,则应该放null
来代替obj)。
这意味着您实际上应该将与clazz
类型相同的目标实例作为Field.set(Object, Object)
方法中的第一个参数,因为您要修改字段的目标实例没有DatabaseService的Class
对象。但是,您丢失了一个用Controller
或BaseController
注释的类型的实例,稍后将对其进行修改。