Spring Ioc 依赖查找&注入
Spring Ioc 依赖查找&注入
根据bean 名称进行查找
- 实时查找 beanFactory.getBean(Striing);
- 延时查找 ObjectFactory
根据bean类型进行查找
- 单个bean对象 beanFactory.getBean(Person.class);
- 集合bean对象
根据bean名称+类型查找
根据java注解查找
- 单个bean对象
- 集合bean对象
根据bean名称注入
根据bean类型注入
- 单个bean对象
- 集合bean对象
注入容器内建Bean对象
例如 Environment
bean名称 | bean实例 | 使用场景 |
---|---|---|
Environment | Environment对象 | 外部化配置和profiles |
systemProperties | java.util.properties对象 | java系统属性 |
systemEnvironment | java.util.Map 对象 | 操作系统环境变量 |
messageSource | MessageSource对象 | 国际化文案 |
lifecycleProcessor | lifecycleProcessor对象 | lifecycle bean 处理器 |
applicationEventMulticast | applicationEventMulticast | spriing事件管理器 |
注入非Bean对象 beanFactory
注入类型
- 实时注入
- 延迟注入
BeanFactory 和ApplicationContext 谁才是真正的ioc 容器?
ApplicationContext 除了ioc 容器角色,还有
- 面向切面aop
- 配置元信息 configuration metadata
- 资源管理 resources
- 事件 events
- 国际化i18n
- 注解 annotations
- environment 抽象(environment abstraction)
Spring bean
BeanDefinition 元信息
属性 (Property) | 说明 |
---|---|
Class | bean全类名 |
Name | bean的名称或者Id |
Scope | bean的作用域 (singleton,prototype) |
constructor arguments | bean构造器参数(用于依赖注入) |
properties | bean 属性设置(用于依赖注入) |
autowring mode | 自动绑定模式(byName、byType) |
Lazy initialization mode | 延迟初始化模块(延迟、非延迟) |
initialization method | bean初始化回调方法 |
Destruction method | bean 销毁回调方法 |
BeanDefinition 构建
实例化springbean
- 通过serverLoaderFactoryBean
- 通过AutowireCapableBeanFactory#createBean(java.lang.class,int boolean)
- 通过BeanDefinitionRegistry#registerBeanDefinition(String,BeanDefinition)
初始化SpringBean
- @PostConstruct 标注方法
- 实现InitializingBean 接口的afterPropertiesSet()方法
- 自定义初始化方法
- xml配置
- Java 注解 @Bean(init-method=”init”)
- Java Api AbstractBeanDefinition#setInitMethodName(String);
- xml配置
[^这三种实现顺序为: postContruct —>iinitializing—>自定义方法]:
大家都知道创建一个javaweb项目都需要从web.xml开始配置,那么项目中要使用spring,spring
容器是怎么启动的呢,需要在web.xml中进行配置,
也就是DispatcherServlet 看起,从名字上就能看出来他也是一个servlet,那么他必须有init
(),doGet(),doPost(),destory()方法。我们肯定从init方法开始,发现没有init方法呢?
这个时候看这个DispatcherServlet 类,ctrl+H 查看下类继承的关系,发现他有父类,
frameworkServlet,HttpServletBean,HttpServlet .
发现 HttpServletBean 中有init方法,其中代码如下1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
public final void init() throws ServletException {
if (logger.isDebugEnabled()) {
logger.debug("Initializing servlet '" + getServletName() + "'");
}
// Set bean properties from init parameters.
try {
PropertyValues pvs = new ServletConfigPropertyValues(getServletConfig(), this.requiredProperties);
BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(this);
ResourceLoader resourceLoader = new ServletContextResourceLoader(getServletContext());
bw.registerCustomEditor(Resource.class, new ResourceEditor(resourceLoader, getEnvironment()));
initBeanWrapper(bw);
bw.setPropertyValues(pvs, true);
}
catch (BeansException ex) {
logger.error("Failed to set bean properties on servlet '" + getServletName() + "'", ex);
throw ex;
}
// Let subclasses do whatever initialization they like.
initServletBean(); //注意这里人家写注释了,发现调用初始化Bean的对象了,但是方法是空的,那就是让子类去实现了呗。
if (logger.isDebugEnabled()) {
logger.debug("Servlet '" + getServletName() + "' configured successfully");
}
}