spring 笔记 -spring 的理解

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筛选。





























































































































































































































































































































评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值