ssm框架学习
ssm框架
一、spring
1.1 Spring Framework系统架构
Spring Framework是Spring生态圈中最基础的项目,是其他项目的根基
- Data Access: 数据访问
- Data Integration: 数据集
- Web: Web开发
- AOP:面向切面编程
- Aspects: AOP思想实现
- Core Container: 核心容器
- Test:单元测试与集成测试
1.2 核心概念
IoC(Inversion of Control)控制反转
- 使用对象时,由主动new产生对象转换为由外部提供对象,此过程中对象创建控制权由程序转移到外部,此思想称为控制反转
Spring技术对IoC思想进行了实现
- Spring提供了一个容器,称为IoC容器,用来充当IoC思想中的外部
- IoC容器负责对象的创建、初始化等一系列工作, 被创建或被管理的对象在IoC容器中统称为Bean
DI ( Dependency Injection )依赖注入
- 在容器中建立bean与bean之间的依赖关系的整个过程, 称为依赖注入
IoC具体实现:
导入spring坐标,新建spring配置文件applicationContext.xml
在配置文件中配置bean
1
2
3
4
5
6
7
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id = "bookDao" class="org.example.dao.impl.BookDaoImpl"/>
<bean id = "bookService" class="org.example.service.impl.BookServiceImpl"/>
</beans>获取Ioc容器
获取bean
1 | public class App2 { |
DI具体实现:
1.删除业务层中new创建的dao对象
2.提供对应的set方法
3.配置dao与service的关系
1 | <bean id = "bookDao" class="org.example.dao.impl.BookDaoImpl"/> |
1.3 XML-bean配置
- bean基础配置
- bean别名配置
使用name属性配置别名,多个别名使用空格隔开
1 | <bean id = "bookDao" name="bookDao2 bookDao3" class="org.example.dao.impl.BookDaoImpl"/> |
- bean作用范围配置
spring创建的bean默认为单例,使用scope属性配置,singleton(单例),prototype(非单例)
- bean适用对象说明
- 适合交给容器进行管理的bean
- 表现层对象
- 业务层对象
- 数据层对象
- 工具对象
- 不适合交给容器进行管理的bean
- 封装实体的域对象
1.4 XML-bean实例化
- 方法一:构造方法实例化bean
bean本质上就是对象,实例化就是调用的无参构造方法(无论是public还是private)
- 方法二:使用静态工厂实例化bean
静态工厂:
1 | public class OrderDaoFactory { |
配置:
1 | <bean id="orderDao" class="org.example.factory.OrderDaoFactory" factory-method="getOrderDao" /> |
- 方法三:实例工厂实例化bean
实例工厂:
1 | public class UserDaoFactory { |
配置:
1 | <bean id="userDaoFactory" class="org.example.factory.UserDaoFactory" /> |
- 方法四:使用factoryBean实例化(方法三改良)
1 | public class UserDaoFactoryBean implements FactoryBean<UserDao> { |
配置:
1 | <bean id="userDao" class="org.example.factory.UserDaoFactoryBean"/> |
1.5 XML-bean生命周期
- 提供生命周期控制方法,并写好配置文件
1 | public class BookDaoImpl implements BookDao { |
配置:
使用init-method
、destory-method
属性配置
1 | <bean id = "bookDao" name="bookDao2 bookDao3" class="org.example.dao.impl.BookDaoImpl" init-method="init" destroy-method="destory"/> |
- 使用spring提供的接口控制生命周期
实现InitializingBean, DisposableBean接口,实现方法destory()
、afterPropertiesSet()
1 | public class BookServiceImpl implements BookService, InitializingBean, DisposableBean { |
1.6 XML-依赖注入方式(DI)
- setter注入(简单类型,引用类型)
- 简单类型
写好简单类型的set方法
在配置文件中,bean标签中使用property标签,配置property标签的
name
属性(与简单类型相同)与value
属性(要提供的值)
- 引用类型
写好引用类型的set方法
在配置文件中,bean标签中使用property标签,配置property标签的
name
属性(与简单类型相同)与ref
属性(参照bean的名称)
1 | <!-- 简单类型配置--> |
- 构造方法注入(简单类型、引用类型)
- 简单类型
使用构造器传参,在constructor-arg标签中配置name(与构造器形参一致)、value属性
- 引用类型
使用构造器传参,在constructor-arg标签中配置name(与构造器形参一致)、ref属性
1 | <!-- 简单类型配置--> |
解耦合改良:
使用type属性表示形参
使用index属性表示形参
1.7 XML-依赖自动装配(引用类型)
- IoC容器根据bean所依赖的资源在容器中自动查找并注入到bean中的过程称为自动装配
- 自动装配方式
- 按类型(常用)
- 按名称
- 按构造方法
- 不启用自动装配
1 | <bean id = "bookService" class="org.example.service.impl.BookServiceImpl" autowire="byType"> |
1.8 XML-集合注入
集合 | 标签 |
---|---|
array | property嵌array嵌value(ref) |
list | property嵌list嵌value(ref) |
set | property嵌set嵌value(ref) |
map | property嵌map嵌entry |
property | property嵌props嵌prop |
1 | <bean id = "bookDao" name="bookDao2 bookDao3" class="org.example.dao.impl.BookDaoImpl" > |
1.9 XML-管理数据源对象
1 | <!-- 管理DruidDataSource对象--> |
1.9 XML-加载properties文件
- 开启context命名空间
1 | <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" |
2.加载properties文件,多个文件location中用,
隔开
1 | <context:property-placeholder location="jdbc.properties"/> |
常用格式:
1 | <context:property-placeholder location="classpath*:*.properties"/> |
3.使用属性占位符${}读取文件中的属性-
1 | <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"> |
1.10 容器
- 创建容器
- 获取bean
- 容器类层次结构图
2.1 注解开发
- 使用@component定义bean
1 |
|
- 核心配置文件中通过组件扫描加载bean
1 | <context:component-scan base-package="org.example"/> |
component衍生注解
2.2 纯注解开发
使用
@Configuration
注解设置当前类为配置类使用
@ComponentScan
注解设定扫描路径,多个数据用数组格式
1 |
|
- 加载配置类初始化容器
1 | //获取ioc容器 |
2.3 注解开发-bean管理
- bean作用范围
使用@Scope
注解设定某个类
1 |
2.bean生命周期
使用@PostConstruct
注解设定某个类中的方法为构造方法后初始化方法
1 |
|
使用@PreDestory
注解设定某个类中的方法为销毁前方法
1 |
|
2.4 注解开发-依赖注入
- 引用类型:自动装配
使用@Autowired
注解设置引用类型自动装配,默认为按类型装配,
可使用@Qualifier
注解设置按名称装配(要为配装配的类设置称)
1 |
|
- 简单类型
- 使用
@Value
注解为简单类型设置值
1 |
|
使用配置文件导入值,在配置类中添加
@PropertySource(file path)
注解(多个文件使用数组形式,不支持*通配符),再使用
@Value
注解与${}
占位符注入值1
2
3
4
5
public class SpringConfig {
}1
2
private String a;
2.5 注解开发-第三方bean管理、依赖注入
- 第三方bean管理
在配置类中定义一个方法用于获取数据源对象,为该方法添加@Bean
注解
1 | public class SpringConfig { |
获取数据源对象:
1 | public class App |
- 改良:新建单独配置类,在主配置类中使用
@Import(className.Class)
导入该类(导入多个类使用数组形式)
1 | public class JdbcConfig { |
1 |
|
- 依赖注入
- 简单类型
1 |
|
- 引用类型
作为形参会自动装配(按类型)
1 |
|
3. XML与注解开发对比
二、Spring整合
1.1Spring整合MyBatis
- 导入依赖坐标
1 | <dependency> |
- 与sqlsessionFactory有关的配置转换成sqlSessionFactory方法来配置
- mapper映射转换成Mybatis配置类中MapperScannerConfiguer方法
1.2 Spring整合Junit
- 导入依赖坐标
1 | <dependency> <groupId>org.springframework</groupId> |
- 设置类加载器(SpringJunit4ClassRunner),设置spring上下文配置(SpringContext)
1 | //类加载器 |
- 进行测试
1 | public class AccountServiceTest { |
三 AOP
1.1 AOP简介
- AOP(Aspect Oriented Programming) 面向切面编程,一种编程范式 ,指导开发者如何组织程序结构
- 00P(Object 0riented Progr amming)面向对象编程
- 作用:在不惊动原始设计的基础上为其进行功能增强
- Spring理念:无入侵式/无侵入式
核心概念:
- 连接点( JoinPoint ) : 程序执行过程中的任意位置, 粒度为执行方法、抛出异常、设置变量等
- 在SpringAOP中 ,理解为方法的执行
- 切入点( Pointcut ) : 匹配连接点的式子(切入点<连接点)
- 在SpringAOP中 , -个切入点可以只描述一个具体方法,也可以匹配多个方法
- 一个具体方法: com. itheima . dao包下的BookDao接口中的无形参无返回值的save方法
- 匹配多个方法:所有的save方法,所有的get开头的方法,所有以Dao结尾的接口中的任意方法,所有带有-个参数的方法
- 通知( Advice ) : 在切入点处执行的操作,也就是共性功能
- 在SpringAOP中,功能最终以方法的形式呈现
- 通知类:定义通知的类
- 切面( Aspect ) : 描述通知与切入点的对应关系
1.2 AOP入门案例
- 导入Aspect坐标
1 | <dependency> |
写一个通知类,写一个通知,一个切入点
设置切入点的注解,绑定通知与切入点
切入点定义依托一个不具有实际意义的方法进行,即无参数,无返回值, 方法体无实际逻辑(如下的pc方法)
将通知类转为bean,使用
@Aspect
注解让spring将通知类以aop来处理
1 | //4.设置通知类为bean,以便spring管理 |
- 在配置类中打开aop注解开发模式
@EnableAspectJAutoProxy
1 |
|
1.3 AOP工作流程
- 工作流程
- Spring容器启动
- 读取所有切面配置中的切入点
- 初始化bean ,判定bean对应的类中的方法是否匹配到任意切入点
- 匹配失败 ,创建对象
- 匹配成功 ,创建原始对象(目标对象)的代理对象
- 获取bean执行方法
- 获取bean ,调用方法并执行,完成操作
- 核心概念
- 目标对象( Target ) : 原始功能去掉共性功能对应的类产生的对象,这种对象是无法直接完成最终工作的
- 代理( Proxy) :目标对象无法直接完成工作,需要对其进行功能回填 ,通过原始对象的代理对象实现
1.4 AOP切入点表达式
- 语法格式
- 切入点:要进行增强的方法
- 切入点表达式:要进行增强的方法的描述方式
切入点表达式标准格式:动作关键字(访问修饰符 返回值 包名.类/接口名.方法名(参数)异常名)
- 动作关键字:描述切入点的行为动作, 例如execution表示执行到指定切入点
- 访问修饰符: public , private等,可以省略
- 返回值
- 包名
- 类/接口名.
- 方法名
- 参数
- 异常名:方法定义中抛出指定异常,可以省略
- 切入点表达式通配符:
*
:单个独立的任意符号,可以独立出现,也可以作为前缀或者后缀的匹配符出现
..
:多个连续的任意符号,可以独立出现,常用于简化包名与参数的书写
+
:专用于匹配子类类型
- 书写技巧
1.5 AOP通知类型
- AOP通知描述了抽取的共性功能, 根据共性功能抽取的位置不同,最终运行代码时要将其加入到合理的位置
- AOP通知共分为5种类型
- 前置通知
- 后置通知
- 环绕通知(重点)
- 返回后通知(了解)
- 抛出异常后通知 (了解)
- 前置通知
@Before
1 |
|
- 后置通知
@After
1 |
|
- 环绕通知
@Around
无返回值:
1 |
|
有返回值:
1 |
|
注意:
环绕通知必须依赖形参ProceedingJoinPoint才 能实现对原始方法的调用, 进而实现原始方法调用前后同时添加通知
通知中如果未使用ProceedingJoinPoint对原始方法进行调用将跳过原始方法的执行
对原始方法的调用可以不接收返回值 ,通知方法设置成void即可,如果接收返回值,必须设定为Object类型
原始方法的返回值如果是void类型,通知方法的返回值类型可以设置成void ,也可以设置成Object
由于无法预知原始方法运行后是否会抛出异常 ,因此环绕通知方法必须抛出Throwable对象
获取原方法信息:
- Signature对象(执行签名信息)中的方法获取
- getDeclaringType,获取声明类型(接口名)
- getName,获取原方法名称
- getDeclaringType().getName() = getDeclaringTypeName(),获取类型名
1 | Signature signature = pjp.getSignature(); |
- 返回后通知
@AfterReturning
1 |
|
- 抛出异常后通知
@AfterThrowing
1 |
|
1.6 AOP通知获取数据
- 获取参数
- 获取返回值
- 获取异常
1.7 AOP总结
- 切入点
- 通知
- 通知中获取信息
四、Spring事务
1.1 事务简介
- 事务作用:在数据层保障一系列的数据库操作同成功同失败
- Spring事务作用:在数据层或业务层保障一系列的数据库操作同成功同失败