ioc
一个理论思想。
概念:指导开发人员在容器中,代码之外管理对象,给属性赋值,管理依赖
ioc技术实现使用的是di(依赖注入) 开发人员在项目中,只需要提供对象的名称,对象的查找、赋值都由容器内部自己实现
Spring使用的是di的技术,底层使用的是反射机制
di
依赖注入,表示创建对象,给属性赋值
di的实现语法有两种:
1、在Spring的配置文件中,使用标签和属性完成,叫做基于xml的di实现
2、使用Spring的注解,完成属性赋值,叫做基于注解的di实现
1、基于xml的di实现
实例对象
public class Student {
private String name;
private int age;
private School school;
}
告诉Spring创建对象 声明bean 告诉Spring要创建某个类的对象 id:对象的自定义名称,唯一值。 Spring 通过这个值来找到对象 class:类的全限定名称(不能是接口,Spring是反射机制创建对象,必须使用类) Spring就完成 SomeService someservice=new SomeServiceImpl(); Spring把创建好的对象放入到map中,spring框架中有一个mao存放对象 Springmap(id的值,对象) 一个bean标签声明一个对象 一个Student对象:
<bean id="student" class="entity.Student">
<property name="name" value="xianji">
<property name="age" value="xianji">
</bean>
1、set注入(设置注入):Spring调用类的set方法,在set方法中实现属性赋值
1)简单类型的set注入
(必须有set方法 没有set方法报错 set方法中必须有赋值语句
Spring只是执行set方法 set方法内部是什么代码 Spring并不关心)
Spring先执行类对象的无参构造方法 创建对象 然后执行set方法
Spring只关心set方法 并不关心是否有相关的字段
Spring可以给任意类赋值 只要他存在set方法
<bean id="" class="">
<property name="属性名字" value="属性的值">
一个property只能给一个属性赋值
<property>......
</bean>
<property> 只能给简单类型赋值,不能用来给引用类型赋值</property>
创建带有引用类型的student对象
<bean id="myStudent" class="ba.Student">
<property name="name" value="李献计"></property>
<property name="age" value="20"></property>
引用类型赋值 先创建引用类型 ref是引用类型的id值;
<property name="school" ref="mySchool"></property>
</bean>-->
2)引用类型的set注入 Spring调用类的set方法
<bean id="" class="">
<property name="属性名字" ref="bean的id(对象名称)">
</bean>
总结:
对象的创建使用<bean></bean>
在其中使用<property>标签进行赋值,spring框架调用对象的set方法进行赋值
对于简单类型的数值使用value 对于引用类型的对象使用ref
2、构造注入:Spring调用类的有参数构造方法,在创建对象的同时,在构造方法中给属性赋值
构造注入使用<constructor-arg>
<constructor-arg>标签一个 <constructor-arg>表示构造方法一个参数
<constructor-arg>标签属性:
name:表示构造方法的形参名
index:表示构造方法的参数的位置 参数从左到右是0,1,2的顺序
value:构造方法的形参类型是简单类型的
ref:构造方法的形参类型是引用类型的
<bean id="myStudent" class="ba.Student">-->
<constructor-arg name="name" value="李献计"></constructor-arg>
<constructor-arg name="age" value="20"></constructor-arg>
<constructor-arg name="school" ref="mySchool"></constructor-arg>
</bean>-->
使用index赋值
<bean id="myStudent1" class="ba.Student">
<constructor-arg index="0" value="李献计"></constructor-arg>
<constructor-arg index="1" value="20"></constructor-arg>
<constructor-arg index="2" ref="mySchool"></constructor-arg>
</bean>
省略index
<bean id="myStudent2" class="ba.Student">
<constructor-arg value="李献计"></constructor-arg>
<constructor-arg value="20"></constructor-arg>
<constructor-arg ref="mySchool"></constructor-arg>
</bean>
使用引用类型的自动注入spring框架根据某种规则可以给引用类型赋值
使用规则ByName ByType
1、ByName(按名称注入):
java类中引用类型的属性名和Spring 容器中(配置文件中)<bean>的id名称一样且数据类型是一致的,这样的容器中的bean,spring可以赋值给引用类型
语法:
<bean id="xx" class="yyy" autowire="ByName">
简单类型赋值
</bean>
<bean id="student" class="ba.Student" autowire="byName">
<property name="name" value="mnnu"></property>
<property name="age" value="23"></property>
</bean>
<bean id="school" class="ba.University">
<property name="name" value="mnnu"></property>
<property name="address" value="漳州"></property>
</bean>
引用类型的ID值必须和对象属性中的引用类型字段一致
2、ByType(按类型注入) java类中引用类型的类型和Spring 容器中(配置文件中)<bean>的class属性是同源关系
这样的容器中的bean,spring可以赋值给引用类型
同源:
1、Java类中引用类型的数据类型和bean的class值是一样的
2、Java类中引用类型的数据类型和bean的class值是父子关系的
3、Java类中引用类型的数据类型和bean的class值接口和实现类关系的
语法:
<bean id="xx" class="yyy" autowire="ByType">
简单类型赋值
</bean>
在Bytype中,在xml配置文件中只能有一个符合条件的引用类型,多余的是错误的
<bean id="myStudent3" class="ba.Student" autowire="byType">
<constructor-arg value="李献计"></constructor-arg>
<constructor-arg value="20"></constructor-arg>
</bean>
<bean id="Myschool" class="ba.University">
<property name="name" value="mnnu"></property>
<property name="address" value="漳州"></property>
</bean>
使用注解创建对象:
注解使用: 通过Spring的注解完成java对象的创建,赋值。代替XML文件
学习的注解:
@Component 创建普通对象
//使用value属性指定对象名称 value可以省略
@Component("myStudent")
//不指定对象名称,由Spring提供默认的名称,类名的首字母小写
public class Student {
@Respotory 创建dao对象,用来访问数据库
@Service 创建Service对象,用来处理业务逻辑,可以有事务功能
@Controller 创建控制器对象,接受请求,显示处理结果
@Value 简单类型的属性赋值
/**
* @Value简单类型的属性赋值
* 属性:value是String类型的,表示简单类型的属性值
* 位置:1、在属性定义的方法,无需set方法 推荐使用
* 2、在set方法上面
*/
@Value("李献计")
private String name;
@Autowired spring框架中引用类型赋值,支持byName和bytype,默认是byType
/**
* 引用类型赋值
* @Autowired Spring框架提供的注解,实现引用类型的赋值
* 属性:required,是一个boolean类型的 默认是true
* required=true 表示引用类型赋值失败 程序报错,并终止运行 推荐
* required=false 引用类型如果赋值失败 程序正常运行,引用类型赋值为null
* spring中提供注解给引用类型赋值,使用的是自动注入原理
* 支持ByName,ByTyoe 默认使用Bytype
* 位置:属性定义的上面,无需set方法 推荐
* set方法上面
*
* 如果使用Byname方式,需要做的是:
* 1、在属性上加上@Autowired
* 2、在属性上加上@Qualifier(value="bean的id"):表示使用指定名称的bean完成赋值
*/
@Resource Jdk中的注解 自动注入给引用类型赋值。支持byName和bytype,默认是byName
/**
* @Resource:来自Jdk中的注解,Spring框架提供了对这个注解的功能支持
* 可以使用它来给引用对象赋值
* 使用的也是自动注入原理,支持ByName,ByTyoe 默认使用Byname
* 位置:
* 1、属性定义的上面,无需set方法 推荐
* 2、在set方法上面
*
*/
// @Autowired(required = false)
// @Qualifier("school-1")
//默认是ByName:先使用ByName自动注入,如果ByName失败,在使用ByType
//@Resource 只使用byNmae方法,需要增加一个属性 name
//name的值是id(名称)
步骤:
1、加入Spring依赖
2、在类中加入Spring的注解(多个不同功能的注解)
3、在Spring的配置文件中,加入一个组建扫描器的标签,说明注解在你的项目中的位置
<!-- 声明组件扫描器(Component-scan)
base-package:指定注解在你的项目中的包名
工作方式:Spring会扫描遍历base-package指定的包
把包中和子包中的所有类,找到类中的注解,按照注解的功能创造对象,给属性赋值
加入了component-scan 配置文件会加入新的约束文件
-->
<context:component-scan base-package="ba01"></context:component-scan>
<context:component-scan base-package="ba02"></context:component-scan>
4、使用注解创造对象,创建容器ApplicationConText
其他:
经常改的用配置文件
不经常改的用注解
配置文件: 代码和赋值完全分开
注解: 效率高
ioc实现解耦合:
ioc能够实现业务对象的解耦合,例如service和dao对象之间的解耦合