Spring5 笔记
IOC
Sprint 配置的两种基本注入属性方法
依赖 bean 对象中的 set 方法进行属性的注入:
1 | <bean id="book" class="pers.uang.pojo.Book"> |
依赖 bean 对象的有参构造器进行属性的注入:
1 | <bean id="book" class="pers.uang.pojo.Book"> |
在 construtor-arg
中还有 index
属性,可用通过索引来对构造器中对应位置上的参数进行属性注入:
1 | <bean id="book" class="pers.uang.pojo.Book"> |
p
名称空间注入(了解)
首先添加在配置文件中 beans 标签添加 xmlns:p = "http://www.springframework.org/schema/p"
:
1 | <bean id="book" class="pers.uang.pojo.Book" p:name="人间失格" p:author="太宰治"></bean> |
注意:这个方法的底层还是使用 set 方法进行属性的注入
Xml 配置注入其他类型的属性
字面量
Null 值,使用
<null />
标签1
2
3
4
5
6
7
8<bean id="book" class="pers.uang.pojo.Book">
<constructor-arg name="name">
<null />
</constructor-arg>
<constructor-arg name="author">
<null />
</constructor-arg>
</bean>属性值包含其他特殊符号
1
2
3
4
5
6
7
8
9
10
11
12<!-- 使用转义字符 -->
<bean id="book" class="pers.uang.pojo.Book">
<constructor-arg name="name" value="<人间失格>"></constructor-arg>
<constructor-arg name="author" value="太宰治"></constructor-arg>
</bean>
<!-- 使用 CDATA 方法-->
<bean id="book" class="pers.uang.pojo.Book">
<constructor-arg name="name">
<value><![CDATA[<太宰治>]]></value>
</constructor-arg>
<constructor-arg name="author" value="太宰治"></constructor-arg>
</bean>
注入 Bean 对象属性
外部 Bean
1
2
3
4
5<!-- 向 bookService 中通过外部 Bean 方法注入属性对象-->
<bean name="bookService" class="pers.uang.service.BookService">
<property name="bookDAO" ref="bookDAOImpl"></property>
</bean>
<bean name="bookDAOImpl" class="pers.uang.dao.BookDAOImpl"></bean>内部 Bean
1
2
3
4
5
6
7
8
9
10
11<!-- 内嵌 Bean 对象,内部 Bean 方法注入属性对象 -->
<bean id="employee" class="pers.uang.pojo.Employee">
<property name="e_name" value="太宰治"></property>
<property name="sex" value="男"></property>
<property name="department">
<bean id="department" class="pers.uang.pojo.Department">
<property name="d_name" value="安保部"></property>
<property name="id" value="1"></property>
</bean>
</property>
</bean>级联赋值
方式一:
1
2
3
4
5
6
7
8
9<bean id="employee" class="pers.uang.pojo.Employee">
<property name="e_name" value="太宰治"></property>
<property name="sex" value="男"></property>
<property name="department" ref="dept"></property>
</bean>
<bean id="dept" class="pers.uang.pojo.Department">
<property name="id" value="1"></property>
<property name="d_name" value="技术部"></property>
</bean>方式二:
1
2
3
4
5
6
7
8<bean id="employee" class="pers.uang.pojo.Employee">
<property name="e_name" value="太宰治"></property>
<property name="sex" value="男"></property>
<property name="department" ref="dept"></property>
<property name="department.d_name" value="安保部"></property>
<property name="department.id" value="110"></property>
</bean>
<bean id="dept" class="pers.uang.pojo.Department"></bean>
注入集合类型属性
注入数组类型属性
1
2
3
4
5
6<property name="course">
<array>
<value>Java</value>
<value>Python</value>
</array>
</property>注入 List 集合类型属性
1
2
3
4
5
6<property name="hobbys">
<list>
<value>打篮球</value>
<value>跑步</value>
</list>
</property>注入 Map 集合类型属性
1
2
3
4
5
6<property name="program">
<map>
<entry key="JAVA" value="java"></entry>
<entry key="PYTHON" value="python"></entry>
</map>
</property>注入 Set 集合类型属性
1
2
3
4
5
6<property name="cities">
<set>
<value>C++</value>
<value>JavaScript</value>
</set>
</property>
在集合中设置对象类型的值
方式一:
1 | <bean id="person" class="pers.uang.pojo.Person"> |
方式二:
1 | <bean id="person" class="pers.uang.pojo.Person"> |
将集合注入部分提取成公共部分
1 | <util:list id="DBList"> |
在 Spring 里可以设置 Bean 实例是单实例或者多实例,默认情况下创建的 Bean 是单实例对象。
组件扫描过滤器配置
1 | <!-- 下面 xml 表示只扫描包含注解为 org.springframework.stereotype 包下的 Controller --> |
IOC Bean 注解
Bean 标注注解
- @Component :组件通用注解,常用于 Model 类
- @Controller :常用于对 Controller 实现类进行标注
- @Service:常用于对 Service 实现类进行标注
- @Repository:常用于对 DAO 实现类进行标注
Bean 属性注入注解
- @Value :注入普通类型属性
- @Resource :注入对象类型
- @Autowired :注入对象类型,默认按照类型注入。结合 @Qualifier 注解完成按名称的注入。
Bean 作用范围注解
- @Scope :在类上添加的,控制类生成的时候采用单例还是多例
- singleton :单例
- prototype :多例
- request :request域,需要在web环境
- session :session域,需要在web环境
- application: context域,需要在web环境
- globalsession 集群环境的session域,需要在web环境
Bean 生命周期注解
@PostConstruct :相当于init-method
@PreDestroy :相当于destroy-method
Aop
Aop 指面向切面, 不改变源代码达到增强代码功能的技术
使用 JDK 动态代理增强方法步骤
- 创建接口, 定义方法
- 创建接口实现类, 实现接口方法
- 创建代理类对象, 实现 InvocationHandler 接口, 创建代理对象, 实现 invoke 增强方法
Aop 术语
连接点
指的是被一个类中可以被增强的所有方法, 这些方法被称为连接点
切入点
是指实际上真正被增强的那些方法称为切入点
通知(增强)
实际增强的逻辑部分被称为通知 (增强)
具体可分为多种类型:
前置通知
后置通知
环绕通知
异常通知
最终通知
当上方全部通知都存在时, 执行顺序是: 环绕前 > 前置通知 > 原方法 > 环绕后 > 最终通知 > 后置通知
切面
将通知应用到切入点的过程被称为切面
Aop 操作前的准备
Spring 框架一般基于 AspectJ 实现 AOP 操作
AspectJ 部署 Spring 的组成部分, 是个独立的 AOP 框架, 一般将 AspectJ 和 Spring 框架一起使用, 进行 AOP 操作
基于 AspectJ 实现 Aop 操作
方法1: 基于 xml 配置文件实现
- 创建两个类,增强类和被增强类, 定义方法
- 在 spring 配置文件中创建两个类对象
- 在 spring 配置文件中配置切入点
方法2: 基于注解方式实现 (使用)
- 在 Spring 配置文件中开启注解扫描
- 使用注解创建 User 类 和 UserProxy 对象
- 在增强类上面加上注解 @Aspect
- 在 Spring 配置文件中开启生成代理对象
- 也可以通过创建配置类实现完全注解开发:
- @Configuration: 配置类注解, 加上此注解表示此类为配置类
- ComponentScan(basePackages = {“路径”}): 开启注解扫描, basePackages 设置扫描路径
- EnableAspectJAutoProxy(proxyTargetClass = true): 开启 Aspect 生成代理对象
Pointcut 注解可以抽取切入点, 后续的通知注解可以填写 Pointcut 注解后的方法调用起到相同的功能
Order 注解可以设置多个增强类的优先级, 值越小优先级越高
纯注解开发
- 通过 @Configuration 注解设置类为配置类
- 通过 @ComponentScan( basePackages={“路径”}) 注解 开启注解扫描
- 在测试调用时, 使用 AnnotationConfigApplicationContext() 来读取配置类的 Class
JdbcTemplate
JdbcTemplate 准备工作
引入 相关 jar 包
在 spring xml 配置文件中配置数据库连接池
1
2
3
4
5
6
7<!-- 配置德鲁伊数据库连接池 -->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" destroy-method="close">
<property name="url" value="${prop.url}"></property>
<property name="username" value="${prop.userName}"></property>
<property name="password" value="${prop.password}"></property>
<property name="driverClassName" value="${prop.driverClass}"></property>
</bean>配置 jdbcTemplate 对象注入 DataSource
1
2
3
4
5<!-- 创建 JdbcTemplate 对象 -->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<!-- 注入 dataSource -->
<property name="dataSource" ref="dataSource"></property>
</bean>创建 servie 、dao 类,将 jdbcTemplate 对象注入到 dao 中
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16// BookDaoImpl.java 源文件
public class BookDaoImpl implements BookDao {
private JdbcTemplate jdbcTemplate;
}
// BookService.java 源文件
public class BookService {
private BookDao bookDao;
}开启注解扫描
1
<context:component-scan base-package="pers.uang.spring5" />
Spring 中的事务管理
事务管理操作两种方式
编程式事务管理 (容易导致代码臃肿)
声明式事务管理(推荐使用)
在 Spring 中使用声明式事务管理,底层使用的是 AOP 原理
基于注解方式(推荐)
在 sprint xml 配置文件中,创建事务管理器
1
2
3
4<!-- 创建事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>开启事务注解(需要引入 tx 名称空间)
1
2<!-- 开启事务注解 -->
<tx:annotation-driven transaction-manager="transactionManager"></tx:annotation-driven>在需要配置事务管理器的 类 或 类方法上使用 @Transactional 注解
- 当对类使用时,表示此类中所有方法都开启了事务管理器
- 当对类中方法使用时,表示此方法开启了事务管理器
Transsactional 注解的参数配置,以及它的作用
propagation:表示事务的传播行为
多事务方法直接进行调用,这个过程中是如何进行管理的
ioslation:事务的隔离级别
多事务操作之间不会产生影响
timeout:超时时间
设置事务在一定时间内未进行提交操作后,就进行回滚操作,默认值为 -1 ,永不超时,单位为秒
readOnly:是否只读
设置 false,表示可以进行增、删、改、查操作,反之只能进行 查 操作,即 true 则设置为只读
rollbackFor:回滚
设置出现哪些异常进行事务的回滚
noRollbackFor:不回滚
设置出现哪些异常不进行事务的回滚
基于 xml 配置文件方式
配置事务管理器
1
2
3<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>配置通知
1
2
3
4
5
6
7<tx:advice id="txadvice">
<tx:attributes>
<!-- 指定按哪种规则的方法上添加事务 -->
<tx:method name="accountMoney"/>
<!-- <tx:method name="account*"/> -->
</tx:attributes>
</tx:advice>配置切入点、切面
1
2
3
4
5<!-- 配置切入点和切面 -->
<aop:config>
<aop:pointcut id="pt" expression="execution(* pers.uang.spring5.service.BookService.*(..))" />
<aop:advisor advice-ref="txadvice" pointcut-ref="pt" />
</aop:config>
完全注解声明式事务管理
创建配置类,使用配置类替代 xml 配置文件