SpringFramework
2021-06-01 19:22:14 2 举报
AI智能生成
包括IOC、AOP、JDBC、TX
作者其他创作
大纲/内容
IOC
XML
1、对象创建
id:唯一标识
class:类全路径
2、依赖注入
setter方法注入
1.依赖属性的setter方法
<property name="name" value="三国志"></property>
<property name="price" value="12.99"></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>
<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>
<bean id="book3" class="ioc.xml.Book" p:name="水浒传" p:price="49.99"></bean>
特殊注入
字面值
null值
<property name="name">
<null/>
</property>
<null/>
</property>
特殊符号
1.<> 转移字符为< >
2. <![CDATA[...]]>
集合
数组
<property name="author">
<array>
<value>Thomas</value>
<value>Ronald</value>
</array>
</property>
<array>
<value>Thomas</value>
<value>Ronald</value>
</array>
</property>
List
<property name="reference>
<list>
<value>数据结构</value>
<value>算法</value>
</list>
</property>
<list>
<value>数据结构</value>
<value>算法</value>
</list>
</property>
Set
<property name="sponsor">
<set>
<value>Microsoft</value>
<value>Orcle</value>
<value>Microsoft</value>
</set>
</property>
<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>
<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>
<value>数据结构与算法</value>
<value>算法导论</value>
</util:list>
set
<util:set id="set">
<value>Microsoft</value>
<value>Oracle</value>
<value>Microsoft</value>
</util: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>
<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的生命周期
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>
</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
String name
3、bean管理
完全注解开发
创建配置类,代替xml配置文件
@Configuration:表明类是一个配置类
proxyBeanMethods = true:代理模式实现,每次从容器中取
proxyBeanMethods = false:配置此类不适用代理模式
@ComponentScan(basePackages = {"ioc.annotation"}):配置包扫描
AOP
动态代理
jdk动态代理
只能应用于接口
1.通过实现InvocationHandler创建自己的调用处理器
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
Object proxy:代理对象
Method method:通过反射获得的接口的方法,调用Object res = method.invoke(obj, args)执行方法,其中obj为指定执行哪个对象的方法,args为参数,res为返回值
2.通过Proxy.newProxyInstance(classLoader, interfaces[], InvocationHandler)来指定类加载器、一组接口和调用处理器来创建动态代理类,动态代理类实现了接口
3.通过反射机制获得动态代理类的构造函数,其唯一参数类型是调用处理器接口类型
4.通过构造函数创建动态代理类实例,构造时调用处理器对象作为参数被传入
cglib动态代理
方法增强(通知)
前置通知
后置通知
环绕通知
异常通知
最终通知
切入点:被增强的方法
切面:把方法应用到切入点过程
切入点表达式:execution([权限修饰符][返回类型][类全路径][方法名称]([参数列表]))
对add方法增强:execution(* aop.annotation.User.add(..))
对所有方法进行增强: execution(* aop.annotation.User.*(..))
对包里面所有类进行增强:execution(* aop.annotation.*.*(..))
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("环绕之后");
}
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")
public void pointDemo() {
}
@Before(value = "pointDemo")
多个增强类在同一个方法上进行增强,设置增强的优先级
@Order(1)
完全注解开发
1、创建配置类:@Configuration
2、开启包扫描:@ComponentScan(basePackages = {"aop.annotation"})
3、开启AOP AspectJ:@EnableAspectJAutoProxy(proxyTargetClass = true)
XML
配置切入点
<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>
<!--切入点-->
<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>
<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
key=value
prop.driverClass=com.mysql.jdbc.Driver
prop.url=jdbc:mysql:localhost:3306/book
prop.userName=root
prop.password=root
prop.url=jdbc:mysql:localhost:3306/book
prop.userName=root
prop.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>
<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
依赖jar包
spring-jdbc
spring-orm
spring-tx
配置JdbcTemplate对象,注入dataSource
<bean id="jdbcTemplate" class="org.springframe.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"></property>
</bean>
<property name="dataSource" ref="dataSource"></property>
</bean>
update方法
插入
String sql = "insert into book values(?,?,?)";
Object args = {book.getId(), book.getName(), book.getPrice()};
int update = jdbcTemplate.update(sql, args);
Object args = {book.getId(), book.getName(), book.getPrice()};
int update = jdbcTemplate.update(sql, args);
删除
String sql = "delete from book where id = ?";
int id = 1;
int delete = jdbcTemplate.update(sql,String.valueof(id));
int id = 1;
int delete = jdbcTemplate.update(sql,String.valueof(id));
queryForObject方法
查询返回某个值
String sql = "select book_name from book where id = 1";
String name = jdbcTemplate.queryForObject(sql, String.class);
String name = jdbcTemplate.queryForObject(sql, String.class);
查询返回对象
String sql = "select * from book where id = ?"
int id = 1;
Book book = jdbcTemplate.queryForObject(sql, new BeanPropertyRowMapper<Book>(Book.class), id);
int id = 1;
Book book = jdbcTemplate.queryForObject(sql, new BeanPropertyRowMapper<Book>(Book.class), id);
查询返回集合
String sql = "select * from book";
List<Book> bookList = jdbcTemplate.query(sql, new BeanPropertyRowMapper<Book>(Book.class));
List<Book> bookList = jdbcTemplate.query(sql, new BeanPropertyRowMapper<Book>(Book.class));
batchUpdate方法
实现批量添加操作
String sql = "insert into book values(?,?,?)";
List<Object[]> batchArgs = new ArrayList<>();
Object[] o1 = {"3", "rust", "12"};
Object[] o2 = {"4", "scale", "13"};
Object[] o3 = {"5", "lua", "14"};
batchArgs.add(o1);
batchArgs.add(o2);
batchArgs.add(o3);
int[] inserts = jdbcTemplate.batchUpdate(sql, batchArgs);
List<Object[]> batchArgs = new ArrayList<>();
Object[] o1 = {"3", "rust", "12"};
Object[] o2 = {"4", "scale", "13"};
Object[] o3 = {"5", "lua", "14"};
batchArgs.add(o1);
batchArgs.add(o2);
batchArgs.add(o3);
int[] inserts = jdbcTemplate.batchUpdate(sql, batchArgs);
实现批量修改操作
String sql = "update book set book_name = ?, price = ? where id = ?";
Object[] o1 = {"rust", "100", "1"};
Object[] o2 = {"scala", "20", "2"};
List<Object[]> batchArgs = new ArrayList<>();
batchArgs.add(o1);
batchArgs.add(o2);
batchArgs.add(o3);
int[] updates = jdbcTemplate.batchUpdate(sql, batchArgs);
Object[] o1 = {"rust", "100", "1"};
Object[] o2 = {"scala", "20", "2"};
List<Object[]> batchArgs = new ArrayList<>();
batchArgs.add(o1);
batchArgs.add(o2);
batchArgs.add(o3);
int[] updates = jdbcTemplate.batchUpdate(sql, batchArgs);
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);
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>
<property name="dataSource" ref="dataSource"></property>
</bean>
在service层添加事务注解
@Transactional
@Transactional
事务传播行为
propagation
propagation
Propagation.REQUIRED
如果当前已经存在事务,则加入该事务;如果不存在则创建一个事务
Propagation.SUPPORTS
如果当前已经有事务执行,则加入该事务,否则,执行空事务,类似于没有事务
Propagation.MANDATORY
当前必须存在一个事务,否则则抛出异常,defaultAutoCommit=true,则sql执行有效;defaultAutoCommit=false执行无效
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>
<bean id="dataTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataDataSource" />
<property name="nestedTransactionAllowed" value="true" />
</bean>
隔离级别
isolation
isolation
事务并发可能出现的情况
脏读
一个事务读到了另一个未提交事务修改过的数据
出现在读未提交
不可重复读
一个事务只能读到另一个已经提交的事务修改过的数据,并且其他事务每对该数据进行一次修改并提交后,该事务都能查询得到最新值。
出现在读未提交、读已提交
幻读
一个事务先根据某些条件查询出一些记录,之后另一个事务又向表中插入了符合这些条件的记录,原先的事务再次按照该条件查询时,能把另一个事务插入的记录也读出来。
出现在读未提交、读已提交、可重复读
读未提交
Isolation.READ_UNCOMMITTED
Isolation.READ_UNCOMMITTED
读已提交
Isolation.READ_COMMITTED
Isolation.READ_COMMITTED
可重复读
Isolation.REPEATABLE_READ
Isolation.REPEATABLE_READ
Isolation.SERIALIZABLE
超时时间
timeout
timeout
是否只读
readOnly
readOnly
回滚
rollbackFor
rollbackFor
不回滚
noRollbackFor
noRollbackFor
0 条评论
下一页