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");
		}
	}
