Spring(03)Spring IOC 概述
Spring(03)Spring IOC 概述
Spring 核心编程思想目录:https://www.cnblogs.com/binarylei/p/12290153.html
1. Spring IoC 依赖查找
1.1 根据 Bean 名称查找
-
实时查找
User user = (User) beanFactory.getBean("user");
-
延迟查找
bean 配置如下:
<bean id="user1" class="com.binarylei.spring.ioc.bean.User" lazy-init="true"/> <bean id="user2" class="org.springframework.beans.factory.config.ObjectFactoryCreatingFactoryBean"> <property name="targetBeanName" value="user1"/> </bean>
通过 ObjectFactory 获取 bean 时会延迟加载 bean,只有手动调用 getObject 方法都会初始化 User 对象。将 User 设置为 lazy-init="true" 效果会更明显,Spring 会默认初始化所有非懒加载的 bean。
ObjectFactory<User> objectFactory = (ObjectFactory) beanFactory.getBean("user2"); User user = objectFactory.getObject();
思考: ObjectFactory 和 FactoryBean 都是通过 getObject 创建对象,它们有什么区别呢?
-
ObjectFactory :是属于懒加载 bean,只有手动调用 getObject 都会初始化 bean。
-
FactoryBean:当加载 FactoryBean 的同时就会调用 getObject 初始化对象,不属于懒加载 bean。Spring 中如果想要获取 FactoryBean 本身,可以在 bean 名称前加载
&
符号。FactoryBean<User> factoryBean = (FactoryBean<User>) beanFactory.getBean("&user");
1.2 根据 Bean 类型查找
-
单个 Bean 对象
User user = beanFactory.getBean(User.class);
-
集合 Bean 对象
Map<String, User> userMap = ((DefaultListableBeanFactory) beanFactory) .getBeansOfType(User.class);
思考: beanFactory.getBean(User.class),如果返回多个对象,Spring 会如何处理,如何解决?
当 Spring 容器中有多个 User 对象时,Spring 会抛出异常 NoUniqueBeanDefinitionException,这时可以通过标注 primary 来处理。
<bean id="user1" class="com.binarylei.spring.ioc.bean.User" primary="true"/>
1.3 根据 Bean 名称 + 类型查找
User user = beanFactory.getBean("user", User.class);
1.4 根据 Java 注解查找
Map<String, Object> beanMap = ((DefaultListableBeanFactory) beanFactory)
.getBeansWithAnnotation(Component.class);
2. Spring IoC 依赖注入
有 UserManager 类,如何将 users 注入呢?
@Data
public class UserManager {
private BeanFactory beanFactory;
private SuperUser superUser;
private List<User> users;
}
2.1 根据 Bean 名称注入
-
单个Bean 对象
<bean id="userManager" class="com.binarylei.spring.ioc.bean.UserManager"> <property name="superUser" ref="user"/> </bean>
-
集合 Bean 对象
<bean id="userManager" class="com.binarylei.spring.ioc.bean.UserManager"> <property name="users"> <util:list> <ref bean="user1"/> <ref bean="user2"/> </util:list> </property> </bean>
2.2 根据 Bean 类型注入
<bean id="userManager" class="com.binarylei.spring.ioc.bean.UserManager"
autowire="byType"/>
2.3 注入容器內建 Bean 对象
如 Environment 对象。
2.4 注入非 Bean 对象
如 BeanFacory 可以正常注入到 UserManager 中。如果通过 beanFactory.getBean(BeanFactory.class) 会抛出 NoSuchBeanDefinitionException 异常。
2.5 注入类型
- 实时注入
- 延迟注入
2.6 注入模式
- 手动模式- 配置或者编程的方式,提前安排注入规则
- XML 资源配置元信息
- Java 注解配置元信息
- API 配置元信息
- 自动模式- 实现方提供依赖自动关联的方式,按照內建的注入规则
- Autowiring(自动绑定):no、byName、byType、constructor
3. Spring IoC 依赖来源
- 自定义 Bean
- 容器內建 Bean 对象
- 容器內建依赖
4. Spring IoC 配置元信息
-
Bean 定义配置
- 基于 XML 文件
- 基于 Properties 文件
- 基于 Java 注解
- 基于 Java API(专题讨论)
-
IoC 容器配置
- 基于 XML 文件
- 基于 Java 注解
- 基于 Java API (专题讨论)
-
外部化属性配置
- 基于Java 注解,@Value 注解
5. Spring IoC 容器
- BeanFactory 是 Spring 底层 IoC 容器。
- ApplicationContext 是具备应用特性的 BeanFactory 超集。
ApplicationContext 除了IoC 容器角色,还有提供:
- 面向切面(AOP)
- 配置元信息(Configuration Metadata)
- 资源管理(Resources)
- 事件(Events)
- 国际化(i18n)
- 注解(Annotations)
- Environment 抽象(Environment Abstraction)
public interface ApplicationContext extends EnvironmentCapable,
ListableBeanFactory, HierarchicalBeanFactory, MessageSource,
ApplicationEventPublisher, ResourcePatternResolver {
}
6. Spring 应用上下文
ApplicationContext
7. Spring IoC 容器生命周期
- 启动
- 运行
- 停止
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
prepareRefresh();
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
prepareBeanFactory(beanFactory);
try {
postProcessBeanFactory(beanFactory);
invokeBeanFactoryPostProcessors(beanFactory);
registerBeanPostProcessors(beanFactory);
initMessageSource();
initApplicationEventMulticaster();
onRefresh();
registerListeners();
finishBeanFactoryInitialization(beanFactory);
finishRefresh();
} catch (BeansException ex) {
destroyBeans();
cancelRefresh(ex);
throw ex;
} finally {
resetCommonCaches();
}
}
}
8. 面试题精选
问题1:什么是 Spring IoC 容器?
问题2:BeanFactory 与FactoryBean?
- BeanFactory 是IoC 底层容器。
- FactoryBean 是创建Bean 的一种方式,帮助实现复杂的初始化逻辑。
问题3:Spring IoC 容器启动时做了哪些准备?
IoC 配置元信息读取和解析、IoC 容器生命周期、Spring 事件发布、国际化等,更多答案将在后续专题章节逐一讨论
每天用心记录一点点。内容也许不重要,但习惯很重要!