一、spring
* 轻量级框架
* 负责管理对象的生命周期
* spring是一个容器
二、spring框架的搭建
* 引入spring的jar ,还需要引入一个公共的commons-logging.jar
* 建议在src根目录下创建一个applicationContext.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-4.1.xsd">
<!-- 通过bean标签进行配置,声明哪些类对象交给spring管理 -->
<bean id="userService" class="com.service.UserService"></bean>
</beans>
* 将引入spring-beans.xsd 增加具体的版本号spring-beans-4.1.xsd
* 默认情况下会根据uri从网络中寻找指定的xsd文件。
* 会寻找到所有版本的xsd,默认使用最高版本。
* 所以建议指定版本。
* 在java中,加载spring框架,并创建spring容器。
* 获得一个spring的BeanFactory对象或者其扩展的子类ApplicationContext对象
BeanFactory factory = new ClassPathXmlApplicationContext("applicationContext.xml") ;
* 从容器中获得指定的bean对象。
UserService service = (UserService) factory.getBean("userService");
三、spring的核心
* IOC Inversion of Control 控制反转
* 以前所有的service(dao,domain)对象在需要使用的时候由我们编程人员通过代码主动创建
* 使用spring之后,将主动权交给spring容器
* 我们在使用时可以通过beanFactory获得或者通过DI实现注入。
* 被动的获得所需要的对象。
* AOP Aspect Oriented Programming 是一种编程模式(思想)
四、DI Dependency injection 依赖注入
* 依赖注入是IOC的一种体现
* 实现方式
* 构造器注入
* 在bean标签中使用<constructor-arg> 指定构造器参数的值。
* 根据标签的位置对应构造器中的参数
* 使用constructor-arg的value属性为参数赋予具体的值。
* 使用constructor-arg的ref属性将spring管理的另一个bean对象作为参数赋值。
<bean id="user" class="com.domain.User">
<constructor-arg value="1002"></constructor-arg>
<constructor-arg value="dmc"></constructor-arg>
<constructor-arg value="123"></constructor-arg>
</bean>
* set方法注入
* 在bean标签中使用<property>子标签为指定的属性赋值
* 通过property的name属性指定为哪个属性赋值,要求与属性名对应(本质是与set方法名对应)
* 通过property的value属性为指定的属性赋予具体的值。
* 通过property的ref属性将spring管理的另一个bean对象作为参数赋值。
<bean id="user2" class="com.domain.User">
<property name="uno" value="1003"></property>
<property name="uname" value="world"></property>
<property name="upass" value="321"></property>
</bean>
* 自动注入
* 自动注入不能赋予简单的值,只能是将spring管理的bean对象作为参数赋值
* 在bean标签通过autowire属性设置开启自动注入
* 基于构造器注入的自动注入,只支持按照类型注入!
<bean id="a" class="com.domain.A"></bean>
<bean id="b" class="com.domain.B"></bean>
<bean id="user" class="com.domain.User" autowire="constructor"></bean>
public User(A a, B b) {
this.a = a;
this.b = b;
}
* 如果有多个构造器可以使用,会默认使用参数匹配最多那个构造器
* 如果有两个子类实现了同一个接口,在自动注入时两个子类都可以使用时,默认谁都不用。
* set方法注入支持byType和byName
* byName 只根据name匹配(set方法名匹配)
<bean id="a" class="com.domain.A"></bean>
<bean id="user2" class="com.domain.User" autowire="byName"></bean>
-----------------------------------------------------
class User{
private A a ;
private A aa ;
}
----------------------------------------------------
a : com.domain.A@324324324
aa : null
* byType 会根据类型匹配,不考虑名字
a : com.domain.A@324324324
aa : com.domain.A@324324324
* 如果找到了2个bean对象符合同一个参数类型,此时抛出异常:
Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException:
No qualifying bean of type [com.domain.C] is defined: expected single matching bean but found 2: c1,c2
五、bean对象的作用域
* 在bean标签中使用scope属性设置bean对象的作用域。
* 默认情况下spring创建的bean对象是单实例。
* singleton 单实例(默认)
* prototype 多实例
* 一般在开发中都建议(struts2)action是多实例的, service和dao一般都建议是单实例的。
六、bean对象的延迟加载
* 通过懒加载可以设置bean对象是在第一次使用时创建还是在加载spring框架时创建。
* 默认是关闭懒加载,启动时就创建。
* 开启懒加载:
* 在bean标签中使用lazy-init=true设置懒加载
* 在beans根标签中设置
<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-4.1.xsd"
default-lazy-init="true"
>
* 如果bean对象是多实例的,一定是注入时再创建。不受懒加载影响。
七、声明式事务
* 需要提供一个公共数据源(连接池)
* dbcp
* c3p0
<bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource">
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"></property>
<property name="url" value="jdbc:oracle:thin:@localhost:1521:orcl"></property>
<property name="username" value="dmc"></property>
<property name="password" value="456"></property>
<property name="minIdle" value="2"></property>
<property name="maxIdle" value="10"></property>
<property name="maxTotal" value="100"></property>
<property name="maxWaitMillis" value="2000"></property>
</bean>
* 需要定义一个事务管理者 (切面)
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
* 需要定义事务管理者的管理策略 (通知)
<tx:advice id="txAdivce" transaction-manager="txManager">
<tx:attributes>
<tx:method name="save*" isolation="SERIALIZABLE" propagation="REQUIRED" rollback-for="java.lang.Throwable" />
<tx:method name="update*" isolation="SERIALIZABLE" propagation="REQUIRED" rollback-for="java.lang.Throwable" />
<tx:method name="delete*" isolation="SERIALIZABLE" propagation="REQUIRED" rollback-for="java.lang.Throwable" />
<tx:method name="find*" read-only="true" />
</tx:attributes>
</tx:advice>
* 什么时间点使用该策略(切入点)
<aop:config>
<aop:advisor advice-ref="txAdivce" pointcut="execution(* com.service.*.*(..))" />
</aop:config>
** 扩展:
* 将数据源的连接信息定义在properties文件中,将其引入到spring的配置文件里
* 在spring的配置文件里使用类似于el的语法${driver}引用properties中的内容。
* 参考doc/5.8.2 Customizing configuration metadata with a BeanFactoryPostProcessor
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations" value="classpath:db-config.properties"/>
</bean>
db-config.properties
driver=oracle.jdbc.driver.OracleDriver
url=jdbc:oracle:thin:@localhost:1521:orcl
username=dmc
password=456
ApplicationContext.xml
<bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource">
<property name="driverClassName" value="${driver}"></property>
<property name="url" value="${url}"></property>
<property name="username" value="${username}"></property>
<property name="password" value="${password}"></property>
<property name="minIdle" value="2"></property>
<property name="maxIdle" value="10"></property>
<property name="maxTotal" value="100"></property>
<property name="maxWaitMillis" value="2000"></property>
</bean>
八、Spring整合Mybatis
* spring整合mybaits主要是spring框架负责管理mybatis的SqlSessionFactory
* spring框架负责管理mybatis与数据库交互的事务处理
(1)引入jar包
spring3.x与mybatis的整合需要引入一个额外的jar包,提供sm的整合
(2)整合时要求数据源必须交给spring管理。
<bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource">
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"></property>
<property name="url" value="jdbc:oracle:thin:@localhost:1521:orcl"></property>
<property name="username" value="dmc"></property>
<property name="password" value="456"></property>
</bean>
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<property name="configLocation" value="classpath:configuration.xml"></property>
</bean>
configuration.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<mappers>
<mapper resource="com/dao/CarMapper.xml"/>
</mappers>
</configuration>
(3) 声明式事务
spring和mybatis整合时,使用的就是springjdbc自带的事务管理者, 如果要使用事务管理者提供的session对象,需要继承SqlSessionDaoSupport父类。该类提供了一个getSession()方法,来获得事务管理者管理的session对象。此时不建议service继承Support类,所以最好还是提供一个dao类。 Support父类需要一个SqlSessionFactory,记得注入。