spring5笔记

spring5 版本是用 jdk8 编写的,所以要求我们的 jdk 版本是 8 及以上。同时 tomcat 的版本要求 8.5 及以上。

一、IoC 的概念和作用

1.1程序的耦合和解耦

  1. 什么是程序的耦合
耦合度:是对模块间关联程度的度量。模块间联系越多,其耦合度越强.
  1. 什么是内聚
内聚度:内聚标志一个模块内各个元素彼此结合的紧密程度,一个好的内聚模块应当恰好做一件事。
3.解决程序耦合的思路(使用配置文件)(高内聚低耦合)
我们在开发中,有些依赖关系是必须的,有些依赖关系可以通过优化代码来解除的。
在实际开发工程中我们可以把三层的对象都使用配置文件配置起来,当启动服务器应用加载的时候,让一个类中的方法通过读取配置文件,把这些对象创建起来并存起来。在接下来使用的时候,直接拿过来用就好了。这个读取配置文件,创建和获取三层对象的类就是工厂。

1.2 控制反转

1.什么是工厂?
工厂就是负责给我们从容器中获取指定对象的类;我们在获取对象时,都是采用new的方式,是主动的
现在我们获取对象时,是跟工厂要,有工厂为我们查找或创建对象,是被动的。这种被动接受的方式获取对象的思想就是控制反转。
2.什么是控制反转IOC?
把创建对象的权利交给框架。它包括依赖注入DI和依赖查找DL。
作用:解耦

二、Spring基于XML的IOC配置

2.1spring工厂类结构图

(1) BeanFactory 和 ApplicationContext 的区别
BeanFactory 才是 Spring 容器中的顶层接口。ApplicationContext 是它的子接口。
BeanFactory 和 ApplicationContext 的区别:创建对象的时间点不一样。
ApplicationContext:只要一读取配置文件,默认情况下就会创建对象。
BeanFactory:什么使用什么时候创建对象。
(2) ApplicationContext 接口的实现类
ClassPathXmlApplicationContext:
它是从类的根路径下加载配置文件 推荐使用这种
FileSystemXmlApplicationContext:
它是从磁盘路径上加载配置文件,配置文件可以在磁盘的任意位置。
AnnotationConfigApplicationContext:
当我们使用注解配置容器对象时,需要使用此类来创建 spring 容器。它用来读取注解。

2.2 IOC 中 bean 标签和管理对象细节

(1)bean 标签(把对象交给spring容器管理)
作用:用于配置对象让 spring 来创建的。并且存入 ioc 容器之中
默认情况下它调用的是类中的无参构造函数。如果没有无参构造函数则不能创建成功。
属性:
id:给对象在容器中提供一个唯一标识。用于获取对象。
class:指定类的全限定类名。用于反射创建对象。默认情况下调用无参构造函数。
scope:指定对象的作用范围。
* singleton :默认值,单例的.
* prototype :多例的.
(2) bean 的作用范围和生命周期
单例对象:scope="singleton"
一个应用只有一个对象的实例。它的作用范围就是整个引用。
生命周期:
对象出生:当应用加载,创建容器时,对象就被创建了。
对象活着:只要容器在,对象一直活着。
对象死亡:当应用卸载,销毁容器时,对象就被销毁了。
多例对象:scope="prototype"
每次访问对象时,都会重新创建对象实例。
生命周期:
对象出生:当使用对象时,创建新的对象实例。
对象活着:只要对象在使用中,就一直活着。
对象死亡:当对象长时间不用时,被 java 的垃圾回收器回收了。
(3)实例化 Bean 的三种方式
第一种方式:使用默认无参构造函数
<!--在默认情况下:
它会根据默认无参构造函数来创建类对象。如果 bean 中没有默认无参构造函数,将会创建失败。-->
<bean id="accountService" class="com.itheima.service.impl.AccountServiceImpl"/>
 

三、spring 的依赖注入

1、 依赖注入的概念

ioc 解耦只是降低他们的依赖关系,但不会消除。例如:我们的业务层仍会调用持久层的方法。
简单的说,依赖注入就是坐等框架把持久层对象传入业务层,而不用我们自己去获取。

2、 IOC和DI的区别

IOC:控制反转,把对象创建交给spring进行配置
DI:依赖注入,向类里面的属性中设置值
关系:依赖注入不能单独存在,需要在IOC基础上完成操作

3.依赖注入的方式

(1)构造函数注入
使用类中的构造函数,给成员变量赋值。注意,赋值的操作不是我们自己做的,而是通过配置
的方式,让 spring 框架来为我们注入。
<!-- 使用构造函数的方式,给 service 中的属性传值
要求:类中需要提供一个对应参数列表的构造函数。
涉及的标签:
constructor-arg
属性:
index:指定参数在构造函数参数列表的索引位置
type:指定参数在构造函数中的数据类型
name:指定参数在构造函数中的名称 用这个找给谁赋值
=======上面三个都是找给谁赋值,下面两个指的是赋什么值的
value:它能赋的值是基本数据类型和 String 类型
ref:它能赋的值是其他 bean 类型,也就是说,必须得是在配置文件中配置过的 bean
<bean id="accountService" class="com.itheima.service.impl.AccountServiceImpl">
<constructor-arg name="name" value="张三"></constructor-arg>
<constructor-arg name="age" value="18"></constructor-arg>
<constructor-arg name="birthday" ref="now"></constructor-arg>
</bean>
<bean id="now" class="java.util.Date"></bean>
(2) set 方法注入
在类中提供需要注入成员的 set 方法。
<!-- 通过配置文件给 bean 中的属性传值:使用 set 方法的方式
涉及的标签:
property属性:
name:找的是类中 set 方法后面的部分
ref:给属性赋值是其他 bean 类型的
value:给属性赋值是基本数据类型和 string 类型的
实际开发中,此种方式用的较多。
-->
<bean id="accountService" class="com.itheima.service.impl.AccountServiceImpl">
<property name="name" value="test"></property>
<property name="age" value="21"></property>
<property name="birthday" ref="now"></property>
</bean>
<bean id="now" class="java.util.Date"></bean>
 

四、spring基于基于注解的IOC 配置

注解配置和 xml 配置要实现的功能都是一样的,都是要降低程序间的耦合。只是配置的形式不一样。
Spring 注解和 XML 的选择问题
注解的优势:
配置简单,维护方便(我们找到类,就相当于找到了对应的配置)。
XML 的优势:
修改时,不用改源码。不涉及重新编译和部署。
Spring 管理 Bean 方式的比较:
<!-- 告知 spring 创建容器时要扫描的包 -->
<context:component-scan base-package="com.itheima"/>

4.1 常用注解

4.1.1 @Component
用于创建对象的相当于:<bean id="" class="">
@Component
作用:
把资源让 spring 来管理。相当于在 xml 中配置一个 bean。
属性:
value:指定 bean 的 id。如果不指定 value 属性,默认 bean 的 id 是当前类的类名。首字母小写。
@Controller:一般用于表现层的注解。
@Service:一般用于业务层的注解。
@Repository:一般用于持久层的注解。
他们三个注解都是针对一个的衍生注解,他们的作用及属性都是一模一样的。他们只不过是提供了更加明确的语义化。
4.1.2 @Autowired
用于注入数据的相当于:<property name="" ref=""> <property name="" value="">
ioc注解的属性对象必须存在于spring的容器中
@Autowired:自动按照类型注入。默认会去spring容器中按照类型寻找所需要注入的对象,如果找到一个唯一类型,就注入成功。如果找到不是唯一类型,
使用要注入的对象变量名称作为 bean 的 id,在 spring 容器查找,找到了也可以注入成功。找不到就报错.
如果该注解里面配置上了required=false,那么在找不到类型也找不到名字的时候,会返回null值,不会报错。但是如果不配置,就报错。
@Resource:该注解是直接按照名称注入。名称找不到再按照类型注入。如果都找不到,就报错。属性:name:指定 bean 的 id。
@Value:注入基本数据类型和 String 类型数据的.属性:value:用于指定值
4.1.3  @Scope
用于改变作用范围的:相当于:<bean id="" class="" scope="">
 @Scope注解:改变对象作用域的,属性:value:指定范围的值。取值:singleton prototype
单例对象生命周期:容器创建,对象创建,容器在,对象在,容器销毁,对象也销毁。
多例对象生命周期:真正使用的时候,对象创建,一直存在,由java垃圾回收器回收。
4.1.4
(1)<context:component-scan base-package="com.itheima"></</span>context:component-scan>
<!--告知spring框架在,读取配置文件,创建容器时,扫描注解,依据注解创建对象,并存入容器中-->
(2)@Configuration
作用:用于指定当前类是一个 spring 配置类,当创建容器时会从该类上加载注解。获取容器时需要使用
AnnotationApplicationContext(有@Configuration 注解的类.class)。
属性:value:用于指定配置类的字节码
(3)@ComponentScan
作用:用于指定 spring 在初始化容器时要扫描的包。作用和在 spring 的 xml 配置文件中的:
<context:component-scan base-package="com.itheima"/>是一样的。
属性:basePackages:用于指定要扫描的包。和该注解中的 value 属性作用一样。
(4)@Bean
作用:该注解只能写在方法上,表明使用此方法创建一个对象,并且放入 spring 容器。
属性:name:给当前@Bean 注解方法创建的对象指定一个名称(即 bean 的 id)。
(5)@PropertySource
作用:用于加载.properties 文件中的配置。例如我们配置数据源时,可以把连接数据库的信息写到
properties 配置文件中,就可以使用此注解指定 properties 配置文件的位置。
属性:value[]:用于指定 properties 文件位置。如果是在类路径下,需要写上 classpath:
(6)@Import
作用:用于导入其他配置类,在引入其他配置类时,可以不用再写@Configuration 注解。当然,写上也没问
题。
属性:value[]:用于指定其他配置类的字节码。
通过注解获取容器:ApplicationContext ac =new AnnotationConfigApplicationContext(SpringConfiguration.class);

4.2 Spring 整合 Junit

(1)@RunWith 注解替换原有运行器
@RunWith(SpringJUnit4ClassRunner.class)
(2)使用@ContextConfiguration 指定 spring 配置文件的位置
@ContextConfiguration(locations= {"classpath:bean.xml"})
@ContextConfiguration 注解:locations 属性:用于指定配置文件的位置。如果是类路径下,需要用 classpath:表明
classes 属性:用于指定注解的类。当不使用 xml 配置时,需要用此属性指定注解类的位置。

五、AOP

5.1 AOP的相关概念

5.1.1 什么是AOP
Aop面向切面编程,是函数式编程的一种衍生泛型。简单的说它就是把我们程序重复的代码抽取出来,在需要执行的时候,使用动态代理的技术,在不修改源码的基础上,对一个层面的代码进行增强。AOP编程是一个思想,spring的aop底层是使用了jdk动态代理或cglib动态代理实现的。
【动态代理学会一种,另一种也就会了,只是换了下类而已】
我理AOP就是假设A有三个方法,a,b,c
现在要对A进行增强,就是给他增加新的方法,不在A的代码中添加,而是新建一个动态代理类,在他里边给A加一个新的方法d
5.1.2 AOP 的作用及优势
作用:在程序运行期间,不修改源码对已有方法进行增强。
优势:减少重复代码、提高开发效率、维护方便
5.1.3 AOP 的实现方式
使用动态代理技术

5.2动态代理

5.2.1 Jdk动态代理
Jdk动态代理必须是对接口或者是接口的实现类。
创建一个java工程,确保有jdk的包
编写一个需要被增强的类,该类实现了一个接口
创建一个工厂,生产代理对象
工厂中必须提供一个需要被增强的对象的实例或者接口本身
获取代理对象的方法
5.2.2 Cglib动态代理
Cglib是对类的增强的。
导入cglib的jar包
直接导入spring核心包,里面整合了有cglib的包。
编写一个需要被增强的类,该类暂时不实现接口
编写一个工厂,来生成代理对象
必须提供一个被代理对象的实例
提供一个生成代理对象的方法
测试类

5.3  spring中的aop

5.3.1Spring的AOP开发步骤
5.3.2 AOP相关术语
Pointcut连接点:被增强类中所有的方法都是连接点。
Joinpoint切入点:被增强的方法是切入点
Advice(通知/增强):就是增强类
Target(目标对象):被代理对象
Proxy(代理):最终代理对
Aspect(切面):切面就是通知和切入点的组合。
Weaving(织入):把增强类中的方法增强到目标的过程。
可见,所谓面向切面编程,说白了,就是要编写一通知,把通知中的方法织入到切入点上。

六、spring 中的事务控制

6.1 spring事务控制我们要明确的

(1)JavaEE 体系进行分层开发,事务处理位于业务层
(2)spring 框架为我们提供了一组事务控制的接口。这组接口是在spring-tx-5.0.2.RELEASE.jar 中。
(3)spring 的事务控制都是基于 AOP 的,它既可以使用编程的方式实现,也可以使用配置的方式实现。我们学习的重点是使用配置的方式实现。
(4)事务:开启事务、提交事务、回滚事务、释放资源
jdbc:connection 对象的 setAutoCommit(true)。默认是true一条sql语句就是一个事务。模拟转账异常,不支持多条sql语句

6.2 基于 XML 的声明式事务控制(配置方式)

(1)配置事务管理器并注入数据源
<!--配置一个事务管理器-->
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!--注入DataSource-->
<property name="dataSource" ref="dataSource"></</span>property>
</</span>bean>
(2)配置事务的通知引用事务管理器
<!--事务的配置-->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
</</span>tx:advice>
(3)配置事务的属性
<!-- 指定方法名称:是业务核心方法
read-only:是否是只读事务。默认 false,不只读。
isolation:指定事务的隔离级别。默认值是使用数据库的默认隔离级别。
propagation:指定事务的传播行为。
timeout:指定超时时间。默认值为:-1。永不超时。
rollback-for:用于指定一个异常,当执行产生该异常时,事务回滚。产生其他异常,事务不回滚。
没有默认值,任何异常都回滚。
no-rollback-for:用于指定一个异常,当产生该异常时,事务不回滚,产生其他异常时,事务回
滚。没有默认值,任何异常都回滚。-->
<tx:attributes>
<tx:method name="*" read-only="false" propagation="REQUIRED"/>
<tx:method name="find*" read-only="true" propagation="SUPPORTS"/>
</</span>tx:attributes>
(4)配置 AOP 切入点表达式
<!--配置AOP-->
<aop:config>
<!--配置切入点表达式-->
<aop:pointcut expression="execution(* com.itheima.service.impl.*.*(..))"
id="pt1"/>
</</span>aop:config>
(5)配置切入点表达式和事务通知的对应关系
<!--在 aop:config 标签内部:建立事务的通知和切入点表达式的关系-->
<aop:advisor advice-ref="txAdvice" pointcut-ref="pt1"/>
 

6.3 基于 注解的配置方式

(1)拷jar包
(2)配置事务管理器并注入数据源
<!--配置一个事务管理器-->
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!--注入DataSource-->
<property name="dataSource" ref="dataSource"></</span>property>
</</span>bean>
(3)在业务层使用@Transactional 注解
该注解可以出现在接口上,类上和方法上。
出现接口上,表示该接口的所有实现类都有事务支持。
出现在类上,表示类中所有方法有事务支持
出现在方法上,表示方法有事务支持。
以上三个位置的优先级:方法>类>接口
(4)在配置文件中开启 spring 对注解事务的支持
<!--开启 spring 对注解事务的支持-->
<tx:annotation-driven transaction-manager="transactionManager"/>
posted on 2019-08-19 14:39  天高任鸟飞,海阔任鱼游  阅读(148)  评论(0编辑  收藏  举报