Spring

Spring

IOC(控制反转)

概念

把对象的创建、初始化、销毁等工作交给spring容器来做

helloWorld案例

环境

步骤

1、 写一个HelloWorld

2、 写一个配置文件

 

3、 客户端

 

4、 说明:

Spring容器的作用就是为HelloWorld这个类创建对象

Spring容器的结构

 

创建对象

构造函数(用的最多)

在配置文件中进入如下的配置:

在客户端

 

HelloWorld类本身:

 

在控制台打印出了”create object”

可以看出:spring内部默认是调用了HelloWorld这个类的默认的构造函数创建对象

静态工厂

实例工厂

 

说明:

    给工厂类创建了一个对象helloWorldFactory,再利用工厂对象调用工厂方法。

别名

对象的创建时机

案例

执行步骤为1,3,2

 

以上两种情况是默认值,当spring容器启动的时候创建对象

bean有这样一个属性

      Default 相当于false   spring容器启动的时候,创建对象

  True     context.getBean时创建对象

      False     spring容器启动的时候创建对象

意义

如果把lazy-init设置为true,则当spring容器启动的时候,检测不到任何错误,这样会存在很大的安全性隐患,所以一般情况下应该设置lazy-initdefault/false。但是如果一个bean中有一个属性,该属性含有大量的数据,这个时候不希望该bean过早的停留在内存中。

这个时候需要用到lazy-inittrue

对象的scope

默认情况(scope=singleton)

 

在默认情况下放入到spring中的bean是单例的

将来service层和dao层所有的类将放入到spring容器中,所以默认情况下这两个层的类的实例都是单例的,所以不能把数据声明到属性中。如果声明在属性中,将会成为共享的。

Scopeprototype

 

创建时机和scope的结合

Scopeprototypelazy-inittrue

context.getBean时创建对象

Scopseprototypelazy-initfalse

context.getBean时创建对象,lazy-initfalse失效

scposeprototype时,始终在context.getBean时创建对象

Scopsesingleton

是默认情况

Initdestroy

 

说明:

1、 init方法是由spring内部执行的

2、 只有当spring容器关闭以后才能执行destroy方法,spring容器一般情况下是不会关闭的。只有当web容器销毁掉的时候才可能关闭掉,所以只要一个对象在spring容器中,在spring容器关闭之前,会一直保留。

3、 如果一个bean的配置是scope”prototype”,则spring容器不负责销毁。

Spring容器做的事情

 

总结

创建对象

1、 对象的创建方式

2、 对象的创建时机

3、 对象的创建的模式

4、 Initdestroy

5、 创建时机和创建模式的结合

   初始化和销毁

DI(依赖注入)

概念

给属性赋值

pidname赋值的过程就是di

Xml

Setter方法

说明:

1、 spring容器实例化personstudent两个对象

2、 利用java的反射机制调用属性的setter方法赋值

3、 在客户端利用context.getBean方法把spring容器中的一个对象获取了。

 

说明:

1、 启动spring容器

2、 实例化person对象和student对象

3、 person中的属性赋值

4、 调用personinit方法初始化

5、 客户端利用context.getBean获取对象

 

说明:

1、 启动spring容器

2、 实例化person对象

3、 因为person对象依赖于student对象,所以在实例化person对象的时候必须实例化student对象,所以这个时候,在student对象上的lazy-inittrue将失效。

 

说明:

1、 启动spring容器

2、 实例化student

3、 在客户端执行context.getBean方法获取person对象

4、 实例化person对象,调用person的构造函数

5、 调用person中的setStudent方法,给person中的student赋值

6、 执行person中的init方法

7、 Person对象调用方法

构造器

 

说明:

1、 constructor-arg代表指定的构造器函数的其中的一个参数

2、 可以利用index,ref,value,type来指定唯一的构造器

3、 如果一个bean的配置中没有constructor-arg属性,则必须利用默认的构造函数创建对象。

4、 所以在写一个javabean的时候,应该提供属性的setter方法,默认的构造器,带参数的构造器

注解

概念

1、 用来解释说明

2、 注解必须作用在类的某一个部分

3、 注解的作用域范围(java,class,jvm)

4、 注解解析器

自定义的注解

注解的使用

 

注解解析器

Spring中的注解

 

spring的配置文件中

 

说明:

1、 启动spring容器

2、 spring容器内部创建了两个对象personstudent

3、 spring容器解析到

 

启动依赖注入的注解解析器:

4、 spring容器在容器中查找所有的bean(prerson,student)

5、 看哪些bean的属性上面是否有Resource注解

6、 如果属性上面有该注解,再次检查是否有name属性

7、 如果没有name属性,则会把该注解标注的属性的名称获取到和spring容器中的id做匹配,如果匹配成功,则赋值,如果匹配不成功,则按照类型进行匹配,如果匹配成功,则赋值,如果匹配不成功,则报错。

8、 如果有name属性,则把name属性的值解析出来和spring容器中的id做匹配,如果匹配成功,则赋值,如果匹配不成功,则报错。

9、 从上述的步骤可以看出注解的效率比较低,xml的效率比较高,注解书写比较简单,xml书写比较复杂。

Spring容器的关于di的注解

按照类型匹配

按照ID匹配

 

注解只能应用与引用类型

类扫描的注解

步骤

说明:在指定的包及子包中扫描

 

 

流程分析

1、 启动spring容器

2、 Spring容器解析类扫描的注解解析器,在base-package指定的包及子包中查找所有的类

3、 查看哪些类上面是否含有@Component注解

4、 如果该注解的value的属性的值为空,则把类名的第一个字母变成小写,作为id值,放入到spring容器中

5、 如果该注解的value的属性的值不为空,则用value的属性的值作为id值,放入到spring容器中

6、 再次查找在spring容器中的类的所有的属性,按照@Resource的规则给属性赋值

说明

使用了类扫描机制的做法,配置文件中的配置很简单了,但是效率越来越低。

继承

Xml的继承

 

注解的继承

 

IOCDI的意义

案例1

需求

编写一个文档管理系统,在该系统中有如下的结构:

1、 Document:interface

readDocument

writeDocument

2、 WordDocument Document的实现类

readDocument

writeDocument

3、 ExcelDocument

readDocument

writerDocument

4、 PDFDocument

readDocument

writeDocument

5、 DocumentManager

Document  document;

readDocument()

writeDocument()

做法1

说明:

上述的代码是不完全的面向接口编程

做法2

 

说明:

      在代码端没有出现具体的类,完全的面向接口编程。

 

  spring容器的配置文件中决定了documentManager中的接口的实现类是什么。而这个过程和java代码端没有关系。

案例2

需求

action调用serviceservice调用daospring来完成

实现

 

意义

实现了完全的面向接口编程,在代码端没有要关系一个接口的实现类是什么。

Aop

目的

   PersonDao的数据库的操作和Transaction事务的操作分离。

代理模式

静态代理模式

 

动态代理模式

Jdk动态代理
接口

目标类

拦截器

客户端

问题

1、 代理对象有多少方法,方法的名称是什么?

因为代理对象和目标类一样,同样的实现了接口,所以接口中有多少方法,代理对象中就有多少个方法,名称和接口中的方法的名称一样。

2、 拦截器中的invoke方法在什么时候执行的?

当在客户端,代理对象调用方法的时候,进入到了invoke方法

3、 拦截器中的invoke方法中的method参数在什么时候传递的值?

当在客户端,代理对象调用方法的时候,进入到了invoke方法,这个时候,method参数就是代理对象调用的方法。

4、 代理对象的方法体的内容是什么?

代理对象的方法体的内容就是invoke方法体的内容

代理对象的方法体:

1、 开启事务

2、 目标方法

3、 事务的提交

4、 代理对象的方法体就把事务和目标方法结合在一起了,这样做的目的就是为了让目标类的目标方法和事务的方法松耦合。

流程图

 

作用:把目标类和事务松耦合。

Cglib代理

1、 产生的代理类是目标类的子类

2、 是用字节码增强技术产生的代理类

案例

目标接口

 

目标类

日志

安全性框架

权限类

拦截器

 

拦截器把这些内容全部结合在一起了。

改进

可以把日志、安全性框架等作为一个接口出现

 

日志:

 

在拦截器中:

 

Aop的概念

切面

事务、日志、安全性的框架,权限等就是切面

通知

切面中的方法就是通知

切入点

只有符合切入点的条件,才能让通知和目标方法结合在一起

织入

形成代理对象方法体的过程

 

Aop的意义

 

说明:

1、 在开发的过程中,日志、权限、安全性的框架、目标方法完全是松耦合的

2、 在形成代理对象的方法的过程中就把这几个结合在一起了

Springaop

步骤

目标接口

目标类

切面

 

Spring的配置文件

 

执行流程

 

说明:

1、 context.getBean时,如果该类没有生成代理对象,则返回对象本身

2、 如果产生了代理对象,则返回代理对象

3、 如果目标类实现了接口,则采用jdkproxy生成代理对象,如果目标类没有实现接口,则采用cglibproxy生成代理对象,而生成代理对象是由spring容器内部完成的。

切入点表达式

 

代表所有的公共方法

 

代表所有的以set开头的方法

 

代表com.xyz.service包下的AccoutService类的所有的方法

 

代表com.xyz.service包下的所有的类的所有的方法

 

代表com.xyz.service包及子包下的所有的类的所有的方法

 

代表com.itheima.spring.aop.xml包下的所有的类的有三个参数,第一个参数为Long,第二个参数为String,第三个参数为任意类型的所有的方法

 

 

 

 

 

 

通知

前置通知

在目标方法执行之前执行。

 

 

后置通知

在目标方法执行之后执行

可以获取目标方法的返回值

当目标方法遇到异常,不执行

 

 

最终通知

无论目标方法是否遇到异常都会执行,相当于代码中的finnaly

异常通知

获取目标方法抛出的异常

 

环绕通知

能够控制目标方法的执行

 

案例:异常处理

技术图

 

实现
切面

目标类

 

配置

 

从配置中可以看出,把service层所有的类当成目标类,只要service层所有的类的所有的方法抛出异常,则exceptionAspect中的异常通知就会获取到目标方法抛出的异常,所以在这里异常通知就是用来处理异常的,而且只有一个方法。并且该切面和所有的其他类都是松耦合的。

案例:权限的处理

技术图

组成

1、 dao层和service层的类和接口

2、 自定义的注解@PrivilegeInfo

3、 注解解析器:解析目标方法上面的注解的name属性的值

4、 写一个权限类Privilege(name)

5、 写一个关于权限的判断的切面,在切面中写一个环绕通知

实现

参照:/day03-02-itheima09-springAOP-xml-ex-privilege

扩展作业

利用springaop的环绕通知,记录如下的信息:

 目标类     目标方法     执行时间   方法的起始时间  方法的结束时间  

把上述的几个内容保存在数据库中,用jfreechar或者用table显示出来

Spring与数据库

Springjdbc

引入dataSource

 

在客户端:

 

模板编程

类的结构图

方案
方案1


方案2


 

方案3

 

 

Springjdbc的查询

 

Spring的声明式事务处理

概念

程序员不再负责处理事务,事务处理交给spring容器来做。

具体的详解

程序员负责两个内容:

1、 对表的crud操作:目标类的目标方法

2、 告诉spring容器什么样的目标方法采用什么样的事务策略

Spring容器负责:(切面)

     负责事务的处理

实现原理

采用了aop技术来实现的。

事务的架构

 

事务的定义

事务的状态

说明:通过spring的事务处理架构,再通过配置文件具体的实现事务的类,就可以让spring容器知道是什么样的技术来操作数据库,通过对事务状态的判断,通过事务的定义就可以知道具体的目标方法采用什么样的事务策略来处理了。

Springhibernate

组成

1、 hibernate的配置文件

2、 持久化类和映射文件

3、 Dao层和service层所有的类

4、 Spring的配置文件

5、 客户端

Spring的配置文件

关于session

从上图可以看出,程序员使用sessionFactory产生session,从而进行crud的操作

Spring容器利用sessionFactory产生session,进行事务的操作,所以spring容器产生

session和程序员用的session肯定是同一个session,所以在spring声明式事务处理的

时候,session必须由当前线程产生。

Ssh的整合

项目整合

原则

谁能先测试先写谁

步骤

创建web project
把工程改成utf-8的编码
lib下导包

数据库的驱动包

Struts2jar

     struts2-spring-plugin-2.3.1.2.jar  struts2spring整合的jar

hibernatejar

springjar

创建三个src folder

      Src  

          存放源代码

      Config

          存放配置文件

       Test

          存放测试类

src下创建一个包放持久化类和映射文件

config下创建一个package:hibernate.cfg.xml

在该包下创建hibernate的配置文件

 

classpath下准备jdbc.properties

config下创建package:spring

      applicationContext-db.xml文件中:

spring的配置文件中引入sessionFactory

sessionFactory进行测试
创建dao层和service层的接口和类
spring的配置文件中配置声明式事务处理
对声明式事务处理进行测试
创建action层的包和类
action放入到spring的配置文件中

 

准备struts2的配置文件

编写struts-person.xml

web.xml

配置一个监听器

配置一个过滤器

S2sh的整合的目的

问题

1、 struts2action为什么必须交给spring容器产生?

Actionservice要做到完全的松耦合,所以在action中的service必须由spring容器进行注入,那么要完成该注入,action必须在spring容器中。所以action必须由spring容器产生。

2、 在整合的整个过程中,spring容器用到了哪些知识点?

1、 为了松耦合actionservice,servicedao,使用了iocdi

2、 为了不让程序员接触到事务,使用了声明式的事务处理

3、 有可能会用springaop处理权限、日志等内容

3、 在整合的过程中,struts2用到了哪些知识点?

1、 mvc的作用

2、 使用插件的机制使得struts2spring整合在一起了,实际上就是把

Struts2中的action交给spring处理了。

4、 在整合的过程中,hibernate充当了什么角色?

数据库的操作由hibernate充当

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值