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