java 反射 + spring 依赖注入

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7492688/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 20:12:42  来源:igfitidea点击:

Reflection + spring dependency injection

javaspringreflection

提问by Ae.

I'm trying to understand if I can combine reflection with spring dependency injection as the following:

我试图了解是否可以将反射与 spring 依赖注入相结合,如下所示:

public interface ClientCommand {

    public void execute(...);

    public static enum Command {
        SomeCommand(SomeCommand.class);

        private Class<? extends ClientCommand> clazz;

        private Command(Class<? extends ClientCommand> clazz) {
            this.clazz = clazz;
        }

        public Class<? extends ClientCommand> getClazz() {
            return clazz;
        }

        public static ClientCommand getClientCommand(String name) {
            Command command = Enum.valueOf(Command.class, name);
            return command.getClazz().newInstance();
        }
    }
}

This will create an instance of a command class based on the name passed in getClientCommand. This is an example of class extending ClientCommand:

这将根据在 getClientCommand 中传递的名称创建命令类的实例。这是扩展 ClientCommand 的类的示例:

public class LoginCommand implements ClientCommand {
    @Autowired
    private UserRepository userRepository;

    public void setUserRepository(@Qualifier("userRepository")UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    public void execute(...) {
        ...
    }
}

And the repository is something like:

存储库类似于:

@Repository("userRepository")
public class UserRepositoryImpl implements UserRepository {
    ....
}

When the LoginCommand.execute() method is executed, the UserRepository is null. If I use the newInstance() to create the object, does spring care at all to inject the dependencies? More than for practical use, is to understand if is theoretically possible to get this code working. Thanks in advance

当执行 LoginCommand.execute() 方法时,UserRepository 为空。如果我使用 newInstance() 创建对象,spring 是否关心注入依赖项?不仅仅是为了实际使用,更重要的是了解理论上是否可以使此代码正常工作。提前致谢

回答by nicholas.hauschild

To answer this question:

要回答这个问题:

If I use the newInstance() to create the object, does spring care at all to inject the dependencies?

如果我使用 newInstance() 创建对象,spring 是否关心注入依赖项?

I will answer with no, not by default. Spring will only inject dependencies on objects that Spring is in control of, and if you are using reflection to instantiate it, or the newoperator, then youare the one in control, not Spring.

我会回答不,不是默认的。Spring 只会注入对 Spring 控制的对象的依赖,如果你使用反射来实例化它,或者new操作符,那么是控制者,而不是 Spring。

But, there is hope. You can use AspectJ to do bytecode weaving when the newoperator is used, or even when Class.newInstance()is used.

但是,有希望。使用new运算符时,甚至使用时,都可以使用 AspectJ 进行字节码编织Class.newInstance()

Take a look at this Spring documentationfor more on this approach.

有关此方法的更多信息,请查看此Spring 文档

回答by sigget

Since you're creating the object on your own Spring will not do dependency injection on the object. It will also not add any AOP proxies for it if its configured to do that.

由于您是在自己的 Spring 上创建对象,因此不会对该对象进行依赖注入。如果配置为这样做,它也不会为其添加任何 AOP 代理。

You can either use AspectJ to instrument your code by adding the logic necessary to do dependency injection on the instance. This is done completely transparently.

您可以使用 AspectJ 通过添加对实例进行依赖注入所需的逻辑来检测您的代码。这是完全透明的。

Or you can do it yourself by using AutowireCapableBeanFactory. It's a semi-internal interface that you can use and its intended for just this purpose. It has a set of methods that do various parts of creating and injecting, you'll probably need the createBean()method.

或者您可以使用 AutowireCapableBeanFactory 自己完成。它是一个您可以使用的半内部界面,它仅用于此目的。它有一组方法来完成创建和注入的各个部分,您可能需要createBean()方法。

You can get an AutowireCapableBeanFactory by calling getAutowireCapableBeanFactory on your ApplicationContext.

您可以通过在 ApplicationContext 上调用 getAutowireCapableBeanFactory 来获取 AutowireCapableBeanFactory。

In your case it would probably be a good idea to create a CommandFactory, make that implement ApplicationContextAware and have a method like createCommand() that calls createBean().

在您的情况下,创建一个 CommandFactory,使其实现 ApplicationContextAware 并具有调用 createBean() 之类的 createCommand() 方法可能是一个好主意。