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编程模式,目前很多 ...
随机推荐
- 关于wget安装mysql的过程
鄙人才疏学浅,写此文章是为了帮助我那些刚入门的朋友一点心意 第一步 安装yum源 安装mysql的yum源:wget https://dev.mysql.com/get/mysql80-commun ...
- AcWing 482. 合唱队形
#include<iostream> using namespace std ; ; int f[N],g[N]; int w[N]; int main() { int n; cin> ...
- Selenium(Webdriver)自动化测试常问问题
http://blog.sina.com.cn/s/blog_c189e2590102w3bv.html Selenium(Webdriver)自动化测试常问问题 (1)selenium中如何保证操作 ...
- Jmeter录制https协议不能跳转成功(证书导入)
原文: http://www.cnblogs.com/Lam7/p/7154120.html 录制脚本的时候,比如录制https协议的百度网站 https://www.baidu.com ,所有录制 ...
- WPF 解决无边框产生的相关问题
原文:WPF 解决无边框产生的相关问题 最大化: 在设置WindowStyle="None" AllowsTransparency="True"后,最大化会覆盖 ...
- php设计模式之策略模式实例代码
html <html> <head> <meta charset="UTF-8"> <title>简单计算器</title&g ...
- 关于spring boot集成MQTT
安装 说到mqtt,首先肯定要安装了,安装什么的地址:http://activemq.apache.org/ap...我本地是Windows的环境,所以装的是Windows版本,这里是第一个注意的地方 ...
- eclipse debug启动时tomcat报错
Class.getDeclaredConstructors0(boolean) line: not available [native method] tomcat debug启动突然启动不起来 停 ...
- HTML的列表标签和表格标签
网页的列表和表格 列表的分类 无序列表 有序列表 自定义列表 有序列表 <!--有序列表--><ol> <li>辽宁</li> <li ...
- ansible笔记(6):常用模块之系统模块
1.cron模块 cron命令是计划任务功能,与crontab功能类似. 示例:时间格式--->>>分 时 日 月 星期 10 12 27 * * tar -cvzf log ...