spring_ioc:
一.spring:
- spring是一个容器,把项目中用的对象放入到容器中,让容器完成对象的创建和对象之间关系的管理(属性赋值),我们在程序中从容器中获取要使用的对象
- spring的优点:
* 轻量
* 针对接口编程,解耦合(ioc能够实现业务对象之间的解耦合,例如service和dao对象之间的解耦合)
* AOP编程的支持
* 方便集成各种优秀框架 - Spring容器将什么样的对象放入进去了:
* dao类,service类,controller类,工具类 - 不放进容器的:
* 实体类对象,实体类数据来自数据库的
* servlet,listener,filter等
2.框架怎么学:
- 框架是一个软件,其他人写好的软件
- 知道框架能做什么,mybatis–访问数据库,对表中的数据执行CRUD
- 框架的语法,框架要完成一个功能,需要一定的步骤支持的
- 框架的内部实现,框架内部怎么做,原理是什么
- 通过学习,可以实现一个框架
- spring的核心功能: ioc
3.IoC控制反转:
- 控制反转,是一个概念,是一种思想,指导开发人员在容器中,管理对象,给对象赋值,管理依赖
- 控制:创建对象,对象的属性赋值,对象之间的关系管理
- 反转:由容器代替开发人员管理对象,创建对象,给属性赋值
- 正转:使用new构造方法创建对象,开发人员主动管理对象
public static void main(String[] args){
Student student = new Student();//在代码中,创建对象----正转
}
- 容器:是一个服务器软件,一个框架(Spring)
- Ioc目的就是减少对代码的改动,能实现不同的功能,实现解耦合
- java中创建对象有哪些方式:
1.构造方法,new Student(); 2.反射
3.序列化 4.克隆
5.ioc:容器创建对象 6.动态代理
4.IoC的技术实现:
- DI是ioc的技术实现
- DI(Dependency Injection):依赖注入,只需要在程序中提供要使用的对象名称就可以,至于对象如何在容器中创建,赋值,查找都由容器内部实现,创建对象使用的是反射机制
- spring是使用的DI实现了ioc的功能,spring底层创建对象,使用的是反射机制
- spring是一个容器,管理对象,给属性赋值,底层是反射创建对象
5.spring的配置文件(在resources类目录下):
- beans:是根标签,spring把java对象称为bean
- 配置文件:(配置文件一般的文件名叫applicationContext.xml)
- bean:
- 声明bean,就是创建类的对象
- 属性:
- id:对象的自定义名称,唯一值,spring通过这个名称找到对象
- class:类的全限定名称(不能是接口,因为spring是反射机制创建对象,必须使用类)
- spring框架有一个map存放对象的,spring把创建好的"对象"放入到map中:
- springMap.put(id,对象);
- 例如:springMap.put(“someService”,new SomeServiceImpl());
- 声明bean,使用bean中对象用接口ApplicationContext的子类ClassPathXmlApplicationContext(String config);
- ClassPathXmlApplicationContext(String config):表示从类路径(target/classes)中加载spring的配置文件
- ApplicationContext的方法:
- Object getBean(String object):返回一个bean对象
- int getBeanDefinitionCount():获取容器中定义的对象的数量
- String[ ] getBeanDefinitionNames():以数组方式获取容器中每对象的名称(id)
- ClassPathXmlApplicationContext:是spring默认创建对象的时机,会创建容器中所有的对象无参数构造方法,如果在使用对象时,未找到对象,会在一次进行扫描
6.给属性赋值:
- di的实现有两种:
- 在spring的配置文件中,使用标签和属性完成,叫做基于XML的di实现
- 使用spring中的注解,完成属性赋值,叫做基于注解的di实现
- di的语法分类:
- set注入(设置注入):spring调用类的set方法,在set方法可以实现属性的赋值
- 构造注入,spring调用类的有参数构造方法,创建对象,在构造方法中完成赋值
- 注入:就是赋值的意思
- 简单类型:spring中规定java的基本数据类型和String,Integer等都是简单类型
- 所有值必须放入到" "中,这是xml的规则
- 第一种方式set注入(设置注入):
- spring调用类的set方法
- 简单类型的set注入:
- < property >属性标签:
- name:属性名字(去除set的名字)
- value:字面值
- ref:Bean的id
< bean id="xx" class="xx" >
< property name="属性名字" value="此属性的值"/ >
一个property只能给一个属性赋值
< property.... >
< /bean >
4.引用类型的set注入:
< bean id="xx" class="xx">
< property name="属性名字" ref="Bean的id"/ >
< /bean >
- 第二种方式构造注入:
- spring调用类有参数构造方法,在创建对象的同时,在构造方法中给属性赋值
- 构造注入使用< constructor-arg >标签:
- < constructor-arg>标签:一个< constructor-arg >表示构造方法一个参数
- < constructor-arg >标签属性:
- name:表示构造方法的形参名
- index:表示构造方法的参数的位置,参数从左往右位置是0,1,2的顺序
- value:构造方法的形参类型是简单类型,使用value
- ref:构造方法的形参类型是引用类型的,使用ref
< bean id="myStudent_One" class="com.hj.ba01.Student" >
< constructor-arg name="name" value="ww"/ >
< constructor-arg name="age" value="23"/ >
< constructor-arg name="school" ref="mySchool"/ >
< /bean >
- index属性:表示构造方法形参的位置,从0开始:
< bean id="myStudent_Two" class="com.hj.ba01.Student" >
< constructor-arg index="0" value="qq"/ >
< constructor-arg index="1" value="23"/ >
< constructor-arg index="2" ref="mySchool"/ >
< /bean >
- 省略index,按照参数顺序传递:
< bean id="myStudent_Three" class="com.hj.ba01.Student" >
< constructor-arg value="qq"/ >
< constructor-arg value="23"/ >
< constructor-arg ref="mySchool"/ >
< /bean >
7.引用类型的自动注入:
- spring框架根据某些规则可以给"引用类型"赋值,使用规则常用的的是byName,byType
- byName(按名称注入):
1.java类中引用类型的"属性名"和bean的id名称一样且数据类型一致的,这样bean的id就自动赋值给类的"引用类型",语法:
< bean id="xx" class="yy" autowire="byName" >
//简单类型属性赋值
< /bean >
-
byType(按类型注入):
- java类中引用类型的"数据类型"和bean的class属性是同源关系的,这样的bean能够赋值给引用类型
- 同源就是一类的意思:
- java类中引用类型的数据类型与bean的class的数据类型一致,是父子类关系,或是接口和实现类关系的,语法:
< bean id=“xx” class=“yy” autowire=“byType” >
//简单类型属性赋值
< /bean >
- java类中引用类型的数据类型与bean的class的数据类型一致,是父子类关系,或是接口和实现类关系的,语法:
- 在byType中,在xml配置文件中声明bean只能有一个符合条件的,多余一个事错误的
8.多个配置优势:
- 每个文件的大小比一个文件要小很多,效率高
- 避免多人竞争带来的冲突
- 多文件的分配方式:
- 按功能模块,一个模块一个配置文件
- 按类的功能,数据库相关的配置一个配置文件,做事务的功能一个配置文件,做service功能的一个配置文件等
- 包含关系配置文件:
- 整合表示主配置文件:包含其他的配置文件的,主配置文件一般不是定义对象的:
- 语法:
- 关键字:"classpath:"表示类路径(class文件所在的目录),在spring的配置文件中要指定其他文件的位置,需要使用classpath,告诉spring到哪里去加载读取文件
* 加载文件列表:
< import resource=“classpath:ba02/spring_school.xml”/ >
< import resource=“classpath:ba02/spring_student.xml”/ >- 在包含关系的配置文件,可以用通配符(* :表示任意字符)
注意:主配置文件名称不能包含在通配符的范围内,不然会出现死循环 - 如果要用通配符,必须有一级目录
< import resource=“classpath:ba02/spring_*.xml”/ >
- 在包含关系的配置文件,可以用通配符(* :表示任意字符)
9.基于注解的di:
- 通过注解完成java对象创建,属性赋值
- 使用注解的步骤:
1.加入maven的依赖,spring-context,在你加入spring-context的同时,会间接加入spring-aop的依赖;使用注解必须使用spring-aop依赖
2.在类中加入spring的注解(多个不同功能的注解)
- 在spring的配置中,加入一个组件扫描器的标签,说明注解在你的项目中的位置
- 使用注解方式,要在spring配置文件中添加"组件扫描器"(component-scan)
- component-scan的属性:
- base-package:指定注解在你的项目中的包名
- component-scan工作方式:spring会扫描遍历base-package指定的包和子包中所有类,找到类中注解按照注解功能创建对象,或给属性赋值:
< context:component-scan base-package=“com.my.ba01”/ >
- 获取对象和bean的方式一样使用ApplicationContext
如何获取多个扫描器:
* 使用多次组件扫描器,指定不同的包
* 使用分隔符(;或,)分割多个包名
< context:component-scan base-package=“com.my.ba01;com.my.ba02”/ >
* 指定父包com.my
- 学习的注解:
1. @Component:
2. @Component:创建对象的,等同于的功能
3. Component属性:value就是对象的名称,就是bean的id值,value的值是唯一的,创建的对象在整个spring容器中就一个,value是指定对象名称,value可以省略,不指定对象名称,由spring提供默认名称:类名的首字母小写
4. @Repository
5. @Service
6. @Controller - 每个注解开发的作用:
* @Repository(用来持久层类的上面):创建dao对象,用来访问数据库的
* @Service(用在业务层类的上面):创建Service对象,处理业务逻辑,可以有事务功能
* @Controller(用来控制器的上面):创建控制器对象的,接收请求,显示处理结果
以上三个注解的使用语法和@Component()一样都能创建对象,但这三个注解还有额外的功能
* @Repository @Service @Controller是给项目的对象分层的 - @Value的使用:
* @Value:简单类型的属性赋值
* 属性:value是String类型的,表示简单类型的属性值
* 位置:
* 在属性定义上面,无需set方法,推荐使用
* 在set方法的上面 - @Autowired给引用类型自动赋值:
1. spring中通过注解给引用类型赋值,使用的是自动注入原理,支持byName,byType
2. @Autowired:默认使用的是byType自动注入
3. 属性:required,是一个boolean类型的,默认是true**
* required=true :表示引用类型赋值失败,程序报错,并终止执行
* required=false:引用类型如果赋值失败,程序正常执行,引用类型是null
4.位置:1.在属性定义的上面,无需set方法,推荐使用
2.在set方法的上面 - 如果要使用byName方式:(没有先后顺序)
* 第一步:在属性上面加入@Autowired(表示使用自动装配)
* 第二步:在属性上面加入@Qualifier(value=“id”):表示使用byName指定名称bean完成赋值
@Autowired(required=true)
@Qualifier(value=“mySchool”)
private School school; - @Resource:
- @Resource:来自jdk中的注解,spring框架提供了对这个注解功能支持,可以使用它给引用类型赋值,使用的也是自动注入原理,支持byName,byType, 默认是byName
- 位置:1.在属性定义的上面,无需set方法,推荐使用
2.在set方式的上面 - 默认是byName:先使用byName自动注入,如果byName赋值失败,再使用byType
@Resource(name=“mySchool”)
private School school; - @Resource只使用byName方式,需要增加一个属性 name,name的值是bean的id(名称)
- 注解开发与配置文件开发:
- 配置文件缺点:代码量多,不够直观与清晰
- 配置文件优点:代码分离,对于经常改的值非常有效
- 注解开发缺点:侵入性,代码与注解一起乱,不适合经常改动的代码
- 注解开发优点:快捷,方便,生产力得到极大的提高,可读性好
- 在注解中使用${ }:
- .Spring配置文件中加入"加载属性配置文件":
<context:property-placeholder location=“classpath:类路径下要读取的配置文件”/> - 代码中的使用(key=value的形式来进行赋值):
- .Spring配置文件中加入"加载属性配置文件":
@Value("${name}")
private String name;
@Value("${age}")
private int age;