SpringFramework
2021-06-01 19:22:14 2 举报
AI智能生成
包括IOC、AOP、JDBC、TX
作者其他创作
大纲/内容
SpringFramework
IOC
XML
1、对象创建
id:唯一标识
class:类全路径
<bean id=\"book\" class=\"ioc.xml.Book\"></bean>
2、依赖注入
setter方法注入
1.依赖属性的setter方法
<property name=\"name\" value=\"三国志\"></property><property name=\"price\" value=\"12.99\"></property>
有参构造注入
1.依赖于构造函数
2.构造函数要与xml中参数列表匹配,否则会导致匹配不到相同参数列表的构造函数
<constructor-arg name=\"name\" value=\"三国志\"></constructor-arg><constructor-arg name=\"price\" value=\"12.99\"></constructor-arg>
p名称空间注入
1.引入p名称空间
xmlns:p=\"http://www.springframework.org/schema/p\"<bean id=\"book3\" class=\"ioc.xml.Book\" p:name=\"水浒传\" p:price=\"49.99\"></bean>
特殊注入
字面值
null值
<property name=\"name\"> <null/></property>
特殊符号
1.<> 转移字符为< >
2. <![CDATA[...]]>
集合
数组
<property name=\"author\"> <array> <value>Thomas</value> <value>Ronald</value> </array></property>
List
<property name=\"reference> <list> <value>数据结构</value> <value>算法</value> </list></property>
Set
<property name=\"sponsor\"> <set> <value>Microsoft</value> <value>Orcle</value> <value>Microsoft</value> </set></property>
Map
<property name=\"edition\"> <map> <entry key=\"First\" value=\"01/2001\"></entry> <entry key=\"Second\" value=\"05/2010\"></entry> <entry key=\"Third\" value=\"07/2015\"></entry> </map></property>
util名称空间注入
1.引入名称空间util和它的模板xsi:schemaLocation
list
<util:list id=\"list\"> <value>数据结构与算法</value> <value>算法导论</value></util:list>
set
<util:set id=\"set\"> <value>Microsoft</value> <value>Oracle</value> <value>Microsoft</value></util:set>
map
<util:map id=\"map\"> <entry key=\"First\" value=\"01/2001\"></entry> <entry key=\"Second\" value=\"05/2010\"></entry> <entry key=\"Third\" value=\"07/2015\"></entry></util:map>
外部bean
内部bean
级联bean
3、Bean管理
普通bean和工厂bean
bean的作用域
单实例与多实例
默认是单实例
scope属性设置单例还是多例:singleton和prototype
<bean id=\"book\" class=\"ioc.xml.Book\" scope=\"singleton\"></bean>
<bean id=\"book\" class=\"ioc.xml.Book\" scope=\"prototype\"></bean>
单实例在加载配置文件时创建对象;多实例在getBean方法调用是创建多个对象
bean的生命周期
implements BeanPostProcessor
1.通过构造器创建bean实例
2.为bean的属性设置值和对其他bean引用(依赖注入,调用set方法)
3.把bean实例传递bean后置处理器的方法postProcessBeforeInitialization
4.调用bean的初始化方法
<bean id=\"book\" class=\"ioc.xml.Book\" init-method=\"init\"></bean>
5.把bean实例传递bean的后置处理器方法postProcessAfterInitialization
6.bean可以使用了(对象已经获取了)
7.当容器关闭的时候,调用bean的销毁方法(需要进行配置销毁的方法)
<bean id=\"book\" class=\"ioc.xml.Book\" destroy-method=\"destroy\"></bean>
自动装配
autowire
byName:根据属性名称注入,注入值bean的id值和类属性的名称一样
byType:根据类型注入,有且只有一个类型相同的bean
Annotation
1、创建对象
开启组件扫描
<context:component-scan base-package=\"ioc.annotation\"></context:component-scan>
创建对象注解
@Component
基础注解
@Controller
WEB层
@Service
业务层
@Repository
dao层
注解过滤
关闭默认的过滤器
<context:component-scan base-package=\"ioc.annotation\" use-default-filters=\"false\"></context:component-scan>
include-filter
<context:include-filter type=\"annotation\" expression=\"org.springframework.stereotype.Controller/>
exclude-filter
<context:exclude-filter type=\"annotation\" expression=\"org.springframework.stereotype.Controller/>
2、属性注入
@Autowired
required=false:依赖注入时不用强依赖容器中的组件
默认按类型注入,如果存在多个同类型的bean,则报异常
@Qualifier
value = \"beanid\":当容器中存在多个组件时,指定bean id
配合Autowired一起使用
@Resource
可根据类型注入,也可以根据名称注入
@Value
注入普通类型的属性,可以直接注入值
@Value(\"张三\")String name
3、bean管理
完全注解开发
创建配置类,代替xml配置文件
@Configuration:表明类是一个配置类
proxyBeanMethods = true:代理模式实现,每次从容器中取
proxyBeanMethods = false:配置此类不适用代理模式
@ComponentScan(basePackages = {\"ioc.annotation\"}):配置包扫描
AOP
动态代理
jdk动态代理
只能应用于接口
1.通过实现InvocationHandler创建自己的调用处理器
Object proxy:代理对象
3.通过反射机制获得动态代理类的构造函数,其唯一参数类型是调用处理器接口类型
4.通过构造函数创建动态代理类实例,构造时调用处理器对象作为参数被传入
cglib动态代理
方法增强(通知)
前置通知
后置通知
环绕通知
异常通知
最终通知
切入点:被增强的方法
切面:把方法应用到切入点过程
切入点表达式:execution([权限修饰符][返回类型][类全路径][方法名称]([参数列表]))
对add方法增强:execution(* aop.annotation.User.add(..))
对所有方法进行增强: execution(* aop.annotation.User.*(..))
对包里面所有类进行增强:execution(* aop.annotation.*.*(..))
1、开启注解扫描,引入context和aop名称空间
2、使用注解创建对象与代理对象
开启包扫描:<context:component-scan basePackages=\"aop.annotation\"></context:component-scan>
3、在增强类上使用@AspectJ注解
4、在Spring配置文件中开启生成代理对象
开启aop:<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
5、配置通知类型
前置通知@Before(value = execution())
后置通知@AfterReturning(value = execution())
最终通知@After(value = execution())
异常通知@AfterThrowing(value = execution())
环绕通知@Around(value = \"execution()\")
@Around(value = \"execution(* aop.annotation.User.add(..))\")void around(ProceedingJoinPoint proceedingJoinPoint) { System.out.println(\"环绕之前\"); proceedingJoinPoint.proceed(); System.out.println(\"环绕之后\");}
切入点的抽取:
@Pointcut(value = \"execution(* aop.annotation.User.add(..))\")public void pointDemo() {}@Before(value = \"pointDemo\")
多个增强类在同一个方法上进行增强,设置增强的优先级
@Order(1)
1、创建配置类:@Configuration
2、开启包扫描:@ComponentScan(basePackages = {\"aop.annotation\"})
3、开启AOP AspectJ:@EnableAspectJAutoProxy(proxyTargetClass = true)
配置切入点
<aop:config> <!--切入点--> <aop:pointcut id = \"p\" expression=\"execution(* aop.annotation.User.add(..))\"/> <!--切面> <aop:aspect ref=\"UserProxy\"> <!--通知类型--> <aop:before method=\"before\" pointcut-ref=\"p\"/> <aop:aspect><aop:config>
JDBC
druid连接池(mysql为例)
数据库连接池类:com.alibaba.druid.pool.DruidDataSource
Druid连接池属性
driverClassName
url
username
password
创建连接池
<bean id=\"dataSource\" class=\"com.alibaba.druid.pool.DruidDataSource\"> <property name=\"driverClassName\" value=\"com.mysql.jdbc.Driver\"></property> <property name=\"url\" value =\"jdbc:mysql://localhost:3306/root\"></property> <property name=\"username\" value=\"root\"></property> <property name=\"password\" value=\"root\"></property></bean>
依赖jar包
druid
mysql-connector-java
properties配置文件
配置文件格式(以jdbc的DI为例)key=value
prop.driverClass=com.mysql.jdbc.Driverprop.url=jdbc:mysql:localhost:3306/bookprop.userName=rootprop.password=root
把properties属性文件引入到spring配置文件中
引入context名称空间
在spring配置文件中引入外部属性文件
<context:property-placeholder location=\"classpath:jdbc.properties\"/>
使用properties属性文件
<bean id=\"dataSource\" class=\"com.alibaba.druid.pool.DruidDataSource\"> <property name=\"driverClass\" value=\"${prop.driverClass}\"></property> <property name=\"url\" value=\"${prop.url}\"></property> <property name=\"userName\" value=\"${prop.userName}\"></property> <property name=\"password\" value=\"${prop.password}\"></property></bean>
JdbcTemplate
spring-jdbc
spring-orm
spring-tx
配置JdbcTemplate对象,注入dataSource
<bean id=\"jdbcTemplate\" class=\"org.springframe.jdbc.core.JdbcTemplate\"> <property name=\"dataSource\" ref=\"dataSource\"></property></bean>
update方法
插入
String sql = \
删除
String sql = \"delete from book where id = ?\
queryForObject方法
查询返回某个值
String sql = \"select book_name from book where id = 1\
查询返回对象
String sql = \"select * from book where id = ?\
查询返回集合
String sql = \"select * from book\
batchUpdate方法
实现批量添加操作
实现批量修改操作
batchDelete方法
实现批量删除操作
String sql = \"delete from book where id = ?\";List<Object[]> batchArgs = new ArrayList<>();Object[] o1 = {\"3\"};Object[] o2 = {\"4\"};batchArgs.add(o1);batchArgs.add(o2);int[] deletes = jdbcTemplate.batchDelete(batchArgs);
TX
事务的四个特性(ACID)
原子性
一致性
隔离性
持久性
事务的操作过程
1.开启事务
2.进行业务操作
3.没有发生异常,提交事务
4.出现异常,事务回滚
声明式事务管理
引入名称空间
aop
context
tx
开启事务注解
<tx:annotation-driven transaction-manager=\"transactionManager\"></tx:annotation-driven>
创建事务管理器bean
<bean id=\"transactionManager\" class=\"org.springframework.jdbc.datasource.DataSourceTransactionManager\"> <property name=\"dataSource\" ref=\"dataSource\"></property></bean>
在service层添加事务注解@Transactional
事务传播行为propagation
Propagation.REQUIRED
如果当前已经存在事务,则加入该事务;如果不存在则创建一个事务
Propagation.SUPPORTS
如果当前已经有事务执行,则加入该事务,否则,执行空事务,类似于没有事务
Propagation.MANDATORY
Propagation.REQUIERS_NEW
当前的方法必须启动一个新事务,并在这个事务内运行,如果有事务正在运行将它挂起
Propagation.NOT_SUPPORTED
如果当前存在新事务,则挂起当前事务,新的方法在没有事务的环境中运行,此时sql的提交完全依赖于defaultAutoCommit的值
Propagation.NEVER
当前方法不应该运行在事务中,如果有事务,则抛出异常
Propagation.NESTED
如果当前存在事务,则使用 SavePoint 技术把当前事务状态进行保存,然后底层共用一个连接,当NESTED内部出错的时候,自行回滚到 SavePoint这个状态,只要外部捕获到了异常,就可以继续进行外部的事务提交,而不会受到内嵌业务的干扰,但是,如果外部事务抛出了异常,整个大事务都会回滚。
spring配置事务管理器要主动指定 nestedTransactionAllowed=true<bean id=\"dataTransactionManager\" class=\"org.springframework.jdbc.datasource.DataSourceTransactionManager\"> <property name=\"dataSource\" ref=\"dataDataSource\" /> <property name=\"nestedTransactionAllowed\" value=\"true\" /> </bean>
隔离级别isolation
事务并发可能出现的情况
脏读
一个事务读到了另一个未提交事务修改过的数据
出现在读未提交
不可重复读
一个事务只能读到另一个已经提交的事务修改过的数据,并且其他事务每对该数据进行一次修改并提交后,该事务都能查询得到最新值。
出现在读未提交、读已提交
幻读
一个事务先根据某些条件查询出一些记录,之后另一个事务又向表中插入了符合这些条件的记录,原先的事务再次按照该条件查询时,能把另一个事务插入的记录也读出来。
出现在读未提交、读已提交、可重复读
读未提交Isolation.READ_UNCOMMITTED
读已提交Isolation.READ_COMMITTED
可重复读Isolation.REPEATABLE_READ
Isolation.SERIALIZABLE
超时时间timeout
是否只读readOnly
回滚rollbackFor
不回滚noRollbackFor
0 条评论
回复 删除
下一页