我是Spring框架的新手,我一直在摆弄它,并把一些样本应用放在一起,目的是评估Spring MVC在即将到来的公司项目中的使用。到目前为止,我真的很喜欢Spring MVC,它看起来很容易使用,并鼓励你编写对单元测试非常友好的类。
作为练习,我正在为我的一个示例/测试项目编写一个主方法。我不清楚的一件事是BeanFactory和ApplicationContext之间的确切区别——哪个适合在哪些条件下使用?
我知道ApplicationContext扩展了BeanFactory,但是如果我只是编写一个简单的主方法,我是否需要ApplicationContext提供的额外功能呢?ApplicationContext究竟提供了什么样的额外功能?
除了回答“我应该在main()方法中使用哪个”之外,关于在这样的场景中应该使用哪个实现,是否有任何标准或指南?我的main()方法是否应该被编写成依赖于bean/应用程序配置的XML格式——这是一个安全的假设吗,还是我将用户锁定到某个特定的东西?
这个答案在web环境中会改变吗——如果我的任何类需要了解Spring,它们更可能需要ApplicationContext吗?
谢谢你的帮助。我知道很多问题都可以在参考手册中找到答案,但如果没有仔细阅读手册,我很难找到这两个接口的清晰分解以及各自的优缺点。
在大多数情况下,首选ApplicationContext,除非需要节省资源,比如在移动应用程序上。
我不确定是否依赖于XML格式,但我非常确定ApplicationContext最常见的实现是XML实现,例如ClassPathXmlApplicationContext、XmlWebApplicationContext和FileSystemXmlApplicationContext。我只用过这三个。
如果您正在开发web应用程序,可以肯定地说,您将需要使用XmlWebApplicationContext。
如果您希望bean能够感知Spring,您可以让它们为此实现BeanFactoryAware和/或ApplicationContextAware,因此您可以使用BeanFactory或ApplicationContext并选择实现哪个接口。
我认为最好总是使用ApplicationContext,除非您像其他人所说的那样处于移动环境中。ApplicationContext有更多的功能,你肯定想使用postprocessor,比如RequiredAnnotationBeanPostProcessor, AutowiredAnnotationBeanPostProcessor和CommonAnnotationBeanPostProcessor,这将帮助你简化你的Spring配置文件,你可以在你的bean中使用@Required, @PostConstruct, @Resource等注释。
即使您不使用ApplicationContext提供的所有东西,最好还是使用它,然后如果您决定使用一些资源东西,如消息或post处理器,或其他模式来添加事务通知等,您将已经拥有一个ApplicationContext,而不需要更改任何代码。
如果你在写一个独立的应用程序,加载ApplicationContext在主方法中,使用ClassPathXmlApplicationContext,并得到主豆和调用它的运行()(或其他方法)来启动应用程序。如果您正在编写一个web应用程序,使用web . xml中的ContextLoaderListener,创造了从ServletContext ApplicationContext你稍后可以得到它,无论你使用JSP时,JSF, JSTL, struts,挂毯等。
Also, remember you can use multiple Spring configuration files and you can either create the ApplicationContext by listing all the files in the constructor (or listing them in the context-param for the ContextLoaderListener), or you can just load a main config file which has import statements. You can import a Spring configuration file into another Spring configuration file by using <import resource="otherfile.xml" /> which is very useful when you programmatically create the ApplicationContext in the main method and load only one Spring config file.
对我来说,选择BeanFactory而不是ApplicationContext的主要区别似乎是ApplicationContext将预先实例化所有的bean。来自Spring文档:
Spring sets properties and resolves dependencies as late as possible, when the bean is actually created. This means that a Spring container which has loaded correctly can later generate an exception when you request an object if there is a problem creating that object or one of its dependencies. For example, the bean throws an exception as a result of a missing or invalid property. This potentially delayed visibility of some configuration issues is why ApplicationContext implementations by default pre-instantiate singleton beans. At the cost of some upfront time and memory to create these beans before they are actually needed, you discover configuration issues when the ApplicationContext is created, not later. You can still override this default behavior so that singleton beans will lazy-initialize, rather than be pre-instantiated.
考虑到这一点,我最初选择BeanFactory用于集成/性能测试,因为我不想加载整个应用程序来测试孤立的bean。但是——如果我说错了,有人会纠正我——BeanFactory不支持类路径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);
}
}
}
参考Spring Docs中的这个文档:
http://static.springsource.org/spring/docs/3.2.x/spring-framework-reference/html/beans.html#context-introduction-ctx-vs-beanfactory
5.15.1 bean工厂还是应用上下文?
使用ApplicationContext,除非你有很好的理由不这样做。
Because the ApplicationContext includes all functionality of the BeanFactory, it is generally recommended over the BeanFactory, except for a few situations such as in an Applet where memory consumption might be critical and a few extra kilobytes might make a difference. However, for most typical enterprise applications and systems, the ApplicationContext is what you will want to use. Spring 2.0 and later makes heavy use of the BeanPostProcessor extension point (to effect proxying and so on). If you use only a plain BeanFactory, a fair amount of support such as transactions and AOP will not take effect, at least not without some extra steps on your part. This situation could be confusing because nothing is actually wrong with the configuration.
BeanFactory和ApplicationContext都是从spring IOC容器中获取bean的方法,但仍有一些区别。
BeanFactory是实例化、配置和管理许多bean的实际容器。这些bean通常彼此协作,因此它们之间存在依赖关系。这些依赖关系反映在BeanFactory使用的配置数据中。
BeanFactory和ApplicationContext都是Java接口,而ApplicationContext扩展了BeanFactory。它们都是使用XML配置文件进行配置的。简而言之,BeanFactory提供了基本的控制反转(IoC)和依赖注入(DI)特性,而ApplicationContext提供了高级特性。
BeanFactory由接口“org.springframework.beans”表示。其中BeanFactory有多个实现。
ClassPathResource resource = new ClassPathResource("appConfig.xml");
XmlBeanFactory factory = new XmlBeanFactory(resource);
区别
BeanFactory instantiate bean when you call getBean() method while ApplicationContext instantiate Singleton bean when container is started, It doesn't wait for getBean() to be called.
BeanFactory doesn't provide support for internationalization but ApplicationContext provides support for it.
Another difference between BeanFactory vs ApplicationContext is ability to publish event to beans that are registered as listener.
One of the popular implementation of BeanFactory interface is XMLBeanFactory while one of the popular implementation of ApplicationContext interface is ClassPathXmlApplicationContext.
If you are using auto wiring and using BeanFactory than you need to register AutoWiredBeanPostProcessor using API which you can configure in XML if you are using ApplicationContext. In summary BeanFactory is OK for testing and non production use but ApplicationContext is more feature rich container implementation and should be favored over BeanFactory
BeanFactory by default its support Lazy loading and ApplicationContext by default support Aggresive loading.
基本上我们可以用两种方式创建spring容器对象
使用BeanFactory。
使用ApplicationContext。
都是界面,
使用实现类,我们可以为spring容器创建对象
来看看区别
BeanFactory:
不支持基于注释的依赖注入。
不支持I18N。
默认情况下,它支持惰性加载。
它不允许配置到多个配置文件。
例如:BeanFactory context=new XmlBeanFactory(new Resource(“applicationContext.xml”));
ApplicationContext
支持基于注释的依赖注入。@ autowired, @PreDestroy
I18N支持
它默认支持侵略性加载。
它允许配置多个配置文件。
前任:
ApplicationContext context=new ClasspathXmlApplicationContext(“applicationContext.xml”);
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。
通过CLASSPATH加载的bean
XMLWebApplicationContext和AnnotationConfigWebApplicationContext bean通过web应用程序上下文加载。
从基于Annotation的配置中加载Spring bean。
例子:
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(BeansConfiguration.class);
ApplicationContext是由web.xml中定义的ContextLoaderListener或ContextLoaderServlet和struts-config.xml中定义的ContextLoaderPlugin初始化的容器。
注意:XmlBeanFactory从Spring 3.1开始已弃用,取而代之的是DefaultListableBeanFactory和XmlBeanDefinitionReader。
在实时场景中,Spring IOC核心容器(BeanFactory)和高级J2EE容器(ApplicationContext)之间的区别如下。
BeanFactory will create objects for the beans (i.e., for POJO classes) mentioned in the spring.xml file (<bean></bean>) only when you call the .getBean() method, but whereas ApplicationContext creates the objects for all the beans (<bean></bean> if its scope is not explicitly mentioned as "Prototype") configured in the spring.xml while loading the spring.xml file itself.
BeanFactory: (Lazy container because it creates the objects for the beans only when you explicitly call from the user/main class)
/*
* Using core Container - Lazy container - Because it creates the bean objects On-Demand
*/
//creating a resource
Resource r = (Resource) new ClassPathResource("com.spring.resources/spring.xml");
//creating BeanFactory
BeanFactory factory=new XmlBeanFactory(r);
//Getting the bean for the POJO class "HelloWorld.java"
HelloWorld worldObj1 = (HelloWorld) factory.getBean("test");
ApplicationContext: (Eager container because of creating the objects of all singleton beans while loading the spring.xml file itself)
ApplicationContext context = new ClassPathXmlApplicationContext("com/ioc/constructorDI/resources/spring.xml");
Technically, using ApplicationContext is recommended because in real-time applications, the bean objects will be created while the application is getting started in the server itself. This reduces the response time for the user request as the objects are already available to respond.
a. bean工厂和应用程序上下文之间的一个区别是前者只在调用getBean()方法时实例化bean,而ApplicationContext在容器启动时实例化单例bean,它不等待getBean被调用。
b。
ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
or
ApplicationContext context = new ClassPathXmlApplicationContext{"spring_dao.xml","spring_service.xml};
您可以根据项目需求使用一个或多个xml文件。我在这里使用了两个xml文件,即一个用于服务类的配置细节,另一个用于dao类。这里ClassPathXmlApplicationContext是ApplicationContext的子。
c. BeanFactory Container是基本容器,它只能创建对象和注入依赖项。但我们不能附加其他服务,如安全、事务、消息等,以提供我们必须使用ApplicationContext容器的所有服务。
d. BeanFactory不提供国际化支持,即i18n,但ApplicationContext提供了国际化支持。
e. BeanFactory容器不支持自动扫描(支持基于注释的依赖注入)特性,但ApplicationContext容器支持。
f.直到请求时间,Beanfactory容器才会创建bean对象。这意味着Beanfactory容器会懒惰地装载bean。而ApplicationContext容器只在加载时创建单例bean的对象。这意味着有早期装载。
Beanfactory容器只支持bean的两个作用域(单例和原型)。但是ApplicationContext容器支持所有的bean范围。
BeanFactory和ApplicationContext的区别如下:
BeanFactory uses lazy initialization but ApplicationContext uses eager initialization. In case of BeanFactory, bean is created when you call getBeans() method, but bean is created upfront in case of ApplicationContext when the ApplicationContext object is created.
BeanFactory explicitly provide a resource object using syntax but ApplicationContext creates and manages resource objects on its own.
BeanFactory doesnt support internatiolization but ApplicationContext supports internationalization.
With BeanFactory annotation based dependency injection is not supported but annotation based dependency injection is supported in 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");
我需要解释BeanFactory & ApplicationContext。
BeanFactory: BeanFactory is root interface for accessing the SpringBean Container.There is basic client view of a bean container.
That interface is implemented by the object class that holds the number of beans definitions, and each uniquely identify by the String name
Depending the Bean definition the factory will return the instance that instance may be the instance of contained object or a single shared instance. Which type of instance will be return depends of bean factory configuration.
Normally Bean factory will load the all the all the beans definition, which stored in the configuration source like XML...etc.
BeanFactory是一个为依赖注入提供基本支持的最简单的容器
应用程序上下文
应用程序上下文是spring应用程序中的一个中心接口,它向应用程序提供配置信息。它实现了Bean工厂接口。
应用程序上下文是一个高级容器,它增加了高级级别的企业特定功能,例如从属性文件....解析文本消息的能力等
一个ApplicationContext提供:
Bean factory methods for accessing application components. Inherited from ListableBeanFactory.
The ability to load file resources in a generic fashion. Inherited from the ResourceLoader interface.
The ability to publish events to registered listeners. Inherited from the ApplicationEventPublisher interface.
The ability to resolve messages, supporting internationalization. Inherited from the MessageSource interface.
Inheritance from a parent context. Definitions in a descendant context will always take priority. This means, for example, that a single parent context can be used by an entire web application, while each servlet has its own child context that is independent of that of any other servlet.
In addition to standard BeanFactory lifecycle capabilities, ApplicationContext implementations detect and invoke ApplicationContextAware beans as well as ResourceLoaderAware, ApplicationEventPublisherAware and MessageSourceAware beans.