Spring3
一.自动注入
1.在 Spring 配置文件中对象名和 ref="id" id名相同使用自动注入,可以不配置<property/>
2.两种配置办法
1)在<bean>中通过 autowire="" 配置,只对这个<bean>生效
2)在<beans>中通过 default-autowire="" 配置,表示当前文件中所有<bean>都是全局配置内容
3.autowire="" 可取值
1)default: 默认值,根据全局 default-autowire="" 值.默认全局和局部都没有配置情况下,相当于 no
2)no: 不自动注入
3)byName: 通过名称自动注入.在 Spring 容器中找类的 id
4)byType: 根据类型注入.
spring 容器中不可以出现两个相同类型的<bean>
5)constructor: 根据构造方法注入.
提供对应参数的构造方法(构造方法参数中包含注入对象)
底层使用 byName, 构造方法参数名和其他<bean>的 id相同.
二. Spring 加载 properties 文件
1. 在 src 下新建 xxx.properties 文件
2. 在 spring 配置文件中先引入 xmlns:context,在下面添加
1)如果需要记载多个配置文件逗号分割
<context:property-placeholder location="classpath:db.properties,classpath:second.properties"/>
3. 添加了属性文件记载,并且在<beans>中开启自动注入注意的地方
1)SqlSessionFactoryBean 的 id 不能叫做 sqlSessionFactory
2)修改
把原来通过ref引用替换成value赋值,自动注入只能影响ref,不会影响 value 赋值
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="com.su.mapper"></property> <property name="sqlSessionFactoryBeanName" value="factory"></property>
</bean>
4. 在被Spring管理的类中通过@Value(“${key}”)取出properties中内容
1)配置properties文件
my.demo=hello
2)在spring配置文件中添加注解扫描
<context:component-scan base-package="com.su.service.impl"></context:component-scan>
3)在类中添加
key 和变量名可以不相同
变量类型任意,只要保证 key 对应的 value 能转换成这个类型就可以.
@Value("${my.demo}") private String test;
三.scope 属性
1. <bean>的属性
2. 作用:控制对象有效范围(单例,多例等)
3. <bean/>标签对应的对象默认是单例的.
无论获取多少次,都是同一个对象
<bean id="teacher" class="com.su.test.Teacher" scope="singleton"></bean>
4. scope 可取值
1)singleton 默认值,单例
2)prototype 多例,每次获取重新实例化
3)request 每次请求重新实例化
4)session 每个会话对象内,对象是单例的.
5)application 在 application 对象内是单例
6)global session spring推出的一个对象 , 依赖于spring-webmvc-portlet包,类似于 session
四. 声明式事务
1.编程式事务:
1)由程序员编程事务控制代码.
2)OpenSessionInView 编程式事务
2.声明式事务:
事务控制代码已经由 spring 写好.程序员只需要声明出哪些方法需要进行事务控制和如何进行事务控制.
3.声明式事务都是针对于 ServiceImpl 类下方法的.
4.事务管理器基于通知(advice)的.
5.在 spring 配置文件中配置声明式事务
<context:property-placeholder location="classpath:db.properties,classpath:second.properties"/> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="${jdbc.driver}"></property> <property name="url" value="${jdbc.url}"></property> <property name="username" value="${jdbc.username}"></property> <property name="password" value="${jdbc.password}"></property> </bean> <!-- spring-jdbc.jar 中 --> <bean id="txManager" class="org.springframework.jdbc.datasource.DataSour ceTransactionManager"> <property name="dataSource" ref="dataSource"></property> </bean> <!-- 配置声明式事务 --> <tx:advice id="txAdvice" transaction-manager="txManager"> <tx:attributes> <!-- 哪些方法需要有事务控制 --> <!-- 方法以 ins 开头事务管理 --> <tx:method name="ins*" /> <tx:method name="del*" /> <tx:method name="upd*" /> <tx:method name="*" /> </tx:attributes> </tx:advice> <aop:config> <!-- 切点范围设置大一些 --> <aop:pointcut expression="execution(* com.su.service.impl.*.*(..))" id="mypoint" /> <aop:advisor advice-ref="txAdvice" pointcut-ref="mypoint" /> </aop:config>
五.声明式事务中属性解释
1. name="" 哪些方法需要有事务控制
支持*通配符
2. read-only=”boolean” 是否是只读事务.
1)如果为 true,告诉数据库此事务为只读事务.数据化优化,会对性能有一定提升,所以只要是查询的方法,建议使用此数据.
2)如果为 false(默认值),事务需要提交的事务.建议新增,删除,修改.
<tx:method name="*" read-only="true"/>
3. propagation 控制事务传播行为.
当一个具有事务控制的方法被另一个有事务控制的方法调用后,需要如何管理事务(新建事务?在事务中执行?把事务挂起?报异常?)
1)REQUIRED(默认值): 如果当前有事务,就在事务中执行,如果当前没有事务,新建一个事务.
2)SUPPORTS:如果当前有事务就在事务中执行,如果当前没有事务,就在非事务状态下执行.
3)MANDATORY:必须在事务内部执行,如果当前有事务,就在事务中执行,如果没有事务,报错.
4)REQUIRES_NEW:必须在事务中执行,如果当前没有事务,新建事务,如果当前有事务,把当前事务挂起.
5)NOT_SUPPORTED:必须在非事务下执行,如果当前没有事务,正常执行,如果当前有事务,把当前事务挂起.
6)NEVER:必须在非事务状态下执行,如果当前没有事务,正常执行,如果当前有事务,报错.
7)NESTED:必须在事务状态下执行.如果没有事务,新建事务,如果当前有事务,创建一个嵌套事务.
<tx:method name="ins*" propagation="REQUIRED"/>
4. isolation=""事务隔离级别
在多线程或并发访问下如何保证访问到的数据具有完整性.
1、脏读:
一个事务(A)读取到另一个事务(B)中未提交的数据,另一个事务中数据可能进行了改变,此时A事务读取的数据可能和数据库中数据是不一致的,此时认为数据是脏数据,读取脏数据过程叫做脏读。
2、不可重复读:
主要针对的是某行数据.(或行中某列)
主要针对的操作是修改
两次读取在同一个事务内
当事务A第一次读取事务后,事务B对事务A读取的数据进行修改,事务 A 中再次读取的数据和之前读取的数据不一致,过程叫做不可重复读。
3、幻读:
主要针对的操作是新增或删除
两次事务的结果.
事务A按照特定条件查询出结果,事务B新增了一条符合条件的数据.事务 A 中查询的数据和数据库中的数据不一致的,事务 A 好像出现了幻觉,这种情况称为幻读.
4、取值:
1)DEFAULT: 默认值,由底层数据库自动判断应该使用什么隔离级别
2)READ_UNCOMMITTED: 可以读取未提交数据,可能出现脏读、不重复读、幻读。
效率最高.
3)READ_COMMITTED:只能读取其他事务已提交数据.可以防止脏读,可能出现不可重复读和幻读.
4)REPEATABLE_READ: 读取的数据被添加锁,防止其他事务修改此数据,可以防止不可重复读、脏读,可能出现幻读.
5)SERIALIZABLE: 排队操作,对整个表添加锁.一个事务在操作数据时,另一个事务等待事务操作完成后才能操作这个表.
最安全的
效率最低的.
<tx:method name="ins*" isolation="DEFAULT"/>
5. rollback-for=”异常类型全限定路径”
1)当出现什么异常时需要进行回滚
2)建议:给定该属性值.
手动抛异常一定要给该属性值.
<tx:method name="upd*" rollback-for="java.lang.Exception"/>
6. no-rollback-for=””
1)当出现什么异常时不滚回事务
<tx:method name="upd*" no-rollback-for="java.lang.Exception"/>
六. Spring 中常用注解
1. @Component 创建类对象,相当于配置<bean/>
2. @Service 与@Component 功能相同.
写在 ServiceImpl 类上.
3. @Repository 与@Component 功能相同.
写在数据访问层类上.
4. @Controller 与@Component 功能相同.
写在控制器类上.
5. @Resource(不需要写对象的 get/set)
1)java 中的注解
2)默认按照 byName 注入,如果没有名称对象,按照 byType 注入
建议把对象名称和 spring 容器中对象名相同
6. @Autowired(不需要写对象的 get/set)
1)spring 的注解
2)默认按照 byType 注入.
7. @Value() 获取 properties 文件中内容
8. @Pointcut() 定义切点
9. @Aspect() 定义切面类
10. @Before() 前置通知
11. @After 后置通知
12. @AfterReturning 后置通知,必须切点正确执行
13. @AfterThrowing 异常通知
14. @Arround 环绕通知