BeanFactory和ApplicationContext谁才是Spring Ioc容器?
BeanFactory 接口提供了能够管理任何类型对象的高级配置机制。ApplicationContext 是BeanFactory 的子接口。ApplicationContext添加了以下特性:
- 更容易与 Spring 的 AOP 特性集成
- 消息资源处理(用于国际化)
- 事件发布。
- 应用层特定的上下文,例如 web 应用程序中使用的 WebApplicationContext。
- public?interface?ApplicationContext?extends?EnvironmentCapable,?ListableBeanFactory,?HierarchicalBeanFactory,
- ??MessageSource,?ApplicationEventPublisher,?ResourcePatternResolver?{
- public?interface?ListableBeanFactory?extends?BeanFactory?{
简而言之,BeanFactory 提供了配置框架和基本功能,而ApplicationContext 添加了更多特定于企业的功能。
总结:BeanFactory和ApplicationContext可以说都是Spring Ioc容器,在底层实现时,ApplicationContext不止实现了BeanFactory接口,同时还组合了BeanFactory的另一个实现类DefaultListableBeanFactory。
- public?class?ClassPathXmlApplicationContext?extends?AbstractXmlApplicationContext?{
- public?abstract?class?AbstractXmlApplicationContext?extends?AbstractRefreshableConfigApplicationContext?{
- public?abstract?class?AbstractRefreshableConfigApplicationContext?extends?AbstractRefreshableApplicationContext
- ??implements?BeanNameAware,?InitializingBean?{
- public?abstract?class?AbstractRefreshableApplicationContext?extends?AbstractApplicationContext?{
- ?@Nullable
- ?private?Boolean?allowBeanDefinitionOverriding;
- ?@Nullable
- ?private?Boolean?allowCircularReferences;
- ?/**?Bean?factory?for?this?context.?*/
- ?@Nullable
- ?private?DefaultListableBeanFactory?beanFactory;
- @Override
- ?public?final?ConfigurableListableBeanFactory?getBeanFactory()?{
- ??synchronized?(this.beanFactoryMonitor)?{
- ???if?(this.beanFactory?==?null)?{
- ????throw?new?IllegalStateException("BeanFactory?not?initialized?or?already?closed?-?"?+
- ??????"call?'refresh'?before?accessing?beans?via?the?ApplicationContext");
- ???}
- ???return?this.beanFactory;
- ??}
- ?}
configurableApplicationContext <-ApplicationContext<-BeanFactory configurableApplicationContext#getBeanFactory()
Spring容器启动的过程中,会将Bean解析成Spring内部的BeanDefinition结构。 不管是是通过xml配置文件的 <Bean> 标签,还是通过注解配置的 @Bean ,还是 @Compontent 标注的类,还是扫描得到的类,它最终都会被解析成一个BeanDefinition对象,最后Bean工厂就会根据这份Bean的定义信息,对bean进行实例化、初始化等等操作。
Bean定义配置注意基于xml文件、properties文件、Java注解以及java Api;
Ioc容器配置注意基于xml文件、Java注解以及Java Api;
外部化属性配置基于Java注解 @Value。
Spring IoC依赖注入
- public?class?UserRepository?{
- ????/**
- ?????*?自定义bean
- ?????*/
- ????private?Collection<User>?users;
- ????/**
- ?????*?bean工厂
- ?????*?内建非bean对象
- ?????*/
- ????private?BeanFactory?beanFactory;
- ????private?ObjectFactory<User>?userObjectFactory;
- ????private?ObjectFactory<ApplicationContext>?objectFactory;
- ????public?ObjectFactory<ApplicationContext>?getObjectFactory()?{
- ????????return?objectFactory;
- ????}
- ????public?void?setObjectFactory(ObjectFactory<ApplicationContext>?objectFactory)?{
- ????????this.objectFactory?=?objectFactory;
- ????}
- ????public?ObjectFactory<User>?getUserObjectFactory()?{
- ????????return?userObjectFactory;
- ????}
- ????public?void?setUserObjectFactory(ObjectFactory<User>?userObjectFactory)?{
- ????????this.userObjectFactory?=?userObjectFactory;
- ????}
- ????public?Collection<User>?getUsers()?{
- ????????return?users;
- ????}
- ????public?BeanFactory?getBeanFactory()?{
- ????????return?beanFactory;
- ????}
- ????public?void?setBeanFactory(BeanFactory?beanFactory)?{
- ????????this.beanFactory?=?beanFactory;
- ????}
- ????public?void?setUsers(Collection<User>?users)?{
- ????????this.users?=?users;
- ????}
- }
Xml配置信息
- <?xml?version="1.0"?encoding="UTF-8"?>
- <beans?xmlns="http://www.springframework.org/schema/beans"
- ???????xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- ???????xsi:schemaLocation="http://www.springframework.org/schema/beans
- ????????https://www.springframework.org/schema/beans/spring-beans.xsd">
- ????<bean?id="user"?class="org.mango.spring.ioc.overview.domain.User"?>
- ????????<property?name="id"?value="1"/>
- ????????<property?name="name"?value="mango"/>
- ????</bean>
- ????<bean?id="superUser"?class="org.mango.spring.ioc.overview.domain.SuperUser"?parent="user"?primary="true">
- ????????<property?name="address"?value="西安"></property>
- ????</bean>
- ????<bean?id="objectFactory"?class="org.springframework.beans.factory.config.ObjectFactoryCreatingFactoryBean"?>
- ????????<property?name="targetBeanName"?value="user"></property>
- ????</bean>
- </beans>
- <?xml?version="1.0"?encoding="UTF-8"?>
- <beans?xmlns="http://www.springframework.org/schema/beans"
- ???????xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- ???????xmlns:util="http://www.springframework.org/schema/util"
- ???????xsi:schemaLocation="
- ????????http://www.springframework.org/schema/beans?https://www.springframework.org/schema/beans/spring-beans.xsd
- ????????http://www.springframework.org/schema/util?https://www.springframework.org/schema/util/spring-util.xsd">
- ????<!--通过导入复用?dependency-->
- ????<import?resource="dependency-lookup-context.xml"></import>
- ????<!--autowire自动注入-->
- ????<bean?id="userRepository"?class="org.mango.spring.ioc.overview.repository.UserRepository"
- ??????????autowire="byType">?
- ????????<!--硬编码-->
- ?????<!--???<property?name="users">
- ????????????<util:list>
- ????????????????<ref?bean="user"/>
- ????????????????<ref?bean="superUser"/>
- ????????????</util:list>
- ????????</property>-->
- ????</bean>
- </beans>
- ?//配置xml文件?启动spring?应用上下文
- ????????BeanFactory?beanFactory?=?new?ClassPathXmlApplicationContext("META-INF/dependency-injection-context.xml");
- ????????//来源1:?自定义bean
- ????????UserRepository?userRepository?=?(UserRepository)?beanFactory.getBean("userRepository");
- ????????//实时注入bean
- ????????userRepository.getUsers().forEach(System.out::println);
- ????????//来源2:?依赖注入?(内建依赖)
- ????????System.out.println(userRepository.getBeanFactory());
- ????????System.out.println(userRepository.getBeanFactory()?==?beanFactory);
- ????????//延时注入
- ????????ObjectFactory?userFactory?=?userRepository.getUserObjectFactory();
- ????????System.out.println(userFactory.getObject());
- ????????ObjectFactory?objectFactory?=?userRepository.getObjectFactory();
- ????????System.out.println(objectFactory.getObject());
- ????????System.out.println(objectFactory.getObject()?==?beanFactory);
- ????????//来源三:?容器内建?bean
- ????????Environment?environment?=?beanFactory.getBean(Environment.class);
? ? ? ? ? ? ? ? ?System.out.println("获取Environment类型的bean"?+?environment);
?System.out.println(userRepository.getBeanFactory()?==?beanFactory); 输出为false
|