首页 > 代码库 > Spring框架之学习总结

Spring框架之学习总结

Spring 框架

是一个分层架构,由 7 定义良好的模块组成。 Spring模块构建在核心容器之上,核心容器定义了创建、配置和管理 bean 的方式

 

组成 Spring 框架的每个模块(或组件)都单独存在,或者与其他一个或多个模块联合实现。

  • 核心容器:核心容器提供 Spring 框架的基本功能。核心容器的主要组件是 BeanFactory,它是工厂模式的实现。BeanFactory 使用控制反转 (IOC模式将应用程序的配置和依赖性规范与实际的应用程序代码分开。
  • Spring MVC 框架:MVC 框架是一个全功能的构建 Web 应用程序的 MVC 实现。

 

Spring

①是一个轻量级的IoCAOP的容器框架,主要是针对JavaBean的生命周期进行管理的轻量级容器,可以单独使用,也可以和Struts框架,ibatis框架等组合使用。

②基本思想:Ioc/DI

                   IoC(inverse of control )控制反转:所谓控制反转就是把创建对象(bean维护对象(bean)之间的关系的权利转移到Sqring容器中去了(ApplicationContext.xml)而程序本身不在维护了

                   DI(dependency injection)依赖注入:实际上DI和IOC是同一个概念,因为在ApplicationContext.xml配置文件中bean和bean之间通过ref来维护的时候是相互依赖的,所以又叫做依赖注入。也就是控制反转。

 

核心机制:java反射机制,知道类名以后,通过反射机制创建该类的对象,注入到相关类中

作用: (在不使用spring框架之前,我们的service层中要使用dao层的对象,不得不在service层中new一个对象。存在的问题:层与层之间的依赖。)

对象的生成原来自己创建 变成 由Spring IoC自动注入降低项目中各组件之间的耦合度(软件设计原则:高内聚 低耦合 (内聚性又称块内联系 耦合性也称块间联系))

Spring是SSH中的管理员,负责管理其它框架,协调各个部分的工作。

Spring带来了复杂的J2EE开发的春天。

 

                                                                                              

1.Bean的定义方式:(注入Bean)

<bean id="hellos1" class="com.sw.test.HelloSpring"></bean>

<bean name="helloByName" class="com.sw.test.HelloSpring"></bean>

<alias alias="helloByAlias" name="helloByName" />

 

2.Bean的获取

 (BeanFactory接口两个重要实现类: 

FileSystemXmlApplicationContext                     [从文件绝对路径加载配置文件] ClassPathXmlApplicationContext  [classpath下加载配置文件(适合于相对路径方式加载)])

        

         得到一个 BeanFactory接口( IoC容器的核心接口) 的对象,通过该对象.getBean()  获取

                                 ↓

                            两个重要实现类(用来加载配置文件,并对所有的Bean实例化):

 

         Ⅰ/   BeanFactory bf1 = new FileSystemXmlApplicationContext("helloSpring.xml"); //从文件绝对路径加载配置文件.此处的文件是 项目下的

                  

         Ⅱ/   BeanFactory bf = new ClassPathXmlApplicationContext("conf/helloSpring.xml");//classpath下加载配置文件(适合于相对路径方式加载)

 

                   HelloSpring helloSpring1 = bf.getBean("hellos1", HelloSpring.class);

 

3.依赖注入(DI)三种方式: 

spring中有三种注入方式,一种是set注入,一种是接口注入,另一种是构造方法注入。

 

①通过属性注入:(set注入)

<bean id="car" class="com.sw.test.Car">

                   <property name="brand">

                            <value>法拉利</value>

                   </property>

                   <property name="price">

                            <value>2000000.0</value>

                   </property>

         </bean>

灵活度最高

②通过构造器注入

<bean id="car2" class="com.sw.test.Car">

                   <constructor-arg type="double" index="2">

                            <value>1000000</value>

                   </constructor-arg>

                   <constructor-arg type="String" index="1">

                            <value>迷你小战士</value>

                   </constructor-arg>

                   <constructor-arg type="String" index="0">

                            <value>BMW</value>

                   </constructor-arg>

         </bean>

 

③通过静态/非静态工厂方法注入

<bean id="car3" class="com.sw.test.CarFactory" factory-method="getCar">

         </bean>

 

1.注入对象

  通过属性注入对象: (要有setter方法)

private IHelloMessage iHelloMessage;(添加setter/getter方法)

 

<bean id="helloWorld" class="com.sw.test.HelloWorld"></bean>

 

<bean id="person" class="com.sw.test.Person">

                   <property name="iHelloMessage" ref="helloWorld"></property>

</bean>

 

通过构造器注入对象:

 

         public Person(IHelloMessage iHelloMessage,CarRun carRun){

                   this.iHelloMessage = iHelloMessage;

                   this.carRun = carRun;

         }

 

         <bean id="person1" class="com.sw.test.Person">

                   <constructor-arg type="IHelloMessage" ref="helloChina"></constructor-arg>

                   <constructor-arg ref="carRun"></constructor-arg>

         </bean>

 

2、Bean的作用域:scope=""

singleton:单例:指一个容器中只存在一个实例

prototype:多个实例:每次请求都会创建一个实例

request:每次Http请求都会创建一个新的实例,并且只在当前request中有效

session:在当前session中有效

global session:一般在整合多个应用时使用

 

3、通过import引入其它配置文件:<import resource="conf-car.xml"/>

 

4、autowire自动装配代替ref

①byName ②byType③constructor ④autodetect 自动检测

 

①byName:通过属性名称与bean的标识相匹配来为它注入相应的bean

<bean id="person2" class="com.sw.test.Person" autowire="byName"></bean>

②byType:通过属性类型与bean的class相匹配来为它注入合适的bean

<bean id="person3" class="com.sw.test.Person" autowire="byType"></bean>

③constructor:通过构造器中定义的类型与bean相匹配

<bean id="person4" class="com.sw.test.Person" autowire="constructor"></bean>

④autodetect

首先按照byType的形式去匹配,如果匹配不到(找不到无参构造器),则会按照constructor的形式去匹配

<bean id="person5" class="com.sw.test.Person" autowire="autodetect"></bean>

 

  spring框架为我们提供了注解功能。     就不用配置<bean>   开发效率高

1,使用注解,需要在配置文件中增加命名空间和约束文件

2,告诉框架那些类是使用注解的。

<context:component-scan base-package="com.lsz.spring" />

 

注解Annotation,是一种类似注释的机制,在代码中添加注解可以在之后某时间使用这些信息。跟注释不同的是,注释是给我们看的,Java虚拟机不会编译,注解也是不编译的,但是我们可以通过反射机制去读取注解中的信息。

 

在没有使用注解时,spring框架的配置文件applicationContext.xml文件中需要配置很多的<bean>标签,用来声明类对象。使用注解,则不必在配置文件中添加标签拉,对应的是在对应类的“注释”位置添加说明。具体介绍如下:

 

   spring框架使用的是分层的注解。

    持久层:@Repository;

    业务层:@Service

控制层:@Controller

 

等价于@Component,可以加在类上为某个class生成bean

 

 

AOP  (Aspect Oriented Programming  面向切面编程):  利用AOP可以对业务逻辑各个部分进行隔离,从而使得业务逻辑各部分之间耦合度降低提高程序的可重用性,同时提高了开发效率

 

主要功能:日志记录,性能统计,安全控制,事务处理,异常处理等等

 

使用流程:①导入AOPjar包  ②定义一个切面的类,将这个类在spring容器中实例化 ③ 注册这个切面 ④ 给这个切面加入切入点⑤切入点方法执行前后 通知 切面的类 执行以下方法

 

切面:

切入点pointcut:

通知:

①before:方法执行前调用

②after-returning:方法返回后调用

③after-throwing:方法有异常时调用

④after(finally:不管方法中有没有异常,该方法一定会执行

 

定义切入点的方式:

 

execution(* com.sw.service.*Service.*(..));

第一个*代表返回值,第二*代表service下子包,第三个*代表方法名,“(..)”代表方法参数。

execution(* com.sw.service.*Service.set*(..));以set开头的方法

execution(* com.sw.service..(..));匹配到com.sw.service包下所有类中的所有方法

execution(* com.sw.service...(..));匹配到com.sw.service包下所有子包

 

 

 

 

Spring管理事务主要运用以下三个接口:

Platform TransactionManager、TransactionDefinition、Transaction Status。

 

PlatformTransactionManager 平台事务管理器

这个接口下包含以下实现类

DataSourceTransactionManager、HibernateTransactionManager、JdoTransactionManager、JpaTransactionManager等

其中常用

I:DataSourceTransactionManager 用来管理jdbc事务以及MyBatis/iBatis事务

II:HibernateTransactionManager 用来管理Hibernate事务

 

TransactionDefinition 事务定义:定义一些事务的信息(包括事务的隔离级别、传播行为、超时、只读)

隔离级别:针对并发选择合适的隔离级别

ISOLATION_DEFAULT:使用数据库默认隔离级别,mysql默认为REPEATABLE_READ,oracle默认为READ_COMMITTED

传播行为

***PROPAGATION_REQUIRED:支持当前事务,如果没有,就新建一个

PROPAGATION_SUPPORTS:支持当前事务,如果没有,就不使用事务

PROPAGATION_MANDATORY:支持当前事务,如果没有,抛出异常

----------------------

**PROPAGATION_REQUIRES_NEW:如果有事务存在,挂起当前事务,创建一个新的事务

PROPAGATION_NOT_SUPPORTED:以非事务方式运行,如果有事务,挂起当前事务

PROPAGATION_NEVER:以非事务方式运行,如果有事务,抛出异常

-----------------------

*PROPAGATION_NESTED:嵌套事务,例如a方法调用b方法,可以在某个位置设置一个保存点,如果b中出现异常需要回滚事务,可以选择回滚到保存点或者初始位置

其它

TIMEOUT_DEFAULT:设置超时时间

 

TransactionStatus 事务的具体运行状态

hasSavepoint():判断是否有保存点

isCompleted():判断是否完成

isNewTransaction():判断是新事务

flush():将缓存(seesion)中的数据保存数据库中

 

 

Spring有两种事务管理方式:①编程式  ②声明式。

编程式的比较灵活,但是代码量大,存在重复的代码比较多;

而声明式事务管理比编程式更灵活方便。

 

编程式事务管理(通过模版transactionTemplate):

需要在代码中显式调用beginTransaction()、commit()、rollback()等事务管理相关的方法<bean     id="transactionTemplate"

class="org.springframework.transaction.support.TransactionTemplate">

               <property name="transactionManager" ref="transactionManager"></property>

</bean>

(引入配置好的事务管理器        transactionManager

I:DataSourceTransactionManager II:HibernateTransactionManager 注入dataSource)

 

声明式事务管理:建立在 AOP 的基础之上的。其本质是对方法前后进行拦截,然后在目标方法开始之前创建或者加入一个事务,在执行完目标方法之后根据执行情况提交或者回滚事务。

①通过TransactionProxyFactoryBean类生成代理来控制事务

I:配置事务管理器

II:配置TransactionProxyFactoryBean

<bean id="accountServiceProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">

<!-- 配置目标bean,即为哪个bean生成代理 -->

<property name="target" ref="accountService"></property> 

<!-- 配置事务管理器 -->

<property name="transactionManager" ref="transactionManager"></property> 

<!-- 主要设置为哪些方法添加事务,以及事务的传播方式、隔离级别等 -->

<property name="transactionAttributes">    

        <props>

    <prop key="transfer">+java.lang.ArithmeticException,PROPAGATION_REQUIRED</prop>

        </props>

    </property>

</bean>

+表示即使抛出该异常事务同样要提交(异常后面的不提交)

- 表示抛出该异常时需要回滚

 

 传播行为 [,隔离级别] [,只读属性] [,超时属性] [不影响提交的异常] [,导致回滚的异常]

 

 

②使用aop切面管理事务

 I:配置事务管理器

II:配置aop

<aop:config>

                   <aop:pointcut expression="execution(* com.sw.spring.transaction.demo3.*Service.*(..))" id="apointcut"/>

                   <aop:advisor advice-ref="txAdvice" pointcut-ref="apointcut"/>

         </aop:config>

         <tx:advice id="txAdvice" transaction-manager="transactionManager">

                   <tx:attributes>

                            <tx:method name="transfer" propagation="REQUIRED"/>

                   </tx:attributes>

         </tx:advice>

 

基于注解的声明式事务管理(主要用这个)            @Transactional

I:配置事务管理器

II:开启注解事务

<tx:annotation-driven transaction-manager="transactionManager"/>

III:在Service上加上注解:@Transactional

 

 

 

 

1、使用spring整合jdbc

①、添加jar包

②、添加关于数据库驱动名及连接名等配置的文件

③、使用c3p0连接池生成dataSource

④、将dataSource注入到dao层的bean

⑤、 在dao层中添加一个JdbcTemplate类型的属性,用来执行sql,该属性需要使用dataSource作为参数来创建对象

 

 

 

2、spring整合Hibernate

 

①xxx.hbm.xml方式:

    <bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">

    <property name="dataSource" ref="dataSource"></property>

    <property name="mappingResources">

         <list>

             <value>com/sw/spring/transaction/demo5/Account.hbm.xml</value>

            

            

            

         </list>

    </property>

    <property name="hibernateProperties">

         <props>

             <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>

             <prop key="hibernate.show_sql">true</prop>

             <prop key="hibernate.format_sql">true</prop>

<prop key="hibernate.hbm2ddl.auto">update</prop>  <!-- create 会删除原先的表 -->

         </props>

    </property>

</bean>

 

②   @Entity注解方式(Hibernate的注解)

    <bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">

    <property name="dataSource" ref="dataSource"></property>

    <property name="packagesToScan"> <!-- packagesToScan的意思是要扫描的“包” -->

         <list>

             <value>com.sw.spring.transaction.*</value>

         </list>

    </property>

    <property name="hibernateProperties">

         <props>

             <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>

             <prop key="hibernate.show_sql">true</prop>

             <prop key="hibernate.format_sql">true</prop>

<prop key="hibernate.hbm2ddl.auto">update</prop>  <!-- create 会删除原先的表 -->

         </props>

    </property>

    </bean>

 

 

配置hibernate事务,使用基于注解的声明式事务管理

   <!-- 配置事务管理器          hibernate事务 -->

    <bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">

    <property name="sessionFactory" ref="sessionFactory"></property>

    </bean>

 

    <!-- 开启注解事务 -->

  <tx:annotation-driven transaction-manager="transactionManager"/>

 

 

使用Spring注解:

1、使用@Autowired自动装配: 可以实现快速的自动注入,而无需在xml文档里面添加bean的声明,大大减少了xml文档的维护。

<bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/>

①默认byType,如果byType找到多个类型,则会按byName寻找

②如果byName找不到,可以加@Qualifier("accountDao01")来指定bean

③注解可以加在属性上,也可以加载set方法上或构造器上

 

2、使用@Resource作用相当于 @Autowired,只不过 @Autowired 按 byType 自动注入,面 @Resource 默认按 byName 自动注入

默认按照byName注入

也可以指定name,如:@Resource(name="accountDao")

 

在配置文件中加入

<bean class="org.springframework.context.annotation.CommonAnnotationBeanPostProcessor"/><!-- @RESOURCE -->

 

3、使用@Component,可以加在类上为某个class生成bean

自动根据bean的类名实例化一个首写字母为小写的bean

也可以使用@Component("accountDao")来为这个bean指定ID

@Service加到Service层的类上,效果同@Component,一般用来生成业务层的bean

@Repository加到Dao层的类上,效果同@Component,一般用来生成持久层的bean

@Controller加到Action层的类上,效果同@Component,一般用来生成控制层的bean

 

 

 

 

操作数据库,可以使用注入session的形式,也可以使用

org.springframework.orm.hibernate4.HibernateTemplate的bean

            <!-- 配置HibernateTemplate -->

    <bean id="hibernateTemplate" class="org.springframework.orm.hibernate4.HibernateTemplate">

        <property name="sessionFactory" ref="sessionFactory"></property>

    </bean>

 

    @Resource

    private HibernateTemplate hibernateTemplate;

 

Session session=hibernateTemplate.getSessionFactory().openSession();

 

 

Spring整合Struts2:

1、添加Struts与Spring固有的必要jar包以及其它相关jar包

2、添加struts-spring-plugins.jar

3、在web容器中添加监听器用来加载applicationContext.xml并生成相应的bean完成注入

Spring框架之学习总结