Spring容器与依赖注入
1、首先我们要先了解下容器实例化概念
先会通过某种途径加载Configuration MetaData。
在大部分情况下,容器需要依赖BeanDefinitionReader,对加载的Configuration MetaData进行
解析和分析,并将分析后的信息编组为相应的BeanDefinition,最后把这些保存了bean定义必须要信息的BeanDefinition,注册到相应的
BeanDefinitionRegistry。这样容器启动工作就完成了。(总体来说,该阶段所做的工作可以认为是准备性的,重点更加侧重于对象管理信息的收集)
2、Bean依赖关系的定义
我们需要为Spring容器提供所有bean的定义以及bean之间的依赖关系,从而进行bean的依赖注入通常有两种方式, XML配置 或者 注解 ,不管是那种最终都会解析成BeanDefinition。然后就可以由容器来创建bean以及依赖注入了,具体依赖注入的时候对于配置文件和注解的处理手段还不同。
3、什么时候会触发依赖注入
- Spring 容器启动初始化的时候(所有单例非懒加载的bean)
- 懒加载(lazy-init)的bean 第一次进行getBean的时候
1.Spring 容器启动初始化的时候
1
2ApplicationContext context = new ClassPathXmlApplicationContext("spring-beans.xml");
1
2
3
4
5
6
7
8
9public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent)throws BeansException { super(parent); setConfigLocations(configLocations); if (refresh) { // 容器初始化入口 refresh(); } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19public void refresh() throws BeansException, IllegalStateException { synchronized (this.startupShutdownMonitor) { prepareRefresh(); // Prepare the bean factory for use in this context. prepareBeanFactory(beanFactory); // Allows post-processing of the bean factory in context subclasses. postProcessBeanFactory(beanFactory); // Invoke factory processors registered as beans in the context. invokeBeanFactoryPostProcessors(beanFactory); // Register bean processors that intercept bean creation. registerBeanPostProcessors(beanFactory); // Instantiate all remaining (non-lazy-init) singletons. // 初始化所有非 懒加载的bean!!!! finishBeanFactoryInitialization(beanFactory); // Last step: publish corresponding event. finishRefresh(); } }
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
29
30
31
32
33
34
35
36finishBeanFactoryInitialization(beanFactory);// 初始化所有非 懒加载的bean!!! protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) { // Stop using the temporary ClassLoader for type matching. beanFactory.setTempClassLoader(null); // 此处省略多行与本次无关代码 // Instantiate all remaining (non-lazy-init) singletons. beanFactory.preInstantiateSingletons(); } public void preInstantiateSingletons() throws BeansException { // 所有beanDefinition集合 List<String> beanNames = new ArrayList<String>(this.beanDefinitionNames); // 触发所有非懒加载单例bean的初始化 for (String beanName : beanNames) { RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName); // 判断是否是懒加载单例bean,如果是单例的并且不是懒加载的则在Spring 容器 if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) { // 判断是否是FactoryBean if (isFactoryBean(beanName)) { // 对FactoryBean的处理 }else { // 如果是普通bean则进行初始化依赖注入,此 getBean(beanName)接下来触发的逻辑跟 // context.getBean("beanName") 所触发的逻辑是一样的 getBean(beanName); } } } } @Override public Object getBean(String name) throws BeansException { return doGetBean(name, null, null, false); }
懒加载(lazy-init)的bean 第一次进行getBean
懒加载的bean 第一次进行getBean的操作调用的也是同一个方法
1
2
3
4
5@Override public Object getBean(String name) throws BeansException { return doGetBean(name, null, null, false); }
解析Spring 依赖注入源码部分
- 依赖注入实现的入口
- 注解形式注入的源码
- xml 配置形式注入的源码
1. 依赖注入实现的入口
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) { //第一步 创建bean实例 还未进行属性填充和各种特性的初始化 BeanWrapper instanceWrapper = null; if (instanceWrapper == null) { instanceWrapper = createBeanInstance(beanName, mbd, args); } final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null); Class<?> beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null); Object exposedObject = bean; try { // 第二步 进行依赖注入(注入属性) populateBean(beanName, mbd, instanceWrapper); if (exposedObject != null) { // 第三步 执行bean的初始化方法 exposedObject = initializeBean(beanName, exposedObject, mbd); } }catch (Throwable ex) { // 抛相应的异常 } return exposedObject; }
我们这里需要关注的是第二步关于依赖注入这一块,下面这行代码
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
29
30
31
32
33
34populateBean(beanName, mbd, instanceWrapper); protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) { // 所有的属性 PropertyValues pvs = mbd.getPropertyValues(); // 这里是处理自动装配类型的, autowire=byName 或者byType。如果不配置不走这个分支,xml或注解都可配 if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME || mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) { pvs = newPvs; } // 后处理器是否已经准备好(后处理器会处理已@Autowired 形式来注入的bean, 有一个 // 子类AutowiredAnnotationBeanPostProcessor来处理@Autowired注入的bean) boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors(); // 是否需要依赖检查 boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE); if (hasInstAwareBpps || needsDepCheck) { PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching); if (hasInstAwareBpps) { for (BeanPostProcessor bp : getBeanPostProcessors()) { if (bp instanceof InstantiationAwareBeanPostProcessor) { InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor)bp; // 这里会处理对注解形式的注入 重点!!!! pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName); if (pvs == null) { return; } } } } } // 注入参数的方法(注解的Bean的依赖注入除外) applyPropertyValues(beanName, mbd, bw, pvs); }
注解形式注入的源码
1
2
3
4
5
6
7
8
9
10
11
12
13@Override public PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException { // 这里定义了把谁注入到哪里 InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs); try { // 进行注入 metadata.inject(bean, beanName, pvs); }catch (Throwable ex) { throw new BeanCreationException(beanName, "Injection of autowired dependencies failed", ex); } return pvs; }
InjectionMetadata在这个类里头封装了依赖的bean与被依赖的bean的信息,比如orderCcontroller 依赖orderService,需要把orderService 注入到orderController。
然后调用inject,使用反射机制,进行依赖注入
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19protected void inject(Object target, String requestingBeanName, PropertyValues pvs) throws Throwable { if (this.isField) { Field field = (Field) this.member; ReflectionUtils.makeAccessible(field); field.set(target, getResourceToInject(target, requestingBeanName)); }else { if (checkPropertySkipping(pvs)) { return; } try { Method method = (Method) this.member; ReflectionUtils.makeAccessible(method); method.invoke(target, getResourceToInject(target, requestingBeanName)); }catch (InvocationTargetException ex) { throw ex.getTargetException(); } } }
xml 配置形式注入的源码
applyPropertyValues(beanName, mbd, bw, pvs);
这个步骤主要做的就是把属性转 换成 相对应的类的属性类型,并最后注入到依赖的bean里头,由一下步骤组成:
判断是否已转换
进行转换
注入到bean
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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) { MutablePropertyValues mpvs = null; List<PropertyValue> original; if (pvs instanceof MutablePropertyValues) { mpvs = (MutablePropertyValues) pvs; // 判断是否已转换,已经转换了则return if (mpvs.isConverted()) { // Shortcut: use the pre-converted values as-is. bw.setPropertyValues(mpvs); return; } original = mpvs.getPropertyValueList(); } TypeConverter converter = getCustomTypeConverter(); BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter); // Create a deep copy, resolving any references for values. List<PropertyValue> deepCopy = new ArrayList<PropertyValue>(original.size()); boolean resolveNecessary = false; for (PropertyValue pv : original) { if (pv.isConverted()) { deepCopy.add(pv); } else { // 属性名 如(name,orderService) String propertyName = pv.getName(); // 未转换前的值,稍后贴出debug时的图 Object originalValue = pv.getValue(); // 转换后的值,进行转换处理(重要!!!!) Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue); Object convertedValue = resolvedValue; // if (resolvedValue == originalValue) { if (convertible) { pv.setConvertedValue(convertedValue); } deepCopy.add(pv); } else if (convertible && originalValue instanceof TypedStringValue && !((TypedStringValue) originalValue).isDynamic() && !(convertedValue instanceof Collection || ObjectUtils.isArray(convertedValue))) { pv.setConvertedValue(convertedValue); deepCopy.add(pv); } else { resolveNecessary = true; deepCopy.add(new PropertyValue(pv, convertedValue)); } } } // 转换完成 if (mpvs != null && !resolveNecessary) { mpvs.setConverted(); } // 这里就是进行属性注入的地方,跟上面的inject方法类似 try { bw.setPropertyValues(new MutablePropertyValues(deepCopy)); } catch (BeansException ex) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Error setting property values", ex); } }
1.进行转换操作,生成最终需要注入的类型的对象
这个方法会返回一个我们最终要注入的一个属性对应类的一个对象
1
2Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);
根据参数类型做具体的转换处理,参数类型包括 1.Bean 2.Array 3.List 4.Set 5.Map 6.String 等等。
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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53public Object resolveValueIfNecessary(Object argName, Object value) { // Bean 类型 if (value instanceof RuntimeBeanReference) { RuntimeBeanReference ref = (RuntimeBeanReference) value; return resolveReference(argName, ref); } else if (value instanceof ManagedArray) { // 处理数组 return resolveManagedArray(argName, (List<?>) value, elementType); } else if (value instanceof ManagedList) { // 处理list return resolveManagedList(argName, (List<?>) value); } else if (value instanceof ManagedSet) { // 处理set return resolveManagedSet(argName, (Set<?>) value); } else if (value instanceof ManagedMap) { // 处理map return resolveManagedMap(argName, (Map<?, ?>) value); } else if (value instanceof TypedStringValue) { // 处理字符串 } else { return evaluate(value); } } private Object resolveReference(Object argName, RuntimeBeanReference ref) { try { String refName = ref.getBeanName(); refName = String.valueOf(doEvaluate(refName)); if (ref.isToParent()) { if (this.beanFactory.getParentBeanFactory() == null) { throw new BeanCreationException(""); } return this.beanFactory.getParentBeanFactory().getBean(refName); }else { Object bean = this.beanFactory.getBean(refName); this.beanFactory.registerDependentBean(refName, this.beanName); return bean; } }catch (BeansException ex) {throw new BeanCreationException(this.beanDefinition.getResourceDescription(), this.beanName, "Cannot resolve reference to bean '" + ref.getBeanName() + "' while setting " + argName,ex); } } Object bean = this.beanFactory.getBean(refName); this.beanFactory.getParentBeanFactory().getBean(refName);
从sprig ioc 容器的双亲中获取bean(被依赖的bean),假如orderCcontroller依赖orderService,则从容器中获取orderService。这里有个关键点,也就是这个获取bean的过程也是一个依赖注入的过程,换句话说依赖注入是个递归的过程!!!知道被依赖的bean不依赖任何bean。
orderCcontroller 依赖 orderService 的操作会触发 orderService 依赖 orderDao的操作
进行注入操作
这一步是通过Java的反射机制根据set 方法把属性注入到bean里。
bw.setPropertyValues(new MutablePropertyValues(deepCopy));
protected void setPropertyValue(AbstractNestablePropertyAccessor.PropertyTokenHolder tokens, PropertyValue pv) throws BeansException {
String propertyName = tokens.canonicalName;
String actualName = tokens.actualName;
if (tokens.keys != null) {
// 处理集合类型
}
else {
// 对非集合类型的处理
AbstractNestablePropertyAccessor.PropertyHandler ph = getLocalPropertyHandler(actualName);
Object oldValue = null;
try {
Object originalValue = pv.getValue();
Object valueToApply = originalValue;
if (!Boolean.FALSE.equals(pv.conversionNecessary)) {
if (pv.isConverted()) {
valueToApply = pv.getConvertedValue();
}else {
if (isExtractOldValueForEditor() && ph.isReadable()) {
try {
oldValue = ph.getValue();
}catch (Exception ex) {}
}
valueToApply = convertForProperty(propertyName, oldValue, originalValue, ph.toTypeDescriptor());
}
pv.getOriginalPropertyValue().conversionNecessary = (valueToApply != originalValue);
}
// 通过反射注入
ph.setValue(object, valueToApply);
}
}
}
public void setValue(final Object object, Object valueToApply) throws Exception {
final Method writeMethod = this.pd.getWriteMethod();
if (!Modifier.isPublic(writeMethod.getDeclaringClass().getModifiers()) && !writeMethod.isAccessible()) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged(new PrivilegedAction() {
@Override
public Object run() {
writeMethod.setAccessible(true);
return null;
}
});
} else {
writeMethod.setAccessible(true);
}
}
final Object value = valueToApply;
if (System.getSecurityManager() != null) {
} else {
// 通过反射 用set 方法注入属性
writeMethod.invoke(getWrappedInstance(), value);
}
}
最后
以上就是悦耳手套最近收集整理的关于Spring 源码分析之 bean 依赖注入原理(注入属性)Spring容器与依赖注入的全部内容,更多相关Spring内容请搜索靠谱客的其他文章。
发表评论 取消回复