当前位置: 首页 > 知识库问答 >
问题:

让Spring的IoC容器用零配置实例化bean(就像Google Guice的行为一样)

子车劲
2023-03-14

我有一个爱好项目,我想迁移到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管理我要求Application Context实例化的任何类,而无需将它们注册到注释配置(或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一样工作吗?就像让Spring注入我的bean而不必注册或扫描带有@Component-like注释的类的包一样?

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

共有3个答案

田马鲁
2023-03-14

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

景承教
2023-03-14

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

  1. 使用组件扫描并使用组件或其元注释之一(服务、控制器等)对类型进行注释
  2. 定义<代码>

当需要注入时,可以使用从这些bean定义生成的bean。您不希望(至少在我看来)您的容器在没有告诉它是否正常的情况下实例化一个类型。

鄂坚
2023-03-14

我的问题是:有没有办法让Spring管理我要求Application Context实例化的任何类,而无需将它们注册到注释配置(或XML配置)中?

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

您至少可以做以下事情:

AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
context.register(OtherBean.class);
context.register(InjectInMe.class);
context.refresh();
 类似资料:
  • 主要内容:1.Spring IOC容器的设计,2.BeanFactory和ApplicationContext的区别,3.BeanFactory容器的设计原理,4.BeanFactory的详细介绍,5.ApplicationContext容器的设计原理,6.ApplicationContext的详细介绍,7.ApplicationContext容器扩展功能详解介绍1.Spring IOC容器的设计 实现BeanFactory接口的简单容器 实现ApplicationContext接口的高级容器

  • 问题内容: 我是Spring的新手,想将spring ioc连接到我的小型(测试)网络应用程序中。 我有这样的Servlet : 和我的web.xml: 而且我也有这样的Spring配置XML: 我有这样的问题: 我希望在servlet init()期间将requestHelper对象设置为我的servlet。但除了这个,它还给了我nullpointer。 我正在尝试从实现servlet ,将其写

  • 我有三节课。 > 一个抽象类,abstractA有一个受保护的构造函数 一个类扩展了抽象类,父类有两个构造函数 一个类扩展父类,子类有一个构造函数 这是从抽象类扩展而来的父类 这是从父类扩展而来的子类 自定义组件看起来像这样 所以,当spring为特定测试实例化所有bean时,它会正确地实例化子bean。当父bean被实例化时,它得到2个bean[父和子]。所以,我最终会出错, 类型父的多个bea

  • 我有一个基于Spring的WebApp。在我的应用程序上下文中,我定义了这个bean: 我有一个Spring调度servlet定义和一个具有注释的类,我自动连接了这个bean,期望Spring只实例化这个类一次。但是,根据以下调试代码,Spring不止一次实例化这个类: 原因可能是什么? 注意:我使用spring 3.1.2.RELEASE 编辑:多亏了给我的提示,我找到了罪魁祸首。 除了Disp

  • 我是Spring框架的新手,我知道Spring在启动时会实例化单例bean的默认行为,称为热切实例化。这是一个很好的行为,因为它只在启动时暴露bean实例化中的任何问题。但有时这种行为是不可预料的,因此通过向bean定义中添加lazy init=“true”,可以将实例化推迟到第一个请求。 所以,我想知道我们可以使用什么样的场景来延迟实例化bean?。请举例说明。

  • 配置文件配置包扫描路径 递归包扫描获取.class文件 反射,确定需要交给IOC管理的类 对需要注入的类进行依赖注入 配置文件中指定需要扫描的包路径 定义一些注解,分别表示访问控制层、业务逻辑层、数据持久层、依赖注入注解、获取配置文件注解 从配置文件中获取需要扫描的包路径,获取到当前路径下的文件信息及文件夹信息,我们将当前路径下所有以.class结尾的文件添加到一个Set集合中进行存储 遍历这个s