Spring IoC(一)bean实例化和依赖注入
1、IoC容器概述
IoC 全称为 Inversion of Control
,翻译为 “控制反转”,它还有一个别名为 DI(Dependency Injection
),即依赖注入。
所谓 IOC ,就是由 Spring IOC 容器来负责对象的生命周期和对象之间的关系
该org.springframework.context.ApplicationContext
接口代表Spring IoC容器,并负责实例化,配置和组装Bean。
容器通过读取配置元数据来获取有关要实例化,配置和组装哪些对象的指令。
配置元数据以 XML ,Java批注 或 Java代码 表示。
它使您能够表达组成应用程序的对象以及这些对象之间的丰富相互依赖关系。
2、如何理解“控制反转”呢
理解好它的关键在于我们需要回答如下四个问题:
- 谁控制谁:在传统的开发模式下,我们都是采用直接 new 一个对象的方式来创建对象,也就是说你依赖的对象直接由你自己控制,但是有了 IOC 容器后,则直接由 IoC 容器来控制。所以“谁控制谁”,当然是 IoC 容器控制对象。
- 控制什么:控制对象。
- 为何是反转:没有 IoC 的时候我们都是在自己对象中主动去创建被依赖的对象,这是正转。但是有了 IoC 后,所依赖的对象直接由 IoC 容器创建后注入到被注入的对象中,依赖的对象由原来的主动获取变成被动接受,所以是反转。
- 哪些方面反转了:所依赖对象的获取被反转了。
3、bean总览
3.1 命名方式
一共有三种,可以通过id、name还有外部通过<alias name="bean" alias="aliasName">标签命名。
每个bean具有一个或多个标识符。这些标识符在承载Bean的容器内必须唯一。一个bean通常只有一个标识符。
3.2 实例化方式
构造方法实例化;
<!--构造方法实例化-->
<bean id="teacher" class="com.doubleh.pojo.Teacher">
<constructor-arg name="id" value="1"></constructor-arg>
<constructor-arg name="name" value="李白"></constructor-arg>
</bean>
静态工厂方法实例化;
<!--静态工厂方法实例化:构造方法私有化用,例如单例类-->
<!-- public class Teacher{
private static Teacher teacher = new Teacher();
private Teacher() {
}
public static Teacher createInstance() {
return teacher;
}
}
-->
<bean id="teacher" class="com.doubleh.pojo.Teacher" factory-method="createInstance">
</bean>
实例工厂方法实例化(暂未发现用处);
<!--实例工厂方法实例化-->
<!-- public class DefaultServiceLocator {
private static Teacher teacher = new Teacher();
private Teacher() {
}
public Teacher createInstance() {
return teacher;
}
}
-->
<bean id="dsl" class="com.doubleh.pojo.DefaultServiceLocator"> </bean>
<bean id="createInstance" factory-bean="dsl" factory-method="createInstance"></bean>
4、bean依赖注入方式
4.1 构造器注入
顾名思义就是被注入的对象通过在其构造方法中声明依赖对象的参数列表,让外部知道它需要哪些依赖对象。
//老师类
public class Teacher {
private int id;
private String name; public Teacher(int id, String name) {
this.id = id;
this.name = name;
} @Override
public String toString() {
return "Teacher{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
} //学生类
public class Student {
private int id;
private String name;
private Teacher teacher; public Student(int id, String name, Teacher teacher) {
this.id = id;
this.name = name;
this.teacher = teacher;
} @Override
public String toString() {
return "Student{" +
"id=" + id +
", name='" + name + '\'' +
", teacher=" + teacher +
'}';
}
}
<!--配置Teacher类-->
<bean id="teacher" class="com.doubleh.pojo.Teacher">
<constructor-arg index="0" value="1"></constructor-arg>
<constructor-arg index="1" value="屈原"></constructor-arg>
</bean>
<!--配置学生类-->
<bean class="com.doubleh.pojo.Student" id="student" >
<!--构造方法注入:根据参数下标赋值-->
<constructor-arg index="0" value="1"></constructor-arg>
<!--根据参数名赋值:推荐-->
<constructor-arg name="name" value="李白"></constructor-arg>
<!--根据数据类型赋值-->
<constructor-arg type="com.doubleh.pojo.Teacher" ref="teacher"></constructor-arg>
</bean>
构造方法通过<constructor-arg>标签来注入,分别可以通过以下三种方式注入值:
参数下标(index)注入;
参数名(name)注入,推荐这种;
参数类型(name)注入;
4.2 setter注入
对于 JavaBean 对象而言,我们一般都是通过 getter 和 setter 方法来访问和设置对象的属性。所以,当前对象只需要为其所依赖的对象提供相对应的 setter 方法,就可以通过该方法将相应的依赖对象设置到被注入对象中。这种也比较灵活。
setter注入前提是JavaBean对象必须由setter方法,否则会报:
org.springframework.beans.NotWritablePropertyException:
Invalid property 'id' of bean class [com.doubleh.pojo.Student]:
Bean property 'id' is not writable or has an invalid setter method.
Does the parameter type of the setter match the return type of the getter?
setter注入通过<property>标签来注入值;
<bean class="com.doubleh.pojo.Student" id="student" >
<property name="id" value="1"></property>
<property name="name" value="李白"></property>
<property name="teacher" ref="teacher"></property>
</bean>
各种类型值注入方式:
<bean class="com.doubleh.pojo.Student" id="student" >
<!--基础类型-->
<property name="id" value="1"> </property>
<!--bean引用类型-->
<property name="teacher" ref="teacher"></property>
<!--数组类型-->
<property name="strs" >
<array>
<value>李白</value>
<value>杜甫</value>
<value>白居易</value>
</array>
</property>
<!--List类型-->
<property name="list">
<list>
<ref bean="teacher"></ref>
</list>
</property>
<!--Map类型-->
<property name="map">
<map>
<entry value="你好" key="a"></entry>
<entry key="b" value="发顺丰"></entry>
<!--key-ref="" -->
<entry key="c" value="{id = 3,name = 设计费}">
</entry>
</map>
</property>
<!--Set类型-->
<property name="set">
<set>
<value>枪</value>
<value>剑</value>
</set>
</property>
<!--Properties类型-->
<property name="props">
<props>
<prop key="driver">com.mysql.com</prop>
<prop key="url">jdbc:mysql://localhost</prop>
</props>
</property>
<!--NULL类型-->
<property name="t2">
<null />
</property>
</bean>
4.3 p-namespace允许您使用bean
元素的属性(而不是嵌套 <property/>
元素)来描述协作bean的属性值,或同时使用这两者。
<beans></beans>标签中添加配置
xmlns:p="http://www.springframework.org/schema/p"
<!--普通模式-->
<!-- <bean id="people" class="com.doubleh.pojo.People">
<property name="name" value="李白"></property>
</bean>--> <!--P-namespace注入模式-->
<bean id="people" class="com.doubleh.pojo.People" p:name="杜甫">
</bean>
4.4 与具有p-namespace的XML Shortcut相似,在Spring 3.1中引入的c-namespace允许使用内联属性来配置构造函数参数,而不是嵌套constructor-arg
元素。
<beans></beans>标签中添加配置
xmlns:c="http://www.springframework.org/schema/c"
Spring IoC(一)bean实例化和依赖注入的更多相关文章
- 学习Spring IOC控制反转和DI依赖注入总结
30岁的小曹,20岁的身体,还在坚持在能力允许控制范围内22点睡觉,5点起床锻炼身体,好好学习,除了加班或者像今天这样的深夜,再一次写已经有X百万人写过的 spring Ioc 的总结博客. 一.IO ...
- spring源码分析之玩转ioc:bean初始化和依赖注入(一)
最近赶项目,天天加班到十一二点,终于把文档和代码都整完了,接上继续整. 上一篇聊了beanProcess的注册以及对bean的自定义修改和添加,也标志着创建bean的准备工作都做好了,接下来就是开大招 ...
- [Spring]IOC控制反转和DI依赖注入
从之前算起到现在接触Spring也已经有几天了,进度也不是很快,就只弄懂了控制反转和依赖注入那么一点东西.然后敲了两个demo 主要是因为之前没有学过,然后网上资源很多但是都不是面向我们初学者的,大多 ...
- Spring IOC&DI 控制反转和依赖注入
控制反转(Inversion of Control,缩写为IOC),它是把你设计好的对象交给spring控制,而不再需要你去手动 new Object(); 网上对于IOC的解释很多,对程序员而言,大 ...
- Spring源码解析(四)Bean的实例化和依赖注入
我们虽然获得了Bean的描述信息BeanDefinition,但是什么时候才会真正的实例化这些Bean呢.其实一共有两个触发点,但是最后实际上调用的是同一个方法. 第一个:在AbstractAppli ...
- Spring IOC原理补充(循环依赖、Bean作用域等)
文章目录 前言 正文 循环依赖 什么是循环依赖? Spring是如何解决循环依赖的? 作用域实现原理以及如何自定义作用域 作用域实现原理 自定义Scope BeanPostProcessor的执行时机 ...
- Spring源码-IOC部分-Bean实例化过程【5】
实验环境:spring-framework-5.0.2.jdk8.gradle4.3.1 Spring源码-IOC部分-容器简介[1] Spring源码-IOC部分-容器初始化过程[2] Spring ...
- Spring Ioc源码分析系列--自动注入循环依赖的处理
Spring Ioc源码分析系列--自动注入循环依赖的处理 前言 前面的文章Spring Ioc源码分析系列--Bean实例化过程(二)在讲解到Spring创建bean出现循环依赖的时候并没有深入去分 ...
- Spring的三大核心思想:IOC(控制反转),DI(依赖注入),AOP(面向切面编程)
Spring核心思想,IoC与DI详解(如果还不明白,放弃java吧) 1.IoC是什么? IoC(Inversion of Control)控制反转,IoC是一种新的Java编程模式,目前很多 ...
随机推荐
- c#中转义字符\n和\r的区别
在c#中\n代表换行,\r代表回车,但\r是把后面的字符覆盖前面的,例: "1234\n567" 输出的是 1234 567 "1234\r567"输出的是 5 ...
- Paper: A Novel Time Series Forecasting Method Based on Fuzzy Visibility Graph
Problem define a fuzzy visibility graph (undirected weighted graph), then give a new similarity meas ...
- python3练习100题——008
今天第二道,做了明天就可以休息一下- 原题链接:http://www.runoob.com/python/python-exercise-example8.html 题目:输出 9*9 乘法口诀表. ...
- Activiti+Shiro实战
有人曾说:人的差距都在业余时间拉开的……嗯,我现在深刻理解着这句话,作为一个程序员,技术男,就得不断学习新的技术,跟上时代步伐,才会让自己更有价值~~~~以下这个项目是个人利用业余时间学习并实践的~如 ...
- C变量常量
变量是指其值可以变化的量.计算机中,指令代码.数据都存储于内存中.变量也需要存储在内存中.在计算机中,每个变量都被分配了一块内存空间,在这些空间里存储的就是变量的值.变量之所以可以变化,就是这个存储空 ...
- 什么是nuget?nuget包是如何管理
本文链接:https://blog.csdn.net/Microsoft_Mao/article/details/101159800做windows开发的,迟早会接触到nuget这个东西,那么今天我们 ...
- adb+tcpdump手机抓包过程出现的报错及解决方法
tcpdump下载:https://www.androidtcpdump.com/android-tcpdump/downloads 1.夜神模拟器连接不上adb D:1手机木马取证\android- ...
- 题解【POJ3252】Round Numbers
Description The cows, as you know, have no fingers or thumbs and thus are unable to play Scissors, P ...
- python的setup和teardown
关于python unittest ① setup():每个测试函数运行前运行② teardown():每个测试函数运行完后执行③ setUpClass():必须使用@classmethod 装饰器, ...
- selenium的鼠标事件操作
自动化测试过程中,经常会用到鼠标事件,在selenium的action_chains模块的ActionChains定义了鼠标操作的一些事件,要使用ActionChains类中的方法,首先需要对Acti ...