Spring IoC依赖来源
- 自定义bean
- 容器内建bean对象
- 容器内建依赖
Spring IoC依赖注入
-
根据bean名称注入
BeanFactory beanFactory = new ClassPathXmlApplicationContext("classpath:/dependency/injectionDemo.xml"); //依赖来源一:自定义的bean, 根据名称注入 ReporsitoryUser reporsitoryUser = (ReporsitoryUser) beanFactory.getBean("reporsitoryUser");
-
根据bean类型注入
单个bean对象
集合bean对象
-
注入容器内建bean对象
public class ReporsitoryUser { /** * 注入的beanFactory和原来的BeanFactory不是同一个对象, * 注入的是一个容器内建的依赖,而不是一个普通的bean */ //内建非bean对象 (依赖) private BeanFactory beanFactory; private ObjectFactory<User> userObjectFactory; public BeanFactory getBeanFactory() { return beanFactory; } public void setBeanFactory(BeanFactory beanFactory) { this.beanFactory = beanFactory; } public ObjectFactory<User> getUserObjectFactory() { return userObjectFactory; } public void setUserObjectFactory(ObjectFactory<User> userObjectFactory) { this.userObjectFactory = userObjectFactory; } }
BeanFactory beanFactory = new ClassPathXmlApplicationContext("classpath:/dependency/injectionDemo.xml"); //依赖来源一:自定义的bean ReporsitoryUser reporsitoryUser = (ReporsitoryUser) beanFactory.getBean("reporsitoryUser"); //依赖来源二:依赖注入(内部依赖) System.out.println(reporsitoryUser.getBeanFactory()); //返回为false,真正的可以看isRealIoCContainer方法 System.out.println(reporsitoryUser.getBeanFactory() == beanFactory); ObjectFactory userFactory = reporsitoryUser.getUserObjectFactory(); System.out.println(userFactory.getObject()); ObjectFactory objectFactory = reporsitoryUser.getApplicationContextObjectFactory(); System.out.println(reporsitoryUser.getBeanFactory() == objectFactory);
private static void isRealIoCContainer(BeanFactory beanFactory, ReporsitoryUser reporsitoryUser){ //返回为false System.out.println(reporsitoryUser.getBeanFactory() == beanFactory); /** * ApplicationContext 就是一个BeanFactory,但是他们是两个不同的对象 * * org.springframework.beans 和 org.springframework.context 包是 Spring Framework 的 IoC 容器的基础。 * BeanFactory 接口提供了一种能够管理任何类型对象的高级配置机制。 * ApplicationContext 是 BeanFactory 的一个子接口。 */ //因为ApplicationContext是BeanFactory的子集 ApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:/dependency/injectionDemo.xml"); ReporsitoryUser applicationContextBean = (ReporsitoryUser) applicationContext.getBean("reporsitoryUser"); //返回为false /** * ConfigurableApplicationContext <- ApplicationContext <- BeanFactory * ConfigurableApplicationContext#getBeanFactory实际获取的是DefaultListableBeanFactory * 在上下文中的实现是组合了一种方式,同时又在接口上是继承的关系,有点像代理的情况 * ConfigurableApplicationContext # getBean 实际上是用代理对象去查bean, * 并不是自己有这样的能力,而是外面组装了一个组合对象来帮助做这个事情 */ System.out.println(reporsitoryUser.getBeanFactory() == applicationContext); System.out.println(applicationContextBean.getBeanFactory() == applicationContext); }
//依赖来源三:容器内建bean Environment environment = beanFactory.getBean(Environment.class); System.out.println(environment);
注入非bean对象
-
注入类型
- 实时注入
- 延迟注入
BeanFactory && ApplicationContext
org.springframework.beans 和 org.springframework.context 包是 Spring Framework 的 IoC 容器的基础。
-
BeanFactory 接口提供了一种能够管理任何类型对象的高级配置机制。
管理的对象并不等于Beans,依赖来源并不只限定于Bean
-
ApplicationContext 是 BeanFactory 的一个子接口。补充了如下特性:
- 与 Spring 的 AOP 功能更容易集成 (简化了和Spring AOP的整合)
- 消息资源处理(用于国际化)
- 事件发布 (Spring的事件)
- 应用层特定上下文,例如用于 Web 应用程序的 WebApplicationContext
简而言之,BeanFactory 提供了配置框架和基本功能,ApplicationContext 增加了更多企业特定的功能。ApplicationContext 是 BeanFactory 的完整超集
BeanFactory 和 Application是同一类事物,只不过在底层实现的时候ApplicationContext组合了一个BeanFactory的实现,因此ApplicationContext不等于BeanFactory,尽管他俩都复用了同样的接口。(完美的解释了上述的自定义BeanFactory和依赖注入获取的BeanFactory不是同一个对象的原因)
使用Spring IoC容器(选BeanFactory还是ApplicationContext)
- BeanFactory是Spring底层IoC容器,存储了很多关于bean的定义、配置,以及bean的管理对象。
- ApplicationContext是具备应用特性的BeanFactory的超集,