ssm学习笔记二-spring框架

P77-79 废话
P80 优势,有印象即可。
P81 体系机构,记不住,感觉只能了解一下
P82-84 以一个jdbc小项目引出耦合的概念,包括:类耦合和方法耦合。以及解耦的概念和解耦的思路:两个步骤(这个重要)
P85-87 以曾经的servlet web开发的结构小demo代码的耦合性,引出工厂模式解耦及工厂解耦的具体方法,并说明了两个重要概念:

  1. Bean:计算机英语中,可复用组件

  2. JavaBean:使用Java编写的可复用组件

    所以:实体类 ⊂ JavaBean,不对等。
    具体方法也就是前面解耦思路两个步骤的具体实现

P88 89 由以上解决方法产生的问题以及解决方法:多例对象和单例对象的选择(单例更好,减少开销,提高效率)以及尽量定义不能被修改的类成员。

P90 通过以上8p视频的内容,引出IOP控制反转的概念和作用

P91 92 引入spring框架完成上述工厂模式的读取配置文件、创建对象、存入spring核心容器map 这三方法。
P93 上述完成读取配置并创建对象的ApplicationContext接口的三个常用读配置实现类和使用事项(展示方法同mybatis学习中的打开图表):

  • Xml方式:

    ClassPathXmApplicationContext(常用):类路径
    FileSystemXmApplicationContext:磁盘任意路径

  • 注解方式:

    AnnotationConfigApplicationContext

P94 上述完成读取配置并创建Bean对象时图表出现的两个接口:
ApplicationContext:默认立即加载(对象),单例对象适用,现都采用此接口,在p96时讲解的scope属性值修改变成多例对象,同时加载方式也会修改,所以下面的方法被淘汰了
BeanFactory:延迟加载(已过时),多例对象适用

P95-97 ApplicationContext接口读取配置文件映射至类时,创建Bean对象的三个方式(在xml文件中配置):

  • 映射类的默认构造函数,默认无参,有参添加一个p99中说明的constructor-arg标签

  • 使用工厂的普通方法创建对象

  • 使用工厂的静态方法创建对象

    后面两种方式适用于封装的jar包文件

同时说明作用范围:scope属性:

  • 1、 singleton 单例

  • 2、 prototype 多例

  • 3、 request web请求范围

  • 4、 session web会话范围

  • 5、 global-session 集群(全局)会话范围,后半p都在讲解这个,就是服务器集群共用一块session

    多使用前两个属性值

伴随讲的多例和单例对象的生命周期(通用的:产生-执行-销毁):

  1. 单例:与spring容器相同
  2. 多例:前面BeanFactory内容所讲的,需要对象是创建,然后垃圾回收机制回收(长时间未使用)

P98-101 spring的依赖注入
98 注入类型:
基本类型与String 只能使用xml或者注解:@Value方式注入
其他Bean类型(需配置(标签或注解配置))。Xml和注解(三个注解)方式均可
复杂/集合类型 只能使用xml方式注入
上述加粗部分p108讲解

注入方式:
构造函数注入(同上述一直使用的,可带参)
Set方式注入(更常用)
注解方式(后续补充)

99 案例实现构造函数注入前两种类型
100 案例实现set方式注入前两种类型
101 案例实现set方法注入最后一种注入类型

上述都是基于XML的方式实现的

以下开始是注解方式实现的
P104 常用IOC注解按照作用的四个分类

P105 106 第一个作用:创建对象,完成该作用的注解:@Component及其对应三层架构的三个子类,完成案例演示

P107 108 第二个作用:注入数据
107 自动类型注入注释:@Autowired 具体注意见视频,特别注意:注入的变量或方法一定要有数据类型修饰,有多个同类型匹配时,再使用名称(方法名或变量名)作为唯一修饰查找(此时需要修改调用方法的对象声明和使用名称为一个被调用层(如视频的Dao层)类方法名一样的唯一标识,如视频中的Service实现类中定义的Dao类对象改成了accountDao1)。而且注解注入时,set方法就非必须了。
108 如果想在业务层Service实现类使用通用Dao对象,就引出这个注解:@Qualifier,注意的是,其给类成员不能单独使用,需配合上述注解,给方法参数(p119)注入时却可以。
属性值value:指定id(唯一标识),与上述改名差不多一个意思
两个注解同一功能的一个注解:@Resource 属性:name(指定类方法唯一标识)

@Value 属性:value(指定数据的),还可使用SpEL表达式(spring的EL表达式)

P109

  • 第三个作用:改变作用范围:

    @Scope 属性:scope(指定范围的取值,有上述说过的两个常用取值)

  • 第四个作用:生命周期有关 (了解即可)

    @PostConstruct:指定初始化方法
    @PreDestroy:指定销毁方法

P110-112 基于XML方式spring IOC综合案例

  • 第一个问题:

    dependency依赖添加失败,又找了一会,在一个英语博客站找的了相关描述:To Invalidate Caches and Restart(清除缓存并重启),成功了,果然重启大法好。后续我发现了右键maven选项中的Reload Project也能实现该功能。

  • 第二个问题

    110 项目、环境搭建(尝试以上部分的mybatis课程的内容来建立,发现不行,实现类部分处理逻辑没想明白,明天再来试试)

    再次搭建环境,昨天遇到的空指针异常,因为掉用userDao对象没有获得,就把test里的类中对IUserDao解析的方法放入UserDaoImpl类中即可,但是方法上面的注释@Before、@After、@Test貌似只有在Test类中才生效,所以要在每一个实现方法中调用Init()方法来实现userDao对象。本来想把解析从方法中提出出来,但是**Resources.getResourceAsStream(“SqlMapConfig.xml”);**该语句需要throws异常,或者使用try/catch(推荐这个),然后关闭和事务提交找半天发现是在return之后添加的destroy()方法,所以不生效。第二天我又单独把那部分解析方式放入一个独立的类,创建类实例来调用。

P111 编写bean.xml,后半p都在讲jdbc数据源的xml标签填写,与mybatis有点类似。
配置bean.xml文件时出错,发现自己没好好听课,要消减耦合,就不要用new方法,我还是用了。删掉new对象后出现,Cannot resolve property ‘xxx’,这是因为我又没好好听课,原来那个实例不new了后就是空的了,所以我们需要在实例对象下用idea帮我们创建一个setter方法。

P112 编写测试方法
问题:

在完成测试类编写后,运行报错,显示错误信息百度后是数据源的问题,应该是bean.xml没配好,然后我研究了一下,直接在UserDaoImpl提取出init方法的内容实现解析,不在xml中额外配置;或者是新建一个类实现原init()和destroy()解析,并把init()方法改为返回值为IUSerDao类,然后配置xml文件即可,执行操作语句也相应改成handle.init().xxx()。

P113 基于注解方式spring IOC综合案例,但是bean.xml依然存在,此时使用了一个<context:component-scan>标签来指定扫描的包,后续才会讲如何配置后删除,并引出几个问题

P114 115 解决上述的删除xml文件问题,引出三个新注解:
@Configuration,指定当前类是一个配置类
@ComponentScan[s]指定spring在创建容器时要扫描的包(同<context:component-scan>的作用),
@Bean,把当前方法的返回值作为bean对象存入springIOC容器,属性:name,指定bean的id(即map容器的key),不写时默认值为方法名。注意一个该注释的细节:存入的方法带方法参数时,会去map容器中寻找匹配的bean对象,匹配机制同
@Autowired

P116 改造完成后Test类中就需要把实现ApplicationContext接口的的实现类改成第一天p93时说明的AnnotationConfigApplicationContext类,并引出了p94讨论的单例多例问题解决:与@Bean注释一起使用的@Scope注释(类似于xml中bean标签的scope属性),并引出改造之后的可进一步改造几个小细节:

P117 细节一:
@Configuration注释:当类作为AnnotationConfigApplicationContext的参数时,该注释可不写,由此引出@Bean注释必须是被认为是配置类才会被@ComponentScan扫描,多个配置类时,要么都写进AnnotationConfigApplicationContext作为参数,要么加@Configuration注释。或者引出了后半p的新注解**@Import**
@Import,导入其他配置类构成主副配置类。属性:value,类的字节码(即xxx.class)

P118 细节二
注释方式改造后,数据源对象的内容被封装写死。
通过@PropertySource[s]注解引入一个配置文件,属性:value[],指定文件路径和名称(可加上一个关键字classpath:表示字段为类路径)。
发现:配置数据源配置类注解并没有比保留xml文件的注解方法方便,采用何种方法应首先考虑公司项目要求,在哪种方式方便用哪种,比如自己的实现类用注解方便,导入的jar只能用xml等,

P119 细节三
上面p115说的@Bean注释的方法参数匹配时参照**@Autowired**,即多个匹配也可以通过该该参数名来实现对应,或者引出p108的**@Qualifier**单独使用,属性值:id:bean的名称

P120 121 spring整合Junit

120 整合时的问题分析
121 整合具体实现:两个注解:
@RunWith,把Junit自带的用于@Test的测试方法的main()方法替换为spring提供的main()方法。值为:SpringJUnit4ClassRunner.class是我字节码文件
@ContextConfiguration,告知Spring创建IOC容器是基于xml还是注释方式的,并告知位置。属性:locations:(xml方式及xml文件位置(名称)),classes(注解方式及字节码文件位置(名称))
同时注意,spring 5.x版本时,Junit也需要4.12及以上版本。
注意,SpringJUnit4ClassRunner.class中是Junit而不是Junit,

Idea的一个细节:IDEA自动重置LanguageLevel和JavaCompiler版本的问题
解决:https://blog.csdn.net/isea533/article/details/48575983,除了blog的方法,原解决地址还有另一个标签的方法

P123-131 案例引出事务控制的一致性要求和自定义动态代理实现
P123 案例实现一个转账方法引出一个事务提交不一致问题:当需要一致提交的方法,当时为两个语句来分别实现的提交,如果中间出现一个error,就会出现前面的事务提交了,但后面的事务没提交,数据出现异常。

P124-127 综合案例解决上述事务问题:
124 分析事务的问题并编写ConnectionUtils
125 编写事务管理工具类并分析连接和线程解绑
126 编写业务层和持久层事务控制代码并配置spring的ioc(bean.xml)
127 测试转账并分析案例中的问题:方法依赖及解决方法:动态代理

P128-131 案例讲解动态代理及其实现事务控制
128 举一个例子讲述代理的功能
129 动态代理特别是基于接口的动态代理知识回顾,
实现类:Proxy及其实现方法:newProxyInstance()和它的三个方法参数:ClassLoader类加载器(固定写法),Class[]字节码数组(固定写法),InvocationHandler提供增强代码(匿名内部类,解决如何实现,方法invoke(),返回值与被代理对象执行方法的返回值一致),具体作用和要求见视频
与上一部分mybatis中的代理对象的创建方法:getMapper的解析的原理相同,都是该实现类(p11-19)
只能实现对接口的动态代理,不能对普通Java类进行代理

130基于子类的动态代理知识回顾和案例实现
实现类:Enhance及其实现方法:create()和它的两个个方法参数:Class字节码(固定的)和Callback提供增强代码(匿名内部类,解决如何实现,通常使用该类的子接口实现类MethodInterceptor的方法:intercept()四个参数的前三个参数与上述invoke()参数一致,返回值也是,methodProxy是当前执行方法的代理对象),具体作用和要求见视频
要求被实现的类不能是final类
上述两种以及Spring中AOP,实现的选择就看是否实现了接口
131使用动态代理实现事务控制的具体代码案例,类似于上一部分mybatis中的代理对象实现类(p11-19)的自定义实现方法讲解,建立有一定困难,所以引出了spring提供的代理对象实现:AOP(面向切面编程)。

P132-141 小案例讲解spring的AOP基于两种方式的实现
P132 AOP概念以及spring的AOP介绍

P133 Spring的AOP的细节:包括说明、专业术语和运行过程

P134-139 小案例讲解基于XML的AOP配置
134 135 基于XML的AOP-环境搭建和配置步骤及知识点
使用<aop:config>标签(声明配置)并内嵌<aop:aspect>标签配置切面(增强类),最后内嵌四种通知标签<aop:xxxx>之一配置通知类型和关联两个方法(通知方法和切入点方法)
136 AOP的注意点和切入点表达式的写法 (重点通配符的写法)
137 134所说的四种常用通知类型及其执行时间(对应切入点方法执行):
<aop:before> 前置通知 执行之前执行
<aop:after-returning> 后置通知 正常执行之后执行
<aop:after-throwing> 异常通知 执行产生异常后执行
<aop:after> 最终通知 无论如何执行,执行完后都执行
138 通用化切入点表达式标签<aop:pointcut>,可以在<aop:aspect>标签内部也可以在外部,在内部只能在当前切面可用,在外部所有aop切面可用,但注意约束,必须出现在<aop:aspect>标签之前。
引出了一个编程习惯:语句改动位置不能使用时,首先应该想到是否有约束上的要求
139 四种常用通知类型之外的环绕通知:<aop:around>标签:
问题:执行后,切入点方法没执行,通知方法执行了
解决:
Spring提供了一个接口:ProceedingJoinPoint及其方法:proceed(),该方法明确了调用切入点方法。这是spring为我们提供的可以在代码中手动控制增强代码何时实现的方式。
总结:增强代码实现四种常用通知类型可以配置spring来实现,也可以是环绕通知自己编码来实现

P140 spring基于注解的AOP配置:
@Aspect 表示该类是个切面,然后在该类方法下:
@Before() 前置通知
@AfterReturning() 后置通知
@AfterThrowing() 异常通知
@After() 最终通知
@Around() 环绕通知
括号内用属性值:切入点表达式
在一个方法前加@Pointcut()注释,属性值同xml方式的一致:execution(表达式)

最后在xml中使用标签<aop:aspectj-autoproxy>开启spring注解AOP支持。

但是,案例演示中发现,四个常用注解在实际调用中有调用顺序的问题,最终通知会出现在后置或异常通知前,使用环绕通知就不会,因为上述说过,环绕通知是我们自己编码来实现的,而注解方式更方便,具体看自己选择(个人觉得xml的四中常用通知最方便)
还有一个注意:注解中的切入点表达式一定是方法,通知注解参数填写时一定要加括号
纯注解不使用xml的方式提了一下,除了一个注解就能实现外还要加上p114 115所讲的注解表明扫描的配置类

P141 总结及一个重要的作业
把工程类及其生产IAccountService代理对象的xml解析删除,并以xml标签配置AOP即可完成。

P143-147 JdbcTemplate
P143 144 JdbcTemplate概述、简单使用和IOC的使用
P145 JdbcTemplate的CRUD操作案例

P146 持久层(DAO层)的重复代码,解决自定义一个类,再引出spring自带的JdbcDaoSupport类,继承了该类注解配置IOC麻烦,注意

P147 JdbcDaoSupport的使用以及Dao的两种编写方式

P148 141的作业 xml方式
P149 150 141的作业 注解方式
又遇到了140所说的执行顺序问题,这次因为最终通知执行后释放了连接,所以之后的后置/异常通知执行报错。之后打断点debug方式报错分析,解绑后重新拿到的连接与前面的事务不对应,提交不了事务。解决方法:使用环绕通知

P151-155 Spring声明式事务控制

p151 spring中事务控制的一组API相关知识点学习

p152案例实现spring事务控制的环境搭建和代码准备

p153 案例实现spring基于XML的声明式事务控制-配置的五个步骤,第五步中的配置事务属性的属性值对应151知识点中的事务定义信息对象的方法

步骤:
在这里插入图片描述

属性值:

在这里插入图片描述

p154 案例实现spring基于注解(带xml文件)的声明式事务控制-配置的三个步骤,第三个步骤的**@Transactional**注解中对应151知识点中的事务定义信息对象的方法的属性值需要基于每个方法的不同需求来配置,不如xml简单
步骤:
在这里插入图片描述

p155 案例实现spring基于纯注解的声明式事务控制-配置步骤,结合了P113-119的配置类的注解配置,引出一个新的注解:@EnableTransactionManager,开启Spring注解事务的支持

p156 157 案例实现spring编程式事务控制,不灵活,略

158 spring 5.x新特性 其中响应式编程很重要,但要学习了spring boot才能看懂资料

====================================================
10/2更新
在换了BV1WZ4y1H7du的SpringMVC后,稍微查看了一下spring的课程,发现了一个需要记录的知识点:
Spring集成web环境(P72-76):具体案例实现
首先用p1的方法建立web工程
p72 项目和环境搭建
p73 75 Servlet重复代码提取:ServletContext的全局监听器实现

  • 73 ContextLoaderListener监听器的分析
  • 74 自定义ContextLoaderListener,实现容器加载
  • 75 项目优化解耦:全局初始化参数标签:<context-param>,解耦IOC配置文件读取;Servlet保存数据方式:setAttribute()方法的键值耦合解耦:自定义一个工具类并建立方法,再在servlet中实例化

p76 Spring对上述方法的封装实现:
Spring提供的监听器:ContextLoaderListener
客户端工具类:WebApplicationContextUtils

猜你喜欢

转载自blog.csdn.net/qq_43175022/article/details/108889868