-
spring
解决企业级开发的难度,减轻对项目模块之间的管理,类和类之间的管理,帮助开发人员创建对象,管理对象之间的关系 核心技术ioc,aop
-
官网
权威
-
框架内部模块
优点: 1:轻量 2:针对接口编程,解耦 3:aop编程的支持 4:方便集成各种优秀框架 spring体系结构:数据,web,集成,容器,测试
-
ioc的概念
框架怎么学-框架是软件 能做什么:mybatis-访问数据库 框架语法:要完成一个功能,需要一定步骤的支持 框架的内部实现,内部怎么做,原理是什么。 通过学习,实现一个框架。 ioc控制反转:对象的创建,赋值,管理都交给代码之外的容器实现,对象的创建由其他外部资源完成——反转就是由容器代替开发人员管理对象,创建对象,给对象赋值 为什么要使用ioc:目的就是减少对代码的改动,也能实现不同的功能
-
创建对象的方式
1:new 2:反射 3:序列化 4:克隆 5:ioc
-
ioc的技术实现di
ioc的体现:servlet是tomcat服务器为你创建的 ioc的技术实现:di依赖注入——创建,赋值,查找由容器内部实现|||底层用的是反射创建的对象
-
例-创建对象
1:创建maven项目 2:加入maven依赖 3:创建类 4:创建spring需要使用的配置文件 5:测试 @Test 自己new对象
-
创建spring配置文件
声明bean,告诉spring要创建某个类的对象 id:对象的自定义名称,唯一值,spring通过这个名称找到对象 class:类的全限定名称 <bean id="" class=""> spring把创建好的对象放到map中,spring框架有一个map存放对象 一个bean标签声明一个对象
-
创建容器对象Applicationcontext
Applicationcontext就表示spring容器,通过容器获取对象 classpathxmlApplicationcontext:表示从类路径下加载spring的配置文件 Applicationcontext ac=new classpathxmlApplicationcontext("config"); 从容器中获取某个对象,你要调用对象的方法:ac.getbean("配置文件中bean的id值")
-
spring创建对象的时机
会创建配置文件中的所有对象
-
获取容器中对象信息的api
使用spring提供的方法,获取容器中定义的对象的数量:int nums=ac.getbeandefinitioncount(); 容器中每个定义的对象的名称:String names[]=ac.getbeandefinitionNames();
-
创建非自定义对象
创建一个存在的某个类的对象<bean id="mydate" class="java.util.Date"> Date my=(Date) ac.getbean("mydate"); spring创建对象:默认调用的是无参构造方法
-
设值注入概念
di的实现方法有两种: 1:在spring的配置文件中,使用标签和属性完成,叫做基于xml的di实现 2:使用spring中的注解,完成属性赋值,叫做基于注解id实现 di的语法分类: 1:set注入(设置注入):spring调用类的set方法,在set方法可以实现属性的赋值 【spring调用类的set方法,可以在set方法中完成属性赋值】——【简单类型:spring规定java的基本类型和String都是简单类型】 2:构造注入,spring调用类的有参构造方法,创建对象,在构造方法中完成赋值
-
简单类型的设值注入实现
<bean id="xx" class="yy"> <property name="属性名字" value="此属性的值"> "name==setname" //一个property只能给一个属性赋值 </bean>
-
单元测试junit
junit:单元测试——方法测试 1:加入junit依赖 2:创建测试类:src/test/java 3:创建测试方法,【 1)public方法 2)没有返回值void 3)方法名称自定义 4)方法没有参数 5)方法的上面加入@test,这样的方法是可以单独执行的,不用使用main方法 】
-
设值注入的注意事项
要想通过配置文件中property属性注入,必须要有set方法 因为是调用的set方法,所以必须有set方法才能注入 【先创建对象,再赋值 】
-
设值注入——只是使用set方法
根据email,猜测使用setemail方法 property中age="22"为什么要+"":因为这是xml的规则 name->setname(value)
-
引用类型的设值注入
//引用类型 private School school; 先创建对象并赋值后,再调用对象 引用类型的set注入,依旧调用set方法 <bean id="yyy" class="xxx" > <property name="属性名称" ref="bean的id(对象的名称)" /> //引用类型要声明对象 </bean>
-
构造注入
调用类的有参数构造方法,在创建对象的同时,在构造方法中给属性赋值 使用<constructor-arg>标签——一个标签表示构造方法一个参数 标签属性: 【 name:表示构造方法的形参名 index:表示构造方法的参数的位置,参数从左往右位置是0,1,2的顺序 value:形参类型是简单类型 ref:形参类型是引用类型 】
-
构造注入创建文件对象
创建file,使用构造注入 使用name value
-
复习总结
什么样的对象放到容器中:[dao,service,controller,工具类] 怎么放入容器中: 【 1:使用xml文件,使用<bean> 2:注解 】
-
复习ioc
使用容器中的对象,通过Applicationcontext接口和他的实现类ClasspathxmlApplicationContext的方法getbean()
-
ioc作业
用哪个对象,就bean声明哪个对象 在xml中给属性赋值,要求属性要有set方法 面向接口编程 改动量小就会适应 解耦合
-
自动注入Byname
引用类型的自动注入:spring框架根据某些规则可以给引用类型赋值 Byname:java类中引用类型的属性名和spring容器中(配置文件中)<bean>的id名称一样,且数据类型是一样的,这样的容器中的bean,spring能够赋值给引用类型 语法: 【 <bean id="xx" class="yyy" autowired=byName> //简单类型属性赋值 </bean> 】
-
自动注入byType
byTpye:按类型注入,java类中,引用类型的数据类型和spring容器中(配置文件)<bean>的class属性是同源关系,这样的bean能够赋值给引用类型 同源:类型一样或父子,或接口和实现类关系 语法:同上-换byType 在声明父子不能同时,注意唯一bean
-
为什么使用多配置文件
因为在大规模软件中:一个xml会太大,打开,保存都慢,找到类也慢,且多人用同一文件会有竞争 优势: 1:文件小,效率高 2:避免多人竞争冲突 多文件分配方式: 1:按功能模块分 2:按类的功能分
-
包含关系的配置文件
包含其他配置文件 语法:<import resource="其他配置文件的路径"> 关键字:classpath:表示类路径——使用:在spring的配置文件中要指定其他文件的位置——指:(target/classes) 类中加载主配置文件——》主配置文件再去加载其他各文件 在包含关系的配置文件中可以使用通配符来一次加载一类文件(*)
-
注解的使用步骤
用注解代替配置文件,创建对象,使用,和赋值 注解也是一个类 使用步骤: 1:加入maven依赖——spring-context 2:在类中加入spring的注解 3:在spring的配置文件中加入一个组件扫描器的标签,说明注解在你项目中的位置 学习的注解: 1:@component 2:@repostory:(用在持久层类的上面)放在dao层的实现类上面,表示创建dao对象,dao对象是能访问数据库的 3:@service:(用在业务层类的上面) 放在service的实现类上面,创建service对象,service对象是做业务处理,可以有事物等功能的 4:@controller:(用在控制器的上面)放在控制器类的上面,创建控制器的对象的,能够接受用户提交的参数,显示请求的处理结果的 //以上三个注解的使用语法和@component一样的。都能创建对象,但是这三个注解还有额外的功能,这三个注解用来给项目对象分层 5:@value 6:@autowired 7:@resource
-
component注解使用
@component:创建对象的,等同于bean的功能 语法:@component(value="mystudent") 位置:放在类的上面 .xml中声明组件扫描器:<context:component-scan base-package=""> 工作方式:spring会扫描遍历base-package指定的包,把包中和子包中的所有类,找到类中的注解,按照注解的功能创建对象,或给属性赋值 base-package:指定注解在你项目中的包名
-
组件扫描器
在类中: 1:创建容器对象-(容器对象中传入配置文件) 2:从容器中获得bean
-
多注解项目分层
//省略value @component("mystudent") //不指定对象名称,由spring提供默认名称:类名的首字母小写 @component 什么时候用@component:当类不是dao,service,controller时用
-
扫描多个包的方式
指定多个包的三种方式 1:使用多次组件扫描器,指定不同的包 2:使用分隔符(;或,)分隔多个包名 3:指定父包
-
简单类型属性赋值
@value:简单类型的属性赋值 属性:value,是string类型的,表示简单类型的属性值 位置: 【 1:在属性定义的上面,无需set方法,推荐使用 @value(value="张飞") 2:在set方法的上面 】 容器中维护着一个map存放对象
-
引用类型autowired
@autowired:实现引用类型的赋值,使用的是自动注入原理,默认使用的是byType自动注入 位置: 1)在属性定义的上面,无需set方法,推荐使用 2)在set方法的上面
-
引用类型autowired的byname
1.在属性上面加入@autowired 2.>>>+@qulifire(value="bean的id") 俩注解一块用
-
引用类型Autowired的required属性
required:boolean类型,默认true,表示引用类型赋值失败,程序报错,并终止执行 如果false,引用类型如果赋值失败,程序正常执行,引用类型是null
-
引用类型Resource
jdk注解 spring提供了对这个注解的功能支持,可以使用它给引用类型赋值,使用的也是自动注入原理,支持byName,byType,默认是byName 位置: 【 1:在属性定义的上面,无需set方法,推荐使用 2:在set方法上面 】 默认byname,先使用byname,如果byname赋值失败,再使用bytype 只使用byname方式,需要增加一个属性name,name的属性bean的id
-
xml配置文件和注解的对比
注解是开发趋势 优势:方便 劣势:乱 //加载属性配置文件 语法:<context:property-placeholder location="classpath:test.properties"> test.properties:该文件用来给属性赋值
-
复习动态代理的实现方式
jdk: 要求目标对象必须实现接口 cglib:生成原理是生成目标类的子类,效率高于jdk
-
业务方法增加功能
抽取出公共的代码,写到工具类 然后业务层的代码,如果需要就再调用
-
动态代理实现invocationHandler
动态代理:在程序的执行过程中,创建代理对象,通过代理对象执行方法,给目标类的方法增加额外的功能(功能增强) jdk动态代理实现步骤: 1:创建目标类 2:创建invocationHandler接口的实现类 3:使用jdk中类proxy,创建代理对象,实现创建对象的能力
-
创建动态代理对象
1:创建目标对像 service target=new serviceimpl(); 2:创建invocationHandler对象 invocationHandler handler=new myinvocationHandler(target); 3:使用proxy创建代理 someservice proxy=(someservice) proxy.newproxyinstance(target,getclass().getclassloader(),target.getclass().getinterfaces(),handler) //通过代理执行方法,会调用handler中的invoke()
-
什么是aop
底层:动态代理 实现方式: 1:jdk:使用jdk中的proxy 2:cglib:第三方工具库,创建代理对象,原理是继承。 动态代理的作用: 1:目标类源代码不改变,增加功能 2:减少重复代码 3:专注业务逻辑代码 4:解耦合 Aop就是动态代理的规范化,
-
怎么理解面向切面编程
切面:给目标类增加的功能就是切面,像日志,事务 怎么理解: 1:找出切面 2:安排执行时间 3:安排执行位置(哪个类,哪个方法)
-
术语和aop实现框架
aspect:切面 joinpoint:连接点,业务方法-连接业务和切面 pointcut:切入点,多个连接点集合,多个方法 目标对象:给哪个类增加功能,这个类就是目标对象 advice:表示切面功能的执行时间 在项目中很少用spring的aop,因为笨重,更多用aspectj, aspectj框架实现aop,两种方式。 1:使用xml的配置文件 2:使用注解,5个
-
aspect的5个通知注解
1:切面的执行时间,advice(通知,增强) 【 1:@before 2:@afterreturning 3:@around 4:@afterthrowing 5:@after 】
-
切入点表达式语法
excution(访问权限 方法返回值* 方法声明(参数)* 异常类型)
-
前置通知创建maven项目
1:新建maven项目 2:加入依赖 1)spring依赖 2)aspect 依赖
-
aspectj使用步骤
//添加依赖 1:创建切面类: 1)在类的上面加入@aspect 2)在类中定义方法,在方法上加入aspectj的通知注解,如@before, 2:创建spring的配置文件,声明对象,把对象交给容器统一管理 1)声明目标对象 2)声明切面类对象 3)声明aspectj框架中的自动代理生成器标签 自动代理生成器:用来完成代理对象的自动创建功能的
-
创建切面类和配置文件
@aspect 作用:用来给业务方法增加功能的类 @before 前置通知注解 属性:value,切入点表达式 <aop:aspectj-autoproxy>:spring把容器中的所有对象,一次性都生成目标对象
-
Point cut注解
如果项目中多个切入点表达式是重复的,可以用@pointcut注解
-
没有接口是cglib
有接口也可以用cglib 语法:proxy-target-class="true"
-
spring整合mybatis的思路
用的技术:ioc 因为ioc能创建对象,可以把mybatis框架的对象交给spring统一创建,开发人员从spring中获取对象 开发人员不用同时面对多个框架了,就面对一个spring mybatis使用步骤,对象 1:定义dao接口 2:定义mapper文件 3:定义mybatis的主配置文件 4:创建dao的代理对象 studentdao dao=sqlsession.getMapper(studentdao.class) List<student> students=dao.selectstudents(); 要使用dao对象,需要使用getMpper方法 怎么能使用getMapper方法,需要哪些条件 1:创建sqlsession对象,需要使用sqlsessionFactory的openssion()方法 2:创建sqlsessionFactory对象,读取mybatis的主配置文件,能创建sqlsessionFactory对象 主配置文件: 1:数据库信息(连接数据库) 2:mapper文件的位置 会用独立的连接池代替mybatis自带的 1:独立的连接池类的对象,使用阿里的druid连接池 2:sqlsessionFactory对象 3:创建出dao对象 上面3个对象的创建语法,只能使用bean标签来创建对象,因为没有源代码,没有注解
-
整合dao接口和mapper文件
1:新建maven项目 2:加入maven的依赖 1)spring依赖 2)mybatis依赖 3)mysql驱动 4)spring的事务的依赖 5)mybatis和spring集成的依赖:用来在spring项目中创建mybatis的sqlsessionFactory,dao对象的 3:创建实体类 4:创建dao接口和mapper文件 //dao:接口里面定义方法//mapper里面连接接口的方法,查询数据库 5:创建mybatis主配置文件 6:创建service接口和实现类,属性是dao 7:创建spring的配置文件:声明mybatis的对象交给spring创建 1)数据源 2)sqlsessionFactory 3)dao对象 4)声明自定义的service
-
创建mybatis主配置文件
日志/别名/mapper文件的位置
-
创建service类
//调用dao service接口:业务方法 service实现类:业务方法实现
-
配置Datasource
配置Datasource 声明数据源,作用:连接数据库 配置sqlsessionFactorybean
-
配置dao类
mapperscannerconfigerer:在内部调用getmapper()生成每个dao接口的代理对象,它会扫描这个包中的所有接口,把每个接口都执行一次getmapper()方法,得到每个接口的dao对象,创建好的dao对象放入到spring的容器中。dao对象的默认名称是接口名首字母小写
-
测试容器中的service和dao对象
spring和mybatis整合在一起,事务是自动提交的 通过service去访问dao
-
使用属性配置文件
把数据库的配置信息,写在一个独立的文件,编译修改数据库的配置内容
-
处理事务的问题
1:什么是事务 讲mysql的时候提出了事务,希望多个sql语句要么都成功,要么都失败 2:什么时候想到使用事务 都成功或者都失败才能完成功能 事务放在service类的业务方法上 3:通常使用jdbc访问数据库,还是mybatis访问数据库怎么处理事务 jdbc:Connection conn;conn.commit();conn.rollback(); mybatis:Sqlsession.commit();Sqlsession.rollback();
-
统一处理事务的优势
4:3问题中事务的处理方式有什么不足 1)不同的数据库访问技术,处理事务的对象,方法不同,需要了解不同数据库访问技术使用事务的原理 2)掌握多种数据库中事务的处理逻辑,什么时候提交事务,什么时候回滚事务 3)处理事务的多种方法
-
spring处理事务的统一方式
怎么解决不足: spring提供一种处理事务的统一模型,能使用同一步骤,方式完成多种不同数据库访问技术的事务处理 spring的事务处理模型:抽象了事务处理各个方面,定义了事务的处理步骤 声明式事务:把事务相关的资源和内容都提供给spring,spring就能处理事务提交,回滚了,几乎不用代码 处理事务,需要怎么做,做什么: spring处理事务的模型,使用的步骤都是固定的,把事务使用的信息提供给spring就可以了 1)事务内部提交,回滚事务,使用的事务管理器对象,代替你完成commit,rollback,//事务管理器是一个接口和它的众多实现类 怎么使用:需要告诉spring用的是哪种数据库的访问技术,在spring的配置文件中使用<bean声明就可以了>
-
控制事务的三个方面
你的业务方法需要什么样的事务,说明需要事务的类型 说明方法需要的事务: 1)事务的隔离级别:有4个值 【 读未提交 读已提交——default 默认 可重复读 串行化 】 2)事务的超时时间:表示一个方法最长的执行时间,如果方法执行时超过了时间,事务就回滚,单位是秒,整数值,默认-1 3)事务的传播行为:控制业务方法是不是有事务的,是什么样的事务的。 7个传播行为,表示你的业务方法调用时,事务在方法之间是如何使用的
-
事务的传播行为
提交事务,回滚事务的时机 1)当你的业务方法执行成功,没有异常抛出,当方法执行完毕,spring在方法执行后提交事务。事务管理器commit 2)当你的业务方法抛出运行时异常,spring执行回滚,调用事务管理器的rollback,运行时异常RuntimeException 3)如果抛出非运行时异常,提交事务