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编程模式,目前很多 ...
随机推荐
- hadoop搭建HA集群之后不能自动切换namenode
在搭好HA集群之后,想测试一下集群的高可用性,于是先把active的namenode给停掉: hadoop-daemon.sh stop namenode 或者直接kill掉该节点namenode的对 ...
- 【转】Error,java对常量池来说字符串xxx的UTF8表示过长的解决及其理解
做项目,客户端这里自己模拟json数据时,一时没忍住搞得json字符串太长了(idea上大概有600多行吧),这个问题就蹦出来了.老方法直接google.百度然后看到一堆有关String 字符串常量池 ...
- Dimensionality and high dimensional data: definition, examples, curse of..
Dimensionality in statistics refers to how many attributes a dataset has. For example, healthcare da ...
- valign
值 描述 top 对内容进行上对齐. middle 对内容进行居中对齐(默认值). bottom 对内容进行下对齐. baseline 与基线对齐.
- 不能暴露服务给外部环境,因为nginx-ingress-control启动失败
不能暴露服务给外部环境,因为nginx-ingress-control启动失败 待办 rancher 和k8s中的端口冲突,nginx-ingress-control都需要使用80端口 以及443端口 ...
- nuxt导入css样式
全局导入,适用于所有组件 在nuxt.config.js文件引 css:["~样式path"], 如:css:["~assets/css/main.css"], ...
- 题解【POJ3252】Round Numbers
Description The cows, as you know, have no fingers or thumbs and thus are unable to play Scissors, P ...
- testng的prioriy
todo: 同一个class中的priority: 1.不标priority的case和标注priority的case,谁先谁后? 2.标注相同priority的case,谁先谁后?是不是并发? 3. ...
- SpringBoot 各层之间的关系
SpringBoot 各层之间的关系 SpringBoot 分为四层:controller层.service层.dao层.entity层. entity层:和 model 层一样,存放的是实体类,属 ...
- selenium定位方法-iframe元素定位方法
在自动化测试中,如果无法定位到一个元素,那么最大的可能是定位的元素是在iframe框架中,iframe对象代表一个HTML的内联框架,在HTML中,iframe每出现一次,一个iframe对象就会被创 ...