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