反射+弹簧依赖注入

时间:2011-09-20 22:44:16

标签: java spring reflection

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

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

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

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

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

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

存储库就像:

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

执行LoginCommand.execute()方法时,UserRepository为null。 如果我使用newInstance()来创建对象,那么Spring会注意注入依赖项吗? 不仅仅是实际应用,还要了解理论上是否有可能使这段代码正常工作。 提前致谢

2 个答案:

答案 0 :(得分:3)

回答这个问题:

  

如果我使用newInstance()来创建对象,那么Spring是否会注入依赖项?

我会回答否,不是默认情况下。 Spring只会对Spring控制的对象注入依赖关系,如果你使用反射来实例化它,或者new运算符,那么 是控制中的那个,而不是春天。

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

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

答案 1 :(得分:1)

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

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

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

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

在您的情况下,最好创建一个CommandFactory,使其实现ApplicationContextAware并使用一个调用createBean()的createCommand()方法。