XML配置下Spring Bean的注入

主题

之前学习了@Autowired下SpringBean是怎么注入到属性中的.

https://www.cnblogs.com/abcwt112/p/12541783.html

现在学习下远古时代的XML是怎么注入的.

Ac初始化

入口是XML的AC.

new的时候回做refresh方法

refresh之前的文章分享过大致做了什么

https://www.cnblogs.com/abcwt112/p/12388982.html

其中这一步会去掉BeanFactory的getBean方法去初始化配置的bean.

属性注入

BF的getBean里面有无数逻辑.其中注入属性的是这一段

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#populateBean

 1 /**
 2      * Populate the bean instance in the given BeanWrapper with the property values
 3      * from the bean definition.
 4      * @param beanName the name of the bean
 5      * @param mbd the bean definition for the bean
 6      * @param bw the BeanWrapper with bean instance
 7      */
 8     @SuppressWarnings("deprecation")  // for postProcessPropertyValues
 9     protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
10         if (bw == null) {
11             if (mbd.hasPropertyValues()) {
12                 throw new BeanCreationException(
13                         mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
14             }
15             else {
16                 // Skip property population phase for null instance.
17                 return;
18             }
19         }
20
21         // Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
22         // state of the bean before properties are set. This can be used, for example,
23         // to support styles of field injection.
24         boolean continueWithPropertyPopulation = true;
25
26         if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
27             for (BeanPostProcessor bp : getBeanPostProcessors()) {
28                 if (bp instanceof InstantiationAwareBeanPostProcessor) {
29                     InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
30                     if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
31                         continueWithPropertyPopulation = false;
32                         break;
33                     }
34                 }
35             }
36         }
37
38         if (!continueWithPropertyPopulation) {
39             return;
40         }
41
42         PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
43
44         int resolvedAutowireMode = mbd.getResolvedAutowireMode();
45         if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
46             MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
47             // Add property values based on autowire by name if applicable.
48             if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
49                 autowireByName(beanName, mbd, bw, newPvs);
50             }
51             // Add property values based on autowire by type if applicable.
52             if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
53                 autowireByType(beanName, mbd, bw, newPvs);
54             }
55             pvs = newPvs;
56         }
57
58         boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
59         boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);
60
61         PropertyDescriptor[] filteredPds = null;
62         if (hasInstAwareBpps) {
63             if (pvs == null) {
64                 pvs = mbd.getPropertyValues();
65             }
66             for (BeanPostProcessor bp : getBeanPostProcessors()) {
67                 if (bp instanceof InstantiationAwareBeanPostProcessor) {
68                     InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
69                     PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
70                     if (pvsToUse == null) {
71                         if (filteredPds == null) {
72                             filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
73                         }
74                         pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
75                         if (pvsToUse == null) {
76                             return;
77                         }
78                     }
79                     pvs = pvsToUse;
80                 }
81             }
82         }
83         if (needsDepCheck) {
84             if (filteredPds == null) {
85                 filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
86             }
87             checkDependencies(beanName, mbd, filteredPds, pvs);
88         }
89
90         if (pvs != null) {
91             applyPropertyValues(beanName, mbd, bw, pvs);
92         }
93     }

如果XML里bean是这样配置的:

其中最后91行的 applyPropertyValues(beanName, mbd, bw, pvs);

就是把对象中的属性(pvs)转化成对象,设置到bw(BeanWrapper.封装了原始对象)中去.

比如beanName是a.     pvs是a对象里的属性集,其中包含b

具体逻辑是调用Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue); 来获取要注入的属性对应的bean.

最终也是通过BF.getBean去取Bean.再set到beanwrapper上去.

XML配置中还有一种情况是使用默认的自动配置

这个时候bean的属性是不需要配置的.spring会自动根据类型(byType)或者名称(byName)去匹配.

原理是在org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#populateBean中

 1         int resolvedAutowireMode = mbd.getResolvedAutowireMode();
 2         if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
 3             MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
 4             // Add property values based on autowire by name if applicable.
 5             if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
 6                 autowireByName(beanName, mbd, bw, newPvs);
 7             }
 8             // Add property values based on autowire by type if applicable.
 9             if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
10                 autowireByType(beanName, mbd, bw, newPvs);
11             }
12             pvs = newPvs;
13         }

resolvedAutowireMode默认情况下是0.是不会自动装配的.如果配置了就会进对应的autowiredByXXX方法.会找出missing property values然后设置到MutablePropertyValues中.所以最后掉applyPropertyValues方法的时候还是会填充这些属性.

原文地址:https://www.cnblogs.com/abcwt112/p/12557232.html

时间: 2024-11-07 04:03:49

XML配置下Spring Bean的注入的相关文章

基于XML配置的Spring MVC

1.添加jar 2.web.xml配置 <?xml version="1.0" encoding="UTF-8"?> <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation

【小家Spring】老项目迁移问题:@ImportResource导入的xml配置里的Bean能够使用@PropertySource导入的属性值吗?

#### 每篇一句 > 大师都是偏执的,偏执才能产生力量,妥协是没有力量的.你对全世界妥协了你就是空气.所以若没有偏见,哪来的大师呢 #### 相关阅读 [[小家Spring]详解PropertyPlaceholderConfigurer.PropertyOverrideConfigurer等对属性配置文件Properties的加载和使用](https://blog.csdn.net/f641385712/article/details/91444601) [[小家Spring]Spring中@

使用 Java 配置进行 Spring bean 管理--转

概述 众所周知,Spring 框架是控制反转 (IOC) 或依赖性注入 (DI) 模式的推动因素,而这种推动是通过基于容器的配置实现的.过去,Spring 允许开发人员使用基于 XML 的配置,通过利用应用程序上下文 XML 文件来管理 bean 依赖性.此文件处于应用程序的外部,包含 bean 及其与该应用程序的依赖项的定义.尽管使用 XML 配置较为简单和便捷,但仍有另外一种方法可定义 bean 及其依赖项.这种方法也称为基于 Java 的配置.不同于 XML,基于 Java 的配置使您能够

Spring bean依赖注入、bean的装配及相关注解

依赖注入 Spring主要提供以下两种方法用于依赖注入 基于属性Setter方法注入 基于构造方法注入 Setter方法注入 例子: public class Communication { private Messaging messaging; /* * DI via Setter */ public void setMessaging(Messaging messaging){ this.messaging = messaging; } public void communicate(){

基于注解的Spring MVC(所需jar包,web.xml配置,Spring文件配置,@Controller,@RequestMapping,@RequestParam,model填參,EL取值)

1.加入jar 2.web.xml配置: <?xml version="1.0" encoding="UTF-8"? > <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocati

XML 配置里的 Bean 自动装配

在XML文件中,先看一下下面的代码: <bean id="student" class="com.jeremy.spring.beans.student"> <property name="s_name" value="jeremy"></property> <property name="age" value="20"></prop

spring 使用XML配置开发Spring AOP

XML方式开发AOP与注解开发原理是相同的,所以这里主要介绍一些用法即可.这里需要在XML中引入AOP的命名空间,所以先来了解一下AOP可配置的元素 代码清单:切面类 package com.ssm.chapter11.xml.aspect; public class XmlAspect { public void before() { System.out.println("before ......"); } public void after() { System.out.pri

配置 cxf-rs spring bean 文件

http://cxf.apache.org/schemas/jaxrs.xsd http://cxf.apache.org/docs/restful-services.html 示例: <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://ww

XML配置里的Bean自动装配与Bean之间的关系

需要在<bean>的autowire属性里指定自动装配的模式 byType(根据类型自动装配) byName(根据名称自动装配) constructor(通过构造器自动装配) 名字须与属性名一致 byName根据Bean的名字和当前bean的setter风格的属性名进行自动装配,若有匹配的,则进行自动装配,没有则不装配 byType  根据bean的类型和当前bean的属性的类型进行自动装配 缺点:有一个以上的类型匹配的bean则抛异常 自动装配的缺点 不够灵活,不能两者兼而言之 Bean之间