让Spring的IoC容器实例化零配置的bean(比如Google Guice的行为)

时间:2014-11-21 18:44:07

标签: java spring guice spring-ioc

我有一个业余爱好项目,我想迁移到Spring。

作为一个例子,我有以下几个类:

public class OtherBean {
    public void printMessage() {
        System.out.println("Message from OtherBean");
    }
}


public class InjectInMe {
    @Inject OtherBean otherBean;

    public void callMethodInOtherBean() {
        otherBean.printMessage();
    }
}

然而,当我阅读文档时,我必须使用类似@Component(或其他类似的注释)的注释来注释要由Spring管理的所有类。

使用以下代码运行它:

public class SpringTest {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
        context.refresh();

        InjectInMe bean = context.getBean(InjectInMe.class);
        bean.callMethodInOtherBean();
    }
}

给我错误:

Exception in thread "main" org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [somepackage.InjectInMe] is defined
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:371)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:331)
    at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:968)
    at somepackage.SpringTest.main(SpringTest.java:10)

我的问题是:有没有办法让Spring管理任何类我要求ApplicationContext实例化而不用我必须在Annotated Config(或XML配置)中注册它们?

在Guice中我可以注入课堂

public class GuiceTest {
    static public class GuiceConfig extends AbstractModule {

        @Override
        protected void configure() {}

    }
    public static void main(String[] args) {
        Injector injector = Guice.createInjector(new GuiceConfig());
        InjectInMe bean = injector.getInstance(InjectInMe.class);
        bean.callMethodInOtherBean();
    }
}

给我输出:

Message from OtherBean

无论如何我可以让Spring像Guice一样工作吗?正如在make中注入我的bean 没有我必须注册或扫描包含注释@ Component-like注释的类?

任何Spring大师都有办法解决这个问题吗?

3 个答案:

答案 0 :(得分:2)

  

我的问题是:有没有办法让Spring管理我要求的任何课程   ApplicationContext实例化,无需我注册   它们在Annotated Config(或XML配置)中?

不,这是不可能的。这根本不是Spring的设计方式。您必须隐式(例如扫描+注释)或显式(例如XML bean定义)注册您的bean。

你能做的最少就是:

AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
context.register(OtherBean.class);
context.register(InjectInMe.class);
context.refresh();

答案 1 :(得分:0)

有几种方法可以为Spring的ApplicationContext提供bean定义:

  1. 使用组件扫描并使用@Component或其中一个元注释(@Service@Controller等对您的类型进行注释。)
  2. 在XML配置中定义<bean>或在Java配置中定义@Bean(或任何其他类型的显式配置)。
  3. 使用BeanDefinitionRegistryPostProcessor直接在BeanDefinitionRegistry上注册bean。
  4. 某些ApplicationContext子类型实现BeanDefinitionRegistry,因此您可以直接向它们注册bean定义。
  5. 当需要注入时,将从这些bean定义生成的bean可用。你不希望(至少IMO)你的容器实例化一个类型,而你不知道它是否正常。

答案 2 :(得分:0)

您必须将类声明为@Component,或者它可能是什么,或者您必须提供xml定义。如果你没有定义bean,Spring应该怎么知道怎么做?对于类的属性,例如MyController有一个私有服务MyService。如果你将@Autowired标记放在服务实例上,Spring会自动将这个服务器注入你的控制器,这就是你对@Inject的评论似乎暗示的。但是,为了自动装配,您必须为该类定义一个bean,这意味着您必须使用@ Component / @ Controller等注释配置或xml bean配置。