beanfactory与applicationcontext

ie3xauqp  于 2021-07-13  发布在  Java
关注(0)|答案(10)|浏览(244)

我对spring框架还很陌生,我一直在研究它,并将一些示例应用程序放在一起,以便评估springmvc,以便在即将到来的公司项目中使用。到目前为止,我非常喜欢我在springmvc中看到的东西,似乎非常易于使用,并鼓励您编写非常单元测试友好的类。
作为练习,我正在为我的一个示例/测试项目编写一个main方法。我不清楚的一点是 BeanFactory 以及 ApplicationContext -在什么条件下使用哪个合适?
我明白 ApplicationContext 延伸 BeanFactory ,但如果我只是编写一个简单的main方法,是否需要 ApplicationContext 提供?到底什么样的额外功能 ApplicationContext 提供?
除了回答“我应该在main()方法中使用哪种方法”之外,对于在这种情况下应该使用哪种实现,还有什么标准或指导方针吗?我的main()方法应该根据bean/应用程序配置以xml格式编写吗?这是一个安全的假设,还是我将用户锁定为特定的对象?
这个答案在web环境中会改变吗?如果我的任何一个类需要了解spring,它们是否更可能需要spring ApplicationContext ?
谢谢你的帮助。我知道这些问题很多可能都在参考手册中得到了解答,但如果不仔细阅读手册,我很难找到这两个接口的详细分类以及各自的优缺点。

hxzsmxv2

hxzsmxv21#

spring文档在这方面做得很好:3.8.1。beanfactory或applicationcontext?。他们有一个带有比较的表,我将发布一个片段:
豆制品厂
bean示例化/连接
应用程序上下文
bean示例化/连接
自动beanpostprocessor注册
自动BeanFactory后处理器注册
方便的消息源访问(适用于i18n)
applicationevent出版物
因此,如果您需要在应用程序上下文端显示的任何点,您应该使用applicationcontext。

xmd2e60i

xmd2e60i2#

spring提供了两种ioc容器,一种是 XMLBeanFactory 另一个是 ApplicationContext .

+---------------------------------------+-----------------+--------------------------------+
|                                       | BeanFactory     |       ApplicationContext       |
+---------------------------------------+-----------------+--------------------------------+
| Annotation support                    | No              | Yes                            |
| BeanPostProcessor Registration        | Manual          | Automatic                      |
| implementation                        | XMLBeanFactory  | ClassPath/FileSystem/WebXmlApplicationContext|
| internationalization                  | No              | Yes                            |
| Enterprise services                   | No              | Yes                            |
| ApplicationEvent publication          | No              | Yes                            |
+---------------------------------------+-----------------+--------------------------------+

FileSystemXmlApplicationContext 通过完整路径加载bean。 ClassPathXmlApplicationContext 通过类路径加载的bean XMLWebApplicationContext 以及 AnnotationConfigWebApplicationContext 通过web应用程序上下文加载的bean。 AnnotationConfigApplicationContext 从基于注解的配置加载springbean。
例子:

ApplicationContext applicationContext = new AnnotationConfigApplicationContext(BeansConfiguration.class);
``` `ApplicationContext` 容器是否由 `ContextLoaderListener` 或者 `ContextLoaderServlet` 定义在 `web.xml` 以及 `ContextLoaderPlugin` 定义于 `struts-config.xml` .
注: `XmlBeanFactory` 从Spring3.1开始就被弃用,取而代之的是 `DefaultListableBeanFactory` 以及 `XmlBeanDefinitionReader` .
tzcvj98z

tzcvj98z3#

对我来说,选择的主要区别 BeanFactory 结束 ApplicationContext 似乎是这样 ApplicationContext 将预先示例化所有bean。来自spring文档:
spring在bean实际创建时尽可能晚地设置属性和解析依赖项。这意味着,如果在创建一个对象或其依赖项时出现问题,那么正确加载的spring容器稍后可以在您请求该对象时生成一个异常。例如,bean由于缺少或无效属性而引发异常。这可能会延迟某些配置问题的可见性,这就是为什么applicationcontext实现在默认情况下预先示例化单例bean的原因。在实际需要这些bean之前,您需要花费一些前期时间和内存来创建它们,但是在创建applicationcontext时(而不是以后)会发现配置问题。您仍然可以重写这个默认行为,这样单例bean将延迟初始化,而不是预先示例化。
鉴于此,我最初选择 BeanFactory 用于集成/性能测试,因为我不想加载整个应用程序来测试独立的bean。但是——如果我错了,有人纠正我—— BeanFactory 不支持 classpath xml配置。所以呢 BeanFactory 以及 ApplicationContext 每一个都提供了我想要的关键特性,但两者都没有。
正如我所知,文档中关于重写默认示例化行为的注解发生在配置中,并且是每个bean的,所以我不能在xml文件中设置“lazy init”属性,否则我就只能维护一个用于测试的版本和一个用于部署的版本。
我最后做的是扩展 ClassPathXmlApplicationContext 要在这样的测试中延迟加载bean:

public class LazyLoadingXmlApplicationContext extends ClassPathXmlApplicationContext {

    public LazyLoadingXmlApplicationContext(String[] configLocations) {
        super(configLocations);
    }

    /**
     * Upon loading bean definitions, force beans to be lazy-initialized.
     * @see org.springframework.context.support.AbstractXmlApplicationContext#loadBeanDefinitions(org.springframework.beans.factory.xml.XmlBeanDefinitionReader)
     */

    @Override
    protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws IOException {
        super.loadBeanDefinitions(reader);
        for (String name: reader.getBeanFactory().getBeanDefinitionNames()) {
            AbstractBeanDefinition beanDefinition = (AbstractBeanDefinition) reader.getBeanFactory().getBeanDefinition(name);
            beanDefinition.setLazyInit(true);
        }
    }

}
7xllpg7q

7xllpg7q4#

为了补充miguel ping的回答,以下是文档中的另一部分:
简短版本:使用applicationcontext,除非你有很好的理由不这样做。对于那些想稍微深入了解上述建议“但为什么”的人,请继续阅读。
(为将来可能阅读此问题的spring新手发布)

h5qlskok

h5qlskok5#

ApplicationContext 是比 BeanFactory 在新的 Spring 版本中 BeanFactory 替换为 ApplicationContext . 但仍然 BeanFactory 存在向后兼容性 ApplicationContext extends BeanFactory 有以下好处
它支持文本消息的国际化
它支持向注册的侦听器发布事件
对资源(如URL和文件)的访问

mo49yndu

mo49yndu6#

applicationcontext:它加载在spring配置文件中配置的springbean,并在容器启动时管理springbean的生命周期。
beanfactory加载在spring配置文件中配置的SpringBean,当我们调用getbean(“springbeanref”)时管理SpringBean的生命周期,因此当我们在SpringBean生命周期开始时调用getbean(“springbeanref”)时。

sigwle7e

sigwle7e7#

我认为最好总是使用applicationcontext,除非你处在一个移动环境中,就像别人已经说过的那样。applicationcontext有更多的功能,你肯定想使用后处理器,比如requiredannotationbeanpostprocessor,autowiredannotationbeanpostprocessor和commonannotationbeanpostprocessor,这将帮助你简化spring配置文件,你可以使用注解,比如@required,@postconstruct,@resource,在你的豆子里。
即使您没有使用applicationcontext提供的所有内容,最好还是使用它,以后如果您决定使用一些资源内容(如消息或后处理器)或其他模式来添加事务性建议等,那么您就已经有了applicationcontext,不需要更改任何代码。
如果您正在编写一个独立的应用程序,请使用classpathxmlapplicationcontext在主方法中加载applicationcontext,然后获取主bean并调用其run()(或任何方法)来启动应用程序。如果您正在编写web应用程序,请使用web.xml中的contextloaderlistener,这样它就可以创建applicationcontext,并且您可以稍后从servletcontext获取它,而不管您是否使用jsp、jsf、jstl、struts、tapestry等。
另外,请记住,您可以使用多个spring配置文件,您可以通过列出构造函数中的所有文件来创建applicationcontext(或者在contextloaderlistener的context参数中列出这些文件),也可以只加载包含import语句的主配置文件。您可以使用将一个spring配置文件导入另一个spring配置文件,这在以编程方式在main方法中创建applicationcontext并仅加载一个spring配置文件时非常有用。

busg9geu

busg9geu8#

beanfactory和applicationcontext的区别如下:
beanfactory使用延迟初始化,而applicationcontext使用快速初始化。对于beanfactory,bean是在调用getbeans()方法时创建的,但是对于applicationcontext,bean是在创建applicationcontext对象时预先创建的。
beanfactory使用语法显式提供资源对象,但applicationcontext自己创建和管理资源对象。
beanfactory不支持国际化,但applicationcontext支持国际化。
对于beanfactory,不支持基于注解的依赖项注入,但在applicationcontext中支持基于注解的依赖项注入。
使用beanfactory:

BeanFactory beanfactory = new XMLBeanFactory(new FileSystemResource("spring.xml"));
 Triangle triangle =(Triangle)beanFactory.getBean("triangle");

使用applicationcontext:

ApplicationContext context = new ClassPathXMLApplicationContext("spring.xml")
Triangle triangle =(Triangle)context.getBean("triangle");
50few1ms

50few1ms9#

在大多数情况下,applicationcontext是首选,除非您需要节省资源,比如在移动应用程序上。
我不确定是否依赖于xml格式,但我非常确定applicationcontext最常见的实现是xml实现,例如classpathxmlapplicationcontext、xmlwebapplicationcontext和filesystemxmlapplicationcontext。这是我唯一用过的三个。
如果您正在开发一个web应用程序,可以肯定地说您将需要使用xmlwebapplicationcontext。
如果您想让bean了解spring,可以让它们实现beanfactoryaware和/或applicationcontextaware,这样就可以使用beanfactory或applicationcontext并选择要实现的接口。

hrirmatl

hrirmatl10#

beanfactory和applicationcontext都是从springioc容器中获取bean的方法,但是仍然有一些不同。
beanfactory是示例化、配置和管理许多bean的实际容器。这些bean通常是相互协作的,因此它们之间有依赖关系。这些依赖关系反映在beanfactory使用的配置数据中。
beanfactory和applicationcontext都是java接口,applicationcontext扩展了beanfactory。它们都是使用xml配置文件进行配置的。简而言之,beanfactory提供了基本的控制反转(ioc)和依赖注入(di)功能,而applicationcontext提供了高级功能。
beanfactory由接口“org.springframework.beans.factory”表示,其中beanfactory有多个实现。

ClassPathResource resource = new ClassPathResource("appConfig.xml");
XmlBeanFactory factory = new XmlBeanFactory(resource);

差异
beanfactory示例化bean wh

相关问题