Spring 是什么:
spring 是一个开源框架,也是轻量级的
基于控制反转(Inversion of Control,IOc)和面向切面
(Aspect Oriented Programming,AOP)的容器框架
主要目的是简化企业的开发。
为什么要使用Spring
1.降低组件之间的耦合度,是各层间松耦
2.可以使用容器提供的众多服务:如事务管理服务,消息服务
3,非侵入性,对Spring API的依赖减少到最低。
4,AOP技术,很容易实现如权限拦截,日志管理,运行期间监控等功能
5,提供众多的辅助类,加快应用的开发:如jdbcTemplate,Hibernatetemplate
6,对主流的框架提供集成支持,如:JDBC,Hibernate,Struts等,更便于开发。
控制反转:
所谓控制反转就是应用本身不负责依赖对象的创建,依赖对象的
创建及维护是由外部容器负责的
这样控制权就由应用转移到了外部容器,控制权的转移就是所谓的反转。
public class PersonServiceBean {
private PersonDao personDao = new PersonDaoBean();
public void save(Person person){
personDao.save(person);
}
}
PersonDaoBean 是在应用内部创建及维护的。
依赖注入(Dependency Injection)
当我们把依赖对象交给外部容器负责创建,那么PersonServiceBean 类可以改成如下:
public class PersonServiceBean {
private PersonDao personDao ;
//通过构造器参数,让容器把创建好的依赖对象注入进PersonServiceBean,当然也可以使用setter方法进行注入。
public PersonServiceBean(PersonDao personDao){
this.personDao=personDao;
}
public void save(Person person){
personDao.save(person);
}
}
所谓依赖注入就是指:在运行期,由外部容器动态地将依赖对象注入到组件中。(这里通过构造器注入personDao )
配置文件的取名可以任意,文件可以存放在任何目录下,但考虑到通用性,一般放在类路径下。
实例化spring容器:
实例化Spring容器常用的两种方式:
方法一:
在类路径下寻找配置文件来实例化容器
ApplicationContext ctx = new ClassPathXmlApplicationContext(new String[]{"beans.xml"});
方法二:
在文件系统路径下寻找配置文件来实例化容器
ApplicationContext ctx = new FileSystemXmlApplicationContext(new String[]{“d:\\beans.xml“});
Spring的配置文件可以指定多个,可以通过String数组传入。
从spring容器中得到bean
当spring容器启动后,因为spring容器可以管理bean对象的创建,销毁等生命周期,所以我们只需从容器直接获取Bean对象就行,而不用编写一句代码来创建bean对象。从容器获取bean对象的代码如下:
ApplicationContext ctx = new ClassPathXmlApplicationContext(“beans.xml”);
OrderService service = (OrderService)ctx.getBean("personService");
getBean()参数可以指定id属性,也可以指定name属性。
id通常为有效的标识符。id="personServiceBean"
name可以为非标识符。 name="person.server#bean“
无论按照id属性还是name属性找到即可
实例化bean的三种方式:
1.使用类构造器实例化
<bean id=“orderService" class="cn.itcast.OrderServiceBean"/>
2.使用静态工厂方法实例化
<bean id="personService" class="cn.itcast.service.OrderFactory" factory-method="createOrder"/>
public class OrderFactory {
public static OrderServiceBean createOrder(){
return new OrderServiceBean();
}
}
3.使用实例工厂方法实例化:
<bean id="personServiceFactory" class="cn.itcast.service.OrderFactory"/>
<bean id="personService" factory-bean="personServiceFactory" factory-method="createOrder"/>
public class OrderFactory {
public OrderServiceBean createOrder(){
return new OrderServiceBean();
}
}
bean的作用域:
.singleton
在每个Spring IoC容器中一个bean定义只有一个对象实例。(缺省设置为singleton)
<bean id="personServiceBean" class="cn.itcast.service.impl.PersonServiceBean"
prototype
每次从容器获取bean都是新的对象。
根据经验,对有状态的bean应该使用prototype作用域,
而对无状态的bean则应该使用singleton作用域 scope="singleton"/>
.request
表示该针对每一次HTTP请求都会产生一个新的bean,同时该bean仅在当前HTTP request内有效
.session
表示该针对每一次HTTP请求都会产生一个新的bean,同时该bean仅在当前HTTP session内有效
.globalSession
不过它仅仅在基于portlet的web应用中才有意义。Portlet规范定义了全局Session
的概念,它被所有构成某个portlet web应用的各种不同的portlet所共享。
以上3种均基于web的Spring ApplicationContext情形下有效,了解
bean.xml 配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd" >
<!-- 使用类的构造器的方法实例化bean -->
<bean id="personService" class="com.briup.serviceimpl.PersonServiceBean" scope="prototype"></bean>
<!--
<bean id="personDao" class="com.briup.daoimpl.PersonDaoBean"></bean>-->
<!-- 默认情况下,就是在没有指定scope作用域范围的时候,bean的初始化是在spring容器启动的时候,但当你指定scope
的范围为prototype是在获取bean实例的时候才对bean进行实例化,但对于默认的情况我们也可以用lazy-init="true"这个
属性延迟其实例化的时间,在获取bean的时候才对其进行实例化,当我们要对所有的bean进行这个操作的时候,我们可以为根标签
beans指定default-lazy-init="true"但要是在bean里面重设的话,会按bean的处理,
可以用init-method="init"指定实例bean 的初始化方法,用destroy-method="destory"指定销毁是调用的方法。
先实例化,然后再对实例化bean 进行初始化。
-->
<bean id="personService4" class="com.briup.serviceimpl.PersonServiceBean" lazy-init="true" init-method="init"
destroy-method="destory">
</bean>
<!-- 使用静态工厂的方法实例化bean -->
<bean id="personService2" class="com.briup.serviceimpl.PersonServletBeanFactory" factory-method="createPersonServiceBean">
</bean>
<!--使用实例工厂来实例化bean -->
<bean id="personServiceFactory2" class="com.briup.serviceimpl.PersonServletBeanFactory2"></bean>
<!-- scope 指定bean的作用于范围,默认是singleton,也就是单例模式的,有五种范围。prototype(原型)每次都是新的bean,
还有request,session,global session作用范围 -->
<bean id="personService3" factory-bean="personServiceFactory2" factory-method="createPersonServiceBean2" scope="prototype">
</bean>
<!-- 使用seter方法为属性注入值,
1.首先要配置要注入的属性的bean
2.在要注入属性的bean中配置property,然后用ref引用属性的bean
-->
<bean id="personDao" class="com.briup.daoimpl.PersonDaoBean"></bean>
<bean id="personService5" class="com.briup.serviceimpl.PersonServiceBean" >
<property name="personDao" ref="personDao"></property>
</bean>
<!-- 使用内部bean的方式为属性注入值,但和上面的区别是内部bean就不能被其他的bean所使用了既然
不能为其他的bean所使用,所有也就没有必要为其配id属性了 -->
<bean id="personService6" class="com.briup.serviceimpl.PersonServiceBean" >
<property name="personDao" >
<bean class="com.briup.daoimpl.PersonDaoBean"></bean>
</property>
</bean>
<!-- 为基本类型普通的属性注入值 -->
<bean id="personDao1" class="com.briup.daoimpl.PersonDaoBean"></bean>
<bean id="personService7" class="com.briup.serviceimpl.PersonServiceBean" >
<property name="personDao" ref="personDao1"></property>
<property name="name" value="wukaifeng"></property>
<property name="id" value="88"></property>
</bean>
<!-- 为集合类型的属性注入值 -->
<bean id="personService8" class="com.briup.serviceimpl.PersonServiceBean" >
<property name="list">
<list>
<value>list1</value>
<value>list2</value>
<value>list3</value>
<value>list4</value>
</list>
</property>
<property name="map">
<map>
<entry key="map1" value="map1"/>
<entry key="map2" value="map2"/>
<entry key="map3" value="map3"/>
<entry key="map4" value="map4"/>
</map>
</property>
<property name="set">
<set>
<value>set1</value>
<value>set2</value>
<value>set3</value>
<value>set4</value>
</set>
</property>
<property name="properties">
<props>
<prop key="p1" >p1</prop>
<prop key="p2" >p2</prop>
<prop key="p3" >p3</prop>
<prop key="p4" >p4</prop>
</props>
</property>
</bean>
<!-- 使用构造器为属性传入值 -->
<bean id="personService9" class="com.briup.serviceimpl.PersonServiceBean" >
<constructor-arg index="0" type="com.briup.dao.PersonDao" ref="personDao1"></constructor-arg>
<constructor-arg index="1" value="wukaifeng"></constructor-arg>
</bean>
</beans>
测试代码:
package junit.test;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.briup.service.PersonService;
public class SpringTest {
@Test
public void instanceSpring() {
ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
//使用类的构造器来实例化bean
/*PersonService personService = (PersonService) ctx
.getBean("personService");*/
//使用静态工厂来实例化bean
//PersonService personService = (PersonService) ctx.getBean("personService2");
//使用实例工厂来实例化bean
PersonService personService = (PersonService) ctx
.getBean("personService3");
personService.save();
}
@Test
public void test(){
/* <!-- scope 指定bean的作用于范围,默认是singleton,也就是单例模式的,有五种范围。
* prototype(原型)每次都是新的bean,
还有request,session,global session作用范围 -->*/
ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
PersonService personService = (PersonService) ctx.getBean("personService3");
PersonService personService2 = (PersonService) ctx.getBean("personService3");
//是单例的,scope="singleton"或者是默认的
System.out.println(personService==personService2);//true
//是原型的,scope="prototype"每次都是新的bean。
System.out.println(personService==personService2);//false
}
@Test
public void test1(){
//用AbstractApplicationContext可以调用它的close方法,来正常关闭spring容器。
AbstractApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
PersonService personService2 = (PersonService) ctx.getBean("personService4");
ctx.close();
}
@Test
public void test2(){
//测试用seter方法为属性注入值。
ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
PersonService personService = (PersonService) ctx.getBean("personService5");
personService.save();
}
@Test
public void test3(){
//测试用seter方法为属性注入值。
//2.使用内部bean的方式为属性注入值
ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
PersonService personService = (PersonService) ctx.getBean("personService6");
personService.save();
}
@Test
public void test4(){
//测试用seter方法为属性注入值。
//测试为基本类型的普通的属性注入值。
ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
PersonService personService = (PersonService) ctx.getBean("personService7");
personService.save();
}
@Test
public void test5(){
//测试用seter方法为属性注入值。
//测试为基本类型的普通的属性注入值。
ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
PersonService personService = (PersonService) ctx.getBean("personService8");
for (String s : personService.getList()) {
System.out.println(s);
}
System.out.println("______________________________________");
for (String s : personService.getSet()) {
System.out.println(s);
}
System.out.println("______________________________________");
for (String s : personService.getMap().keySet()) {
System.out.println(s+"="+personService.getMap().get(s));
}
System.out.println("______________________________________");
for (Object s : personService.getProperties().keySet()) {
System.out.println(s+"="+personService.getProperties().get(s));
}
}
@Test
public void test6(){
//测试用构造器为属性注入值
ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
PersonService personService = (PersonService) ctx.getBean("personService9");
personService.save1();
}
}
横切性关注点(的一方面的体现):
1,拦截所有业务方法
2,判断用户是否有权限,有权限就允许他执行业务方法,
没有权限就不允许他执行业务方法。
(这些思考的步骤呢,我们就可以成为横切性关注点)
spring声明式事务的管理:
默认的事务管理:
要是遇到unchecked异常的话,事务就会回滚
要是遇到checked异常的话,事务就不会回滚
我们也可以通过设置来改变这种状态的。
事务(Transaction)以及事务的特点
事务是组合在一块的多个操作,这多个操作表现像一个不可分割的原子操作,要么同时成功,
要么同时失败。通过事务确保数据的完整性。
特点(ACID):
1) 原子性(atomicity): 多个操作组合成同时成功,同时失败的原子操作。
2) 一致性(consistency): 事务前后数据一致。例从张三转一百元至李四账户,转账前二帐户总和为2000,转账结束后二帐户总和亦要为2000。
3) 隔离性(isolation): 并发访问的事务进行过程中的状态不为其它事
务所察看
4) 持久性(durability): 事务结束后要将事务进行过程中的状态进行
持久保存入数据库,保证下次来电后依然可以找寻得到。
五种分类
sql的五大分类:
Data retrieval:数据查询
select
DML:数据操纵语言(行级操作语言):操作的是表格当中一条一条的数据
insert update delete
DDL:数据定义语言(表级操作语言):操作的内容为表格(对象)
create alter drop truncate rename
transaction control:事务控制
commit rollback savepoint
DCL:数据控制语言
grant revoke
5、事务边界的声明
事务开始边界的声明:
1)通过SQL*PLUS接入Oracle,即开始了一个 事务;
2)一个事务的结束也意味着另一个事务的开始。
事务结束边界的声明:
1) 正常结束: commit
a) 数据改变写入数据库;
b) 之前数据永久丢失;
c) 所有用户均可看到改变后的结果;
d) 作用于记录上的锁丢失,其它用户可对这些记录进行更
新操作
e) 所有的回滚点擦除。
注: DDL和DCL命令的执行(自动提交),DML不会自动提交,
正常退出会自动提交
2) 异常回滚: rollback
a) 事务进行过程中的状态丢失;
b) 恢复到事务开始前的状态;
c) 作用于记录上的锁丢失,其它用户可对这些记录进行更
新操作;
注: 系统失败或非正常地终止SQL*Plus,将会自动回滚
3) 回滚到特定位置:
a) 通过命令savepoint a设置回滚点a;
b) 通过命令rollback to a回退到a位置;
isolation 事务隔离级别:
read-uncommitted不提交也能读
read-committed提交之后才能读,解决了脏读
repeatable-read 解决了脏读和不可重复读
serializable 三个问题都解决了
级别越高,解决的问题越多但是效率越低。
注意:并不是所有数据库都支持者四种事务隔离级别
比如:oracle就只支持第二种和第四章这两种,比如:
mysql就四种全支持。
oracle默认的事务隔离级别是第二种。
事务以及事务所引发的问题:
1,脏读:一个事务读到另一个事务中修改过但还没有提交的数据。
2,不可重复读:一个事务在第一次读数据和第二次读数据之间,有另一个事务把这个数据更改并提交了,
导致一个事务里面就
读同一个数据两次,读的数据是不同的。
××××脏读和不可重复读,针对的是update,,幻读是针对的delete和insert×××
3,幻读 主要是针对的是insert/delete操作,事务A第一次用where条件筛选出了10条数据,事务A用同样的where条件
筛选却是12条数据,因为事务B在事务A的第一次和第二次查询直接进行了插入操作,并且插入的这个数据满足
事务\A的where筛选。
spring 是一个开源框架,也是轻量级的
基于控制反转(Inversion of Control,IOc)和面向切面
(Aspect Oriented Programming,AOP)的容器框架
主要目的是简化企业的开发。
为什么要使用Spring
1.降低组件之间的耦合度,是各层间松耦
2.可以使用容器提供的众多服务:如事务管理服务,消息服务
3,非侵入性,对Spring API的依赖减少到最低。
4,AOP技术,很容易实现如权限拦截,日志管理,运行期间监控等功能
5,提供众多的辅助类,加快应用的开发:如jdbcTemplate,Hibernatetemplate
6,对主流的框架提供集成支持,如:JDBC,Hibernate,Struts等,更便于开发。
控制反转:
所谓控制反转就是应用本身不负责依赖对象的创建,依赖对象的
创建及维护是由外部容器负责的
这样控制权就由应用转移到了外部容器,控制权的转移就是所谓的反转。
public class PersonServiceBean {
private PersonDao personDao = new PersonDaoBean();
public void save(Person person){
personDao.save(person);
}
}
PersonDaoBean 是在应用内部创建及维护的。
依赖注入(Dependency Injection)
当我们把依赖对象交给外部容器负责创建,那么PersonServiceBean 类可以改成如下:
public class PersonServiceBean {
private PersonDao personDao ;
//通过构造器参数,让容器把创建好的依赖对象注入进PersonServiceBean,当然也可以使用setter方法进行注入。
public PersonServiceBean(PersonDao personDao){
this.personDao=personDao;
}
public void save(Person person){
personDao.save(person);
}
}
所谓依赖注入就是指:在运行期,由外部容器动态地将依赖对象注入到组件中。(这里通过构造器注入personDao )
配置文件的取名可以任意,文件可以存放在任何目录下,但考虑到通用性,一般放在类路径下。
实例化spring容器:
实例化Spring容器常用的两种方式:
方法一:
在类路径下寻找配置文件来实例化容器
ApplicationContext ctx = new ClassPathXmlApplicationContext(new String[]{"beans.xml"});
方法二:
在文件系统路径下寻找配置文件来实例化容器
ApplicationContext ctx = new FileSystemXmlApplicationContext(new String[]{“d:\\beans.xml“});
Spring的配置文件可以指定多个,可以通过String数组传入。
从spring容器中得到bean
当spring容器启动后,因为spring容器可以管理bean对象的创建,销毁等生命周期,所以我们只需从容器直接获取Bean对象就行,而不用编写一句代码来创建bean对象。从容器获取bean对象的代码如下:
ApplicationContext ctx = new ClassPathXmlApplicationContext(“beans.xml”);
OrderService service = (OrderService)ctx.getBean("personService");
getBean()参数可以指定id属性,也可以指定name属性。
id通常为有效的标识符。id="personServiceBean"
name可以为非标识符。 name="person.server#bean“
无论按照id属性还是name属性找到即可
实例化bean的三种方式:
1.使用类构造器实例化
<bean id=“orderService" class="cn.itcast.OrderServiceBean"/>
2.使用静态工厂方法实例化
<bean id="personService" class="cn.itcast.service.OrderFactory" factory-method="createOrder"/>
public class OrderFactory {
public static OrderServiceBean createOrder(){
return new OrderServiceBean();
}
}
3.使用实例工厂方法实例化:
<bean id="personServiceFactory" class="cn.itcast.service.OrderFactory"/>
<bean id="personService" factory-bean="personServiceFactory" factory-method="createOrder"/>
public class OrderFactory {
public OrderServiceBean createOrder(){
return new OrderServiceBean();
}
}
bean的作用域:
.singleton
在每个Spring IoC容器中一个bean定义只有一个对象实例。(缺省设置为singleton)
<bean id="personServiceBean" class="cn.itcast.service.impl.PersonServiceBean"
prototype
每次从容器获取bean都是新的对象。
根据经验,对有状态的bean应该使用prototype作用域,
而对无状态的bean则应该使用singleton作用域 scope="singleton"/>
.request
表示该针对每一次HTTP请求都会产生一个新的bean,同时该bean仅在当前HTTP request内有效
.session
表示该针对每一次HTTP请求都会产生一个新的bean,同时该bean仅在当前HTTP session内有效
.globalSession
不过它仅仅在基于portlet的web应用中才有意义。Portlet规范定义了全局Session
的概念,它被所有构成某个portlet web应用的各种不同的portlet所共享。
以上3种均基于web的Spring ApplicationContext情形下有效,了解
bean.xml 配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd" >
<!-- 使用类的构造器的方法实例化bean -->
<bean id="personService" class="com.briup.serviceimpl.PersonServiceBean" scope="prototype"></bean>
<!--
<bean id="personDao" class="com.briup.daoimpl.PersonDaoBean"></bean>-->
<!-- 默认情况下,就是在没有指定scope作用域范围的时候,bean的初始化是在spring容器启动的时候,但当你指定scope
的范围为prototype是在获取bean实例的时候才对bean进行实例化,但对于默认的情况我们也可以用lazy-init="true"这个
属性延迟其实例化的时间,在获取bean的时候才对其进行实例化,当我们要对所有的bean进行这个操作的时候,我们可以为根标签
beans指定default-lazy-init="true"但要是在bean里面重设的话,会按bean的处理,
可以用init-method="init"指定实例bean 的初始化方法,用destroy-method="destory"指定销毁是调用的方法。
先实例化,然后再对实例化bean 进行初始化。
-->
<bean id="personService4" class="com.briup.serviceimpl.PersonServiceBean" lazy-init="true" init-method="init"
destroy-method="destory">
</bean>
<!-- 使用静态工厂的方法实例化bean -->
<bean id="personService2" class="com.briup.serviceimpl.PersonServletBeanFactory" factory-method="createPersonServiceBean">
</bean>
<!--使用实例工厂来实例化bean -->
<bean id="personServiceFactory2" class="com.briup.serviceimpl.PersonServletBeanFactory2"></bean>
<!-- scope 指定bean的作用于范围,默认是singleton,也就是单例模式的,有五种范围。prototype(原型)每次都是新的bean,
还有request,session,global session作用范围 -->
<bean id="personService3" factory-bean="personServiceFactory2" factory-method="createPersonServiceBean2" scope="prototype">
</bean>
<!-- 使用seter方法为属性注入值,
1.首先要配置要注入的属性的bean
2.在要注入属性的bean中配置property,然后用ref引用属性的bean
-->
<bean id="personDao" class="com.briup.daoimpl.PersonDaoBean"></bean>
<bean id="personService5" class="com.briup.serviceimpl.PersonServiceBean" >
<property name="personDao" ref="personDao"></property>
</bean>
<!-- 使用内部bean的方式为属性注入值,但和上面的区别是内部bean就不能被其他的bean所使用了既然
不能为其他的bean所使用,所有也就没有必要为其配id属性了 -->
<bean id="personService6" class="com.briup.serviceimpl.PersonServiceBean" >
<property name="personDao" >
<bean class="com.briup.daoimpl.PersonDaoBean"></bean>
</property>
</bean>
<!-- 为基本类型普通的属性注入值 -->
<bean id="personDao1" class="com.briup.daoimpl.PersonDaoBean"></bean>
<bean id="personService7" class="com.briup.serviceimpl.PersonServiceBean" >
<property name="personDao" ref="personDao1"></property>
<property name="name" value="wukaifeng"></property>
<property name="id" value="88"></property>
</bean>
<!-- 为集合类型的属性注入值 -->
<bean id="personService8" class="com.briup.serviceimpl.PersonServiceBean" >
<property name="list">
<list>
<value>list1</value>
<value>list2</value>
<value>list3</value>
<value>list4</value>
</list>
</property>
<property name="map">
<map>
<entry key="map1" value="map1"/>
<entry key="map2" value="map2"/>
<entry key="map3" value="map3"/>
<entry key="map4" value="map4"/>
</map>
</property>
<property name="set">
<set>
<value>set1</value>
<value>set2</value>
<value>set3</value>
<value>set4</value>
</set>
</property>
<property name="properties">
<props>
<prop key="p1" >p1</prop>
<prop key="p2" >p2</prop>
<prop key="p3" >p3</prop>
<prop key="p4" >p4</prop>
</props>
</property>
</bean>
<!-- 使用构造器为属性传入值 -->
<bean id="personService9" class="com.briup.serviceimpl.PersonServiceBean" >
<constructor-arg index="0" type="com.briup.dao.PersonDao" ref="personDao1"></constructor-arg>
<constructor-arg index="1" value="wukaifeng"></constructor-arg>
</bean>
</beans>
测试代码:
package junit.test;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.briup.service.PersonService;
public class SpringTest {
@Test
public void instanceSpring() {
ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
//使用类的构造器来实例化bean
/*PersonService personService = (PersonService) ctx
.getBean("personService");*/
//使用静态工厂来实例化bean
//PersonService personService = (PersonService) ctx.getBean("personService2");
//使用实例工厂来实例化bean
PersonService personService = (PersonService) ctx
.getBean("personService3");
personService.save();
}
@Test
public void test(){
/* <!-- scope 指定bean的作用于范围,默认是singleton,也就是单例模式的,有五种范围。
* prototype(原型)每次都是新的bean,
还有request,session,global session作用范围 -->*/
ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
PersonService personService = (PersonService) ctx.getBean("personService3");
PersonService personService2 = (PersonService) ctx.getBean("personService3");
//是单例的,scope="singleton"或者是默认的
System.out.println(personService==personService2);//true
//是原型的,scope="prototype"每次都是新的bean。
System.out.println(personService==personService2);//false
}
@Test
public void test1(){
//用AbstractApplicationContext可以调用它的close方法,来正常关闭spring容器。
AbstractApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
PersonService personService2 = (PersonService) ctx.getBean("personService4");
ctx.close();
}
@Test
public void test2(){
//测试用seter方法为属性注入值。
ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
PersonService personService = (PersonService) ctx.getBean("personService5");
personService.save();
}
@Test
public void test3(){
//测试用seter方法为属性注入值。
//2.使用内部bean的方式为属性注入值
ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
PersonService personService = (PersonService) ctx.getBean("personService6");
personService.save();
}
@Test
public void test4(){
//测试用seter方法为属性注入值。
//测试为基本类型的普通的属性注入值。
ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
PersonService personService = (PersonService) ctx.getBean("personService7");
personService.save();
}
@Test
public void test5(){
//测试用seter方法为属性注入值。
//测试为基本类型的普通的属性注入值。
ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
PersonService personService = (PersonService) ctx.getBean("personService8");
for (String s : personService.getList()) {
System.out.println(s);
}
System.out.println("______________________________________");
for (String s : personService.getSet()) {
System.out.println(s);
}
System.out.println("______________________________________");
for (String s : personService.getMap().keySet()) {
System.out.println(s+"="+personService.getMap().get(s));
}
System.out.println("______________________________________");
for (Object s : personService.getProperties().keySet()) {
System.out.println(s+"="+personService.getProperties().get(s));
}
}
@Test
public void test6(){
//测试用构造器为属性注入值
ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
PersonService personService = (PersonService) ctx.getBean("personService9");
personService.save1();
}
}
横切性关注点(的一方面的体现):
1,拦截所有业务方法
2,判断用户是否有权限,有权限就允许他执行业务方法,
没有权限就不允许他执行业务方法。
(这些思考的步骤呢,我们就可以成为横切性关注点)
spring声明式事务的管理:
默认的事务管理:
要是遇到unchecked异常的话,事务就会回滚
要是遇到checked异常的话,事务就不会回滚
我们也可以通过设置来改变这种状态的。
事务(Transaction)以及事务的特点
事务是组合在一块的多个操作,这多个操作表现像一个不可分割的原子操作,要么同时成功,
要么同时失败。通过事务确保数据的完整性。
特点(ACID):
1) 原子性(atomicity): 多个操作组合成同时成功,同时失败的原子操作。
2) 一致性(consistency): 事务前后数据一致。例从张三转一百元至李四账户,转账前二帐户总和为2000,转账结束后二帐户总和亦要为2000。
3) 隔离性(isolation): 并发访问的事务进行过程中的状态不为其它事
务所察看
4) 持久性(durability): 事务结束后要将事务进行过程中的状态进行
持久保存入数据库,保证下次来电后依然可以找寻得到。
五种分类
sql的五大分类:
Data retrieval:数据查询
select
DML:数据操纵语言(行级操作语言):操作的是表格当中一条一条的数据
insert update delete
DDL:数据定义语言(表级操作语言):操作的内容为表格(对象)
create alter drop truncate rename
transaction control:事务控制
commit rollback savepoint
DCL:数据控制语言
grant revoke
5、事务边界的声明
事务开始边界的声明:
1)通过SQL*PLUS接入Oracle,即开始了一个 事务;
2)一个事务的结束也意味着另一个事务的开始。
事务结束边界的声明:
1) 正常结束: commit
a) 数据改变写入数据库;
b) 之前数据永久丢失;
c) 所有用户均可看到改变后的结果;
d) 作用于记录上的锁丢失,其它用户可对这些记录进行更
新操作
e) 所有的回滚点擦除。
注: DDL和DCL命令的执行(自动提交),DML不会自动提交,
正常退出会自动提交
2) 异常回滚: rollback
a) 事务进行过程中的状态丢失;
b) 恢复到事务开始前的状态;
c) 作用于记录上的锁丢失,其它用户可对这些记录进行更
新操作;
注: 系统失败或非正常地终止SQL*Plus,将会自动回滚
3) 回滚到特定位置:
a) 通过命令savepoint a设置回滚点a;
b) 通过命令rollback to a回退到a位置;
isolation 事务隔离级别:
read-uncommitted不提交也能读
read-committed提交之后才能读,解决了脏读
repeatable-read 解决了脏读和不可重复读
serializable 三个问题都解决了
级别越高,解决的问题越多但是效率越低。
注意:并不是所有数据库都支持者四种事务隔离级别
比如:oracle就只支持第二种和第四章这两种,比如:
mysql就四种全支持。
oracle默认的事务隔离级别是第二种。
事务以及事务所引发的问题:
1,脏读:一个事务读到另一个事务中修改过但还没有提交的数据。
2,不可重复读:一个事务在第一次读数据和第二次读数据之间,有另一个事务把这个数据更改并提交了,
导致一个事务里面就
读同一个数据两次,读的数据是不同的。
××××脏读和不可重复读,针对的是update,,幻读是针对的delete和insert×××
3,幻读 主要是针对的是insert/delete操作,事务A第一次用where条件筛选出了10条数据,事务A用同样的where条件
筛选却是12条数据,因为事务B在事务A的第一次和第二次查询直接进行了插入操作,并且插入的这个数据满足
事务\A的where筛选。