数据源 (连接池) 的作用:
- 数据源是提高程序性能出现的
- 事先实例化数据源,初始化部分连接源
- 使用连接资源时从数据源中获取
- 使用完毕后将连接资源归还给数据源
常用数据源:DBCP、C3P0、BoneCP、Druid等…
数据源面试三连杀:数据源是什么?为什么要用?怎么用?
1. 数据源
-
数据源是什么?
通俗来讲,数据源是存储数据的地方。例如,数据库是数据源,其他系统也可以是数据源。在J2EE里,数据源是代表物理数据存储系统的实际Java对象。通过这些对象,J2EE应用可以获取到数据库的JDBC连接。
-
数据源的设计
从UML图上可以看出,CommonDaraSource 是对数据源概念的顶层抽象,约束了数据源必须实现的方法。数据源有三种类型的实现,分别是:
-
DataSource:基本实现,用于生成标准 Connection 对象
-
ConnectionPoolDataSource:连接池实现,这个数据源并不会直接创建数据库物理连接,而是一个逻辑实现,它的作用在于池化数据库物理连接。
-
XAConnection:分布式事务实现,为支持分布式事务而诞生,这个数据源直接生产出的不是数据库物理连接 Connection ,而是一个支持 XA 的 XAConnection 对象。
XAConnection 对象可以直接生产数据库物理连接,同时生产 XAResource 用于支持XA事务,通常 XAConnection 对象生产出的数据库物理连接 Connection 需要和该 XAConnection 生产出的 XAResource 对象配合使用以完成XA事务处理。
并且XAConnection 继承 PooledConnection,那就也具备连接池的实现。
2. 为什么需要XA数据源
2.1 XA数据源是什么
XA数据源指的是支持XA规范的数据源,支持分布式事务。
2.2 XA规范是什么
XA规范是一种分布式事务解决方案。X/OPEN组织定义的分布式事务处理模型(DTP),其包含3种角色和两个协议:
角色:
-
AP(Application,应用程序)
-
RM(Resources manager,资源管理器),通常指数据库
-
TM(Transaction manager,事务管理器),通常指事务协调者,负责协调和管理事务,提供给AP接口以及管理资源
协议:
-
XA协议是事务管理器与资源管理器之间的通信接口
-
TX协议是应用程序与事务管理器之间的通信接口
该模型中应用程序将一个全局事务传送到事务管理器,事务管理器将每个全局事务分解为多个分支(分支事务),并将分支事务分配给单独的资源管理器进行服务,事务管理器通过XA接口将每个分支事务与适当的资源管理器进行协调。
2.3 分布式事务具备有什么样的作用?
如果仅在同一个事务上下文中需要协调多种资源(即数据库以及消息主题或队列等等),这个事务中的所有操作都必须成功,否则所有操作都将在失败的情况下回滚。
这就是XA数据源的作用。
2.4 那什么样的场景需要使用XA?
-
您的JavaEE应用程序必须使用单个事务将数据存储在两个数据库中
-
您的应用程序需要通过单个事务发送JMS消息并将信息存储在数据库中
-
您希望使用PVP将您自己项目的域信息存储在一个不同的数据库中,而这个数据库是被jBPM用来存储它自己的数据。
3、 那怎么使用分布式事务呢?
3.1 J2EE的分布式事务
Java事务编程接口(Java Transaction API,JTA)和Java事务服务(Java Transaction Service,JTS)为J2EE平台提供了分布式事务服务。
JTA事务是XA规范的Java实现,JTA事务有效的屏蔽了底层事务资源,使应用可以以透明的方式参与到事务处理中。分布式事务包括事务管理器和一个或多个支持XA协议的资源管理器。
JTA是面向应用或应用服务器与资源管理器的高层事务接口。
JTS是一组约定JTA中角色之间交互细节的规范。
JTA提供了以下四个接口
-
javax.transaction.UserTransaction:
是面向开发人员的接口,能够编程地控制事务处理。UserTransaction.begin方法开启一个全局事务,并且将该事务与调用线程关联起来。
-
javax.transaction.TransactionManager:
允许应用程序服务器来控制代表正在管理的应用程序的事务。
它本身并不承担实际的事务处理功能,它更多的是充当UserTransaction接口和Transaction接口之间的桥梁。 -
javax.transaction.Transaction:
代表了一个物理意义上的事务,
在开发人员调用UserTransaction.begin()方法时TransactionManager会创建一个Transaction事务对象, -
javax.transaction.xa.XAResource:
面向提供商的实现接口,是一个基于X/Open CAE Specification的行业标准XA接口的Java映射。
提供商在提供访问自己资源的驱动时,必须实现这样的接口。
开发者调用UserTransaction.begin方法时,因为UserTransaction的实现类持有TransactionManager,TransactionManager充当UserTransaction和Transaction之间的桥梁,
所以在调用UserTransaction的begin方法时,TransactionManager会创建Transaction事务对象,并把此对象通过ThreadLocal关联到当前线程。
当调用UserTransaction其他方法时,会从当前线程取出事务对象Transaction对象,并通过Transaction对象找到与其关联的XAResource对象,然后进行commit、rollback等操作。其基本流程如以下代码:
// 创建一个Transaction,挂到当前线程上
UserTransaction userTx = null;
Connection connA = null;
Connection connB = null;
try{
userTx.begin();
// 将Connection对应的XAResource挂到当前线程对应的Transaction
connA.exec("xxx")
connB.exec("xxx")
// 找到Transaction关联的XAResource,让它们都提交
userTx.commit();
}catch(){
// 找到Transaction关联的XAResource,让它们都回滚
userTx.rollback();
}
3.2 如何使用J2EE的分布式事务
WebLogic、Websphere、JBoss等主流的应用服务器提供了JTA的实现和支持。
Tomcat中没有提供JTA的实现的,这就需要借助第三方的框架Jotm、Automikos等来实现。
数据源的开发步骤:
-
导入数据源的坐标和数据库驱动坐标
-
创建数据源对象
-
设置数据源的基本连接数据
-
使用数据源获取连接资源和归还连接资源
抽取配置文件:
目的: 让具体的字符串设置与数据源解耦合
Spring配置数据源:
可以将DataSource的创建权交给Spring容器去完成
抽取jdbc配置文件:
applicationContext.xml加载jdbc.properties配置文件获得连接信息。
首先需要引入context命名空间和约束路径:
-
命名空间:
xmlns:context="http://www.springframework.org/schema/context" -
约束路径 :
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd <context:property-placeholder location="jdbc.properties"></context:property-placeholder> <!-- Spring产生数据源 --> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <property name="driverClass" value="${key}"></property> <property name="jdbcUrl" value="${key}"></property> <property name="user" value="${key}"></property> <property name="password" value="${key}"></property> </bean>
知识要点:
Spring容器加载properties文件
<context:property-placeholder location="xx.properties"></context:property-placeholder>
注解开发
Spring 原始注解
Spring是轻代码而重配置的框架,配置比较繁重,影响开发效率,所以注解开发是一种趋势,注解代替xml配置文件可以简化配置,提高开发
Spring原始注解主要替代 的配置
组件扫描:
- 使用注解进行开发时,需要在applicationContext.xml中配置组件扫描,作用是指定哪个包下及其子包下的Bean需要进行扫描以便识别使用注解配置的类、字段和方法
在注解开发中,可以不用使用set方式就可以进行依赖注入喔~!
| 注解 | 说明 |
|---|---|
| @Component | 使用在类上用于实例化Bean |
| @Controller | 使用web层类上用于实例化Bean |
| @Service | 使用在service层类上用于实例化Bean |
| @Repository | 使用在dao层类上用于实例化Bean |
| @Autowired | 使用在字段上用于根据类型依赖注入 |
| @Qualifier | 结合@Autowired一起使用用于根据名称进行依赖注入 |
| @Resource | 相当于@Autowired+@Qualifier,按照名称进行注入 |
| @Value | 注入普通属性 |
| @Scope | 标注Bean的作用范围 |
| @PostConstruct | 使用在方法上标注该方法是Bean的初始化方法 |
| @PreDestroy | 使用在方法上标注该方法时Bean的销毁方法 |
Spring 新注解:
- 使用上面的注解还不能全部替代xml文件,还需要使用注解替代的配置如下:
非自定义的Bean的配置:
- 加载properties文件的配置: < context:property-placeholder >
- 引入其他文件:
| 注解 | 说明 |
|---|---|
| @Configuration | 用于指定当前类是一个Spring配置类,当创建容器时会从该类上加载注解 |
| @ComponentScan | 用于指定Spring在初始化容器时要扫描的包,作用和在Spring的xml配置文件中下列语句一样:<context:component-scan base-package=“.”/> |
| @Bean | 使用在方法上,标注该方法的返回值存储到Spring容器中 |
| @PropertySource | 用于加载.properties文件中的配置 |
| @Import | 用于导入其他配置类 |
| @RequestMapping | 用于方法的映射请求 |
Junit测试
原始Junit测试Spring的问题:
在测试类中,每个测试方法都有一下两行代码:
ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
IAccountService as = ac.getBean("accountService" 或者 IAccountService.class);
- 这两行代码的作用是获取容器,如果不写的话,直接会提示空指针异常,所有又不能轻易删掉
上述问题解决思路:
- 让SpringJunit负责创建Spring容器,但是需要将配置文件的名称告诉它。
- 将需要进行测试Bean直接在测试类中进行注入
Spring继承Junit步骤:
- 导入 Spring 继承 Junit 的坐标
- 使用 @Runwith 注解替换原来的运行期
- 使用 @ContextConfiguration 指定配置文件或配置类
- 使用 @Autowired 注入需要测试的对象
- 创建测试方法进行测试
JUnit
JUnit是什么?
- JUnit 是一个 Java 编程语言的单元测试框架。JUnit 在测试驱动的开发方面有很重要的发展,是起源于 JUnit 的一个统称为 xUnit 的单元测试框架之一。 本教程将教你用 Java 编程语言做单元测试时,如何使用 JUnit。
基础使用方法
测试失败说明:
- Failure:一般是由于测试结果和预期结果不一致引发的,表示测试的这个点发现了问题
- error:是由代码异常引起的,它可以产生于测试代码本身的错误,也可以是被测试代码中隐藏的 bug-
一些常用注解:
- @Test:将一个普通方法修饰成一个测试方法 @Test(excepted=xx.class): xx.class 表示异常类,
- 表示测试的方法抛出此异常时,认为是正常的测试通过的 @Test(timeout = 毫秒数) :测试方法执行时间是否符合预期
- @BeforeClass: 会在所有的方法执行前被执行,static 方法 (全局只会执行一次,而且是第一个运行)
- @AfterClass:会在所有的方法执行之后进行执行,static 方法 (全局只会执行一次,而且是最后一个运行)
- @Before:会在每一个测试方法被运行前执行一次
- @After:会在每一个测试方法运行后被执行一次
- @Ignore:所修饰的测试方法会被测试运行器忽略
- @RunWith:可以更改测试运行器 org.junit.runner.Runner
- @Parameters:参数化注解
Spring集成Web环境
-
ApplicationContext应用上下文获取方式
- 应用上下文对象是通过
配置文件方式获取的,但是每次从容器中获得Bean时都要编写配置文件,这样的弊端是指配置文件加载多次,应用上下文对象创建多次。 - 在Web项目中,可以使用SerbletContextListener监听Web应用的启动,我们可以在Web应用启动时,就加载Spring的配置文件,创建应用上下文对象ApplicationContext,在及那个其存储到最大的域servletContext域中,这样就可以在任意未知在域中获得应用上下文ApplicationContext对象了。
- 应用上下文对象是通过
-
Spring提供获取应用上下文的工具
- Spring提供了一个监听器ContextLoaderListener就是对上述功能的封装,该监听器内部加载Spring配置问价你,创建应用上下文对象,并存储到ServletContext域中,提供了一个客户端工具WebApplicationContextUtils供使用者获得应用上下文对象
-
使用Spring提供的工具(步骤)
- 在web.xml中配置ContextLoaderListener监听器(导入Spring-web坐标)
- 使用WebApplicationContextUtils获得应用上下文对象ApplicationContext

被折叠的 条评论
为什么被折叠?



