Java 如何使用反射通过接口创建实例?
我正在尝试编写Spring的DI,只是一个简单的例子。有一个控制器,这个@AutoWired是我定义的空注释Java 如何使用反射通过接口创建实例?,java,spring,reflection,Java,Spring,Reflection,我正在尝试编写Spring的DI,只是一个简单的例子。有一个控制器,这个@AutoWired是我定义的空注释 public class UserController { @AutoWired private UserServise userServise;// a empty interface } 这是实现注释注入的代码: UserController userController = new UserController(); Class<? extends User
public class UserController {
@AutoWired
private UserServise userServise;// a empty interface
}
这是实现注释注入的代码:
UserController userController = new UserController();
Class<? extends UserController> clazz = userController.getClass();
Stream.of(clazz.getDeclaredFields()).forEach(field -> {
AutoWired annotation = field.getAnnotation(AutoWired.class);
if (annotation != null) {
field.setAccessible(true);
Class<?> type = field.getType();
try {
Object o = type.getDeclaredConstructor().newInstance();
field.set(userController, o);
} catch (Exception e) {
e.printStackTrace();
}
}
});
投掷
java.lang.NoSuchMethodException: com.learning.servise.UserServise.<init>()
java.lang.NoSuchMethodException:com.learning.servise.UserServise.()
我猜程序找不到接口的构造函数,那么我如何为注入创建这个实例呢?我不完全确定您想要实现什么。我假设
UserService
是一个接口?
如果是这样,则无法实例化。您必须选择一个实现接口的类。
因此,要么编写一个类(也可以是匿名类或lambda类),要么使用代理:
Object instance = Proxy.newProxyInstance(type.getClassLoader(),
new Class<?>[]{type}, new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//implement your methods here
//determine which method you're in by checking the method arg
}
});
Object instance=Proxy.newProxyInstance(type.getClassLoader(),
新类[]{type},新调用处理程序(){
@凌驾
公共对象调用(对象代理、方法、对象[]args)抛出Throwable{
//在这里实现您的方法
//通过检查方法arg确定您使用的方法
}
});
我不知道这是不是你想要的,但这是我最好的猜测
但也许你做错了。当您试图复制Spring时,有一个可以自动连接的组件或bean是很重要的。因此,您可能应该首先关注@Bean注释(或类似注释)。您可能需要某种类型的注册表,它可以提取带注释的bean,然后将它们注入到您的自动连接字段中。看来你把这件事前后颠倒了。
您应该首先将重点放在将bean注册到您的框架上,并且只有当您实现了这一点时,才应该尝试注入它们。非常感谢您。我明白问题是什么。所以程序创建接口实例是不对的。我应该在Autowire之前完成Bean或其他基本注释。当然,您可以尝试找到接口的实现,然后实例化它们。但您无法控制使用哪种实现,哪种实现不好。而且,只有当实现类可以使用无参数构造函数构造时,这才有效。我认为最好允许用户决定在他的上下文中使用哪个实现。Spring检查实现自动连接接口的bean。如果找到一个实例,它将使用bean的实际类来创建实例
Object instance = Proxy.newProxyInstance(type.getClassLoader(),
new Class<?>[]{type}, new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//implement your methods here
//determine which method you're in by checking the method arg
}
});