首页 > 代码库 > Spring框架之学习总结
Spring框架之学习总结
Spring 框架
是一个分层架构,由 7 个定义良好的模块组成。 Spring模块构建在核心容器之上,核心容器定义了创建、配置和管理 bean 的方式,
组成 Spring 框架的每个模块(或组件)都可以单独存在,或者与其他一个或多个模块联合实现。
- 核心容器:核心容器提供 Spring 框架的基本功能。核心容器的主要组件是 BeanFactory,它是工厂模式的实现。BeanFactory 使用控制反转 (IOC) 模式将应用程序的配置和依赖性规范与实际的应用程序代码分开。
- Spring MVC 框架:MVC 框架是一个全功能的构建 Web 应用程序的 MVC 实现。
Spring
①是一个轻量级的IoC和AOP的容器框架,主要是针对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框架之学习总结