IOC依赖注入(各种类型的传值)

Spring中依赖注入的如何传值

大部分:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	   xsi:schemaLocation="http://www.springframework.org/schema/beans 
	                       http://www.springframework.org/schema/beans/spring-beans-4.1.xsd">
	                    
	              
          <!-- IOC依赖注入如何在容器中传值,下面我们用到的bean中的属性之前也说了这里就不解释,我们直接用 -->
          
          <!-- 基本类型或string -->
          <bean id="student" clss="spring.Student">
          		<property name="id" value="100"></property>
          		<property name="username" value="张三"></property>
          		
          		<!-- 赋空值/赋null-->
          		<property name="telepehone" vlaue=""></property>
          		<property name="telepehone">
          				<null></null>
          		</property>
          		
          		<!-- 引用类型 -->
          		<property name="stuClass" ref="stuClass"></property>
          		
          		<!-- 数组-->
          		<property name="hobbies">
          				<array>
          					<value>打王者</value>
          					<value>打王牌</value>
          					<value>打大哥</value>
          				</array>
          		</property>
          		
          		<!--List集合(基本类型似例如:list<String>):有序允许重复-->
          		<property name="scores">
          				<list>
          					<value>打王者</value>
          					<value>打王牌</value>
          					<value>打大哥</value>
          				</list>
    			</property>
    			<!--List集合(引用类型似例如:list<StuClass>):有序允许重复-->
    			<property name="list">
    				<list>
    					<ref bean="stuClass"></ref>
    				</list>
    			
    			</property>
    			
    			<!-- set集合 :(基本类型例如:set<String>)无序,不允许重复-->
    			<property name="scores">
          				<set>
          					<value>打王者</value>
          					<value>打王牌</value>
          					<value>打大哥</value>
          				</set>
    			</property>
    			<!--set集合 :(引用类型例如:set<StuClass>)无序,不允许重复-->
    			<property name="set">
    				<set>
    					<ref bean="stuClass"></ref>
    				</set>
    			
    			</property>
    			<!-- Map集合 ,会覆盖重复的key-->
    			<property name="map">
    				<map>
    					<entry key="JAVA" value="100"></entry>
    					<entry key="PHP" value="100"></entry>
    					<entry key="PYTHON" value="100"></entry>
    				</map>
    			</property>
    			
    			<!-- Properties类型 -->
    			<property name="properties">
    				<props>
    					<prop key="username">scott</prop>
    					<prop key="password">123456</prop>
    				</props>
    			
    			</property>
          </bean>
          <bean id="stuClass" class="spring.StuClass">
          		<constructor-arg name="id" value="666"></constructor-arg>
          		<constructor-arg name="name" value="Java课程"></constructor-arg>
          </bean>              
</beans>
<think>我们正在讨论IOC(控制反转)的底层实现原理。根据引用内容,IOC的核心是依赖注入(DI),它改变了对象获取依赖的方式——由IOC容器在运行时动态注入,而不是对象自己创建。Spring框架是IOC的典型实现,它通过XML配置或注解来管理对象及其依赖关系。 关键点: 1. **控制反转(IoC)**:将对象的创建和依赖关系的管理从代码内部转移到外部容器(如Spring容器)中。这样,对象不再自己创建依赖对象,而是由容器注入。 2. **依赖注入(DI)**:IoC的实现方式,主要有两种:setter注入(通过set方法)和构造器注入(通过构造方法)。引用[3]和[5]提到了这两种方式。 3. **Spring中的实现**:Spring容器负责管理Bean(即对象)的生命周期和依赖关系。我们可以通过XML配置(如<bean>标签和<property>标签)或注解(如@Component, @Autowired)来实现。 底层原理可以概括为: - **反射机制**:Spring容器在运行时通过反射来创建对象,并注入依赖。例如,通过Class.forName()加载类,然后调用newInstance()创建实例,再通过反射调用setter方法或构造器设置依赖。 - **工厂模式**:Spring使用工厂模式(BeanFactory)来创建和管理Bean。ApplicationContext是其更高级的接口。 - **容器管理**:容器维护一个Bean的定义(BeanDefinition)注册表,根据配置(XML或注解)来实例化Bean,并解决Bean之间的依赖关系(通过反射注入)。 具体步骤(以XML配置为例): 1. 读取配置文件(如applicationContext.xml),解析<bean>标签,将每个Bean的定义(包括类名、属性、依赖关系)注册到BeanDefinition注册表中。 2. 当需要获取一个Bean时,容器会检查该Bean所依赖的其他Bean,并递归创建这些依赖Bean(如果尚未创建)。 3. 创建Bean实例:通过反射调用无参构造器(或指定构造器)创建对象。 4. 依赖注入:通过反射调用setter方法(或构造器)将依赖的Bean注入到目标Bean中。 5. 如果配置了初始化方法(如init-method),则调用它。 6. 容器将创建好的Bean放入缓存(通常是ConcurrentHashMap)中,以便后续使用。 注解方式(如@ComponentScan和@Autowired)的底层原理类似,只是配置方式不同。容器会扫描指定包下的类,识别带有@Component等注解的类,并自动注册为Bean。然后通过@Autowired注解自动注入依赖,同样是通过反射实现。 总结:IOC的底层实现依赖于反射和工厂模式,容器在启动时读取配置信息,然后通过反射机制创建对象并注入依赖,从而实现了对象之间的解耦。</think>### IOC(控制反转)底层实现原理详解 IOC(控制反转)的底层实现原理主要基于**反射机制**、**工厂模式**和**容器管理**,核心是通过**依赖注入(DI)** 反转对象创建与依赖关系的控制权。以下是关键实现原理: --- #### 1. **核心机制:反射(Reflection)** - **动态创建对象**:IOC容器通过反射(如Java的`Class.forName()`和`newInstance()`)动态加载类并实例化对象[^3][^4]。 - **依赖注入实现**:容器扫描类中的字段或方法(如`@Autowired`注解),通过反射将依赖对象注入到目标对象中[^4]。 - *示例*: ```java Class<?> clazz = Class.forName("com.example.UserService"); Object instance = clazz.newInstance(); // 反射创建对象 ``` --- #### 2. **容器与工厂模式** - **BeanFactory**:Spring的核心接口,管理Bean的生命周期(创建、配置、依赖注入)[^3][^4]。 - **容器工作流程**: 1. **加载配置**:解析XML或注解(如`@Component`),生成Bean定义(`BeanDefinition`)[^4]。 2. **实例化Bean**:根据Bean定义,通过反射创建对象。 3. **依赖注入**:递归解析依赖关系,注入其他Bean(通过Setter或构造器)[^3][^5]。 4. **缓存管理**:将初始化后的Bean存入缓存(如`ConcurrentHashMap`),避免重复创建。 --- #### 3. **依赖注入(DI)的实现方式** - **Setter注入**:通过Setter方法注入依赖(XML配置`<property>`或注解`@Autowired`)[^5]。 ```xml <bean id="userService" class="com.example.UserService"> <property name="userDao" ref="userDao"/> <!-- 注入userDao --> </bean> ``` - **构造器注入**:通过构造参数注入依赖(更推荐,避免循环依赖)[^3]。 ```java @Component public class UserService { private final UserDao userDao; @Autowired public UserService(UserDao userDao) { // 构造器注入 this.userDao = userDao; } } ``` --- #### 4. **注解驱动的实现(如Spring)** - **组件扫描**:`@ComponentScan`扫描包路径,识别`@Component`、`@Service`等注解类[^4]。 - **依赖注入**:`@Autowired`自动按类型匹配Bean,并注入字段/方法中。 - **代理模式**:对需增强的Bean(如事务管理`@Transactional`),生成动态代理对象(JDK/CGLib)[^3]。 --- #### 5. **循环依赖的解决** - **三级缓存**(Spring特有机制): 1. **一级缓存**:存放完整初始化的Bean。 2. **二级缓存**:存放半成品Bean(已实例化但未注入依赖)。 3. **三级缓存**:存放Bean的工厂对象(用于生成代理对象)[^3]。 - *流程*:当Bean A依赖Bean B时,容器先创建A的半成品→创建B→B注入A的半成品→B完成→A注入B的完整实例。 --- #### 总结 IOC底层通过**反射动态创建对象**、**容器管理依赖关系**、**工厂模式统一生命周期**,实现控制权的反转。依赖注入(DI)是核心手段,解决了对象间的紧耦合问题,使系统更灵活、可测试[^1][^2][^3]。 --- ### 相关问题 1. **Spring如何解决循环依赖问题?三级缓存的具体作用是什么?** 2. **反射机制在IOC中可能引发哪些性能问题?如何优化?** 3. **除Setter和构造器注入外,还有哪些依赖注入方式?各自适用场景是什么?** 4. **IOC容器与统工厂模式(如SimpleFactory)的核心区别是什么?** 5. **动态代理(JDK/CGLib)在Spring IOC中扮演什么角色?** [^1]: 依赖注入IoC 的核心实现方式。通过 DI,IoC 容器将依赖关系从对象自身转移到容器中管理,从而实现了控制反转。 [^2]: DI(依赖注入)其实就是IOC的另外一种说法,DI是由Martin Fowler 在2004年初的一篇论文中首次提出的。 [^3]: Spring 中依赖注入有两种实现方式:set 方式(方式)和构造器方式(引用方式)。 [^4]: Spring IOC:控制反转与依赖注入。通过注解如`@Component`和`@Autowired`实现组件管理和依赖注入。 [^5]: Spring 的依赖注入在XML中通过`<property>`配置属性
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值