Hibernate源代码分析(一):设计属于我的SessionFactory和ConnectionProvider

过完五一长假,花了四天的时间来学习Hibernate框架的使用,作为门外汉,先是从sourceforg.net下载 Hibernate3.2,先看官方文档,只有一个提纲,了解了一下各个包的结构,便开始根据Toturial实践,基本掌握了它的使用方法之后,盟生了 实现自己的SessionFactory和ConnectionProvider的想法。
闲话少说,要实现我的SessionFactory和ConnectionProvider,不深入了解该体系结构是不行的,先从源代码分析开始: 首先从org.hibernate.cfg.Configuration.java开始,使用Hibernate框架实现应用程序,首先就要与org.hibernate.cfg.Configuration打交道,要使用
Configuration.buildSessionFactory()方法获得一个SessionFactory,截取代码片段如下:

1 public SessionFactorybuildSessionFactory() throws HibernateException {
2
3returnnewSessionFactoryImpl(
4this,
5mapping,
6settings,
7getInitializedEventListeners()
8);
9}

上面的代码片断省略了读取Hibernate配置的代码,从这个我们可以知道,Configuration类buildSessionFactory()方法实际上返回了SessionFactory接口的实现SessionFactoryImpl。

当我们得到了一个SessionFactory接口的实现SessionFactoryImpl,就要调用它的getCurrentSession()方 法来获得一个Session,接下来转到org.hibernate.impl.SessionFactoryImpl.java,来看看 getCurrentSession()方法的实现,代码片段如下:
1 public org.hibernate.classic.SessiongetCurrentSession() throws HibernateException {
2if(currentSessionContext==null){
3thrownewHibernateException("NoCurrentSessionContextconfigured!");
4}

5returncurrentSessionContext.currentSession();
6}

在该方法中,SessionFactoryImpl将获得Session的工作委托给了currentSessionContext.currentSession(),currentSessionContext为何物?其定义为:
org.hibernate.context.CurrentSessionContext;在SessionFactoryImpl的构造函数中,可以看到:

currentSessionContext = buildCurrentSessionContext();

马上追溯到buildCurrentSessionContext()方法,代码片段如下:

1 private CurrentSessionContextbuildCurrentSessionContext() {
2Stringimpl=properties.getProperty(Environment.CURRENT_SESSION_CONTEXT_CLASS);
3//forbackward-compatability
4if(impl==null&&transactionManager!=null){
5impl="jta";
6}

7
8if(impl==null){
9returnnull;
10}

11elseif("jta".equals(impl)){
12if(settings.getTransactionFactory().areCallbacksLocalToHibernateTransactions()){
13log.warn("JTASessionContextbeingusedwithJDBCTransactionFactory;auto-flushwillnotoperatecorrectlywithgetCurrentSession()");
14}

15returnnewJTASessionContext(this);
16}

17elseif("thread".equals(impl)){
18returnnewThreadLocalSessionContext(this);
19}

20elseif("managed".equals(impl)){
21returnnewManagedSessionContext(this);
22}

23else{
24try{
25ClassimplClass=ReflectHelper.classForName(impl);
26return(CurrentSessionContext)implClass
27.getConstructor(newClass[]{SessionFactoryImplementor.class})
28.newInstance(newObject[]{this});
29}

30catch(Throwablet){
31log.error("Unabletoconstructcurrentsessioncontext["+impl+"]",t);
32returnnull;
33}

34}

35}

36

从这里可以发现,SessionFactoryImpl用反射实现了CurrentSessionContext接口的动态装配。
接下来,暂时将视线从SessionFactoryImpl移开,以org.hibernate.context.JTASessionContext为代表,看CurrentSessionContext接口是如何实现
的currentSession()方法的,打开org.hibernate.context.JTASessionContext.java,找到currentSession(),代码片段如下:

1 public SessioncurrentSession() throws HibernateException {
2
3if(currentSession==null){
4currentSession=buildOrObtainSession();
5
6}

7
8returncurrentSession;
9}

转移到buildOrObtainSession()方法,

1 protected SessionbuildOrObtainSession() {
2returnfactory.openSession(
3null,
4isAutoFlushEnabled(),
5isAutoCloseEnabled(),
6getConnectionReleaseMode()
7);
8}

前面SessionFactoryImpl.buildCurrentSessionContext()方法有new JTASessionContext( this ),而此时的factory.openSessio()就是SessionFactoryImpl.openSessio()了。

将目光焦点回到org.hibernate.impl.SessionFactoryImpl.java,SessionFactoryImpl.openSessio()的实现如下:

1 private SessionImplopenSession(
2 Connectionconnection,
3 boolean autoClose,
4 long timestamp,
5 InterceptorsessionLocalInterceptor
6 ) {
7returnnewSessionImpl(
8connection,
9this,
10autoClose,
11timestamp,
12sessionLocalInterceptor==null?interceptor:sessionLocalInterceptor,
13settings.getDefaultEntityMode(),
14settings.isFlushBeforeCompletionEnabled(),
15settings.isAutoCloseSessionEnabled(),
16settings.getConnectionReleaseMode()
17);
18}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值