简体   繁体   English

如何使用反射通过接口创建实例?

[英]How to create instance by interface using reflection?

I'm trying coding Spring's DI , just a simple example.我正在尝试编码 Spring 的 DI ,只是一个简单的例子。 There is a controller, and this @AutoWired is a Empty Annotation defined by me.有一个控制器,这个@AutoWired 是我定义的一个空注解。

public class UserController {
    @AutoWired
    private UserServise userServise;// a empty interface
}

This is the code that implement Annotation injection:这是实现注解注入的代码:

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();
        }
    }
});

When the program runs into当程序运行到

Object o = type.getDeclaredConstructor().newInstance();

throws投掷

java.lang.NoSuchMethodException: com.learning.servise.UserServise.<init>()

I guess program cannot find a constructor for a interface, So how can I create this instance for the injection?我猜程序找不到接口的构造函数,那么如何为注入创建这个实例呢?

I am not completely sure what you are trying to achieve.我不完全确定您要实现的目标。 I'm assuming that UserService is an interface?我假设UserService是一个接口? If so it cannot be instantiated.如果是这样,则无法实例化。 You must either a class which implements the interface.您必须是一个实现该接口的类。 So either write a class (can also be anonymous or lambda) or use a proxy:所以要么写一个类(也可以是匿名的或 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
    }
});

Don't know if this is what you're after, but it is my best guess.不知道这是否是您所追求的,但这是我最好的猜测。

But maybe you're going at this wrong.但也许你做错了。 When you're trying to replicate Spring, it is important that you have a component or bean you can autowire.当您尝试复制 Spring 时,重要的是您有一个可以自动装配的组件或 bean。 So you should probably focus on your @Bean annotation (or similar) first.所以你应该首先关注你的 @Bean 注释(或类似的)。 You'd want some sort of registry which picks up annotated beans and then injects them into your Autowired fields.您需要某种注册表来获取带注释的 bean,然后将它们注入到您的 Autowired 字段中。 It seems you have this back-to-front.看来你有这个背对前。 You should first focus on registering beans to your framework and only when you have achieved that you should try to inject them.您应该首先专注于将 bean 注册到您的框架中,并且只有当您已经实现时,您才应该尝试注入它们。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM