JPA基础(八):分析JPA与持久化实现产品对接的源代码

使用jadnt158工具将ejb3-persistence.jar\javax\persistence.class进行反编译得到源码:

  1 // Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov.
2 // Jad home page: http://www.kpdus.com/jad.html
3 // Decompiler options: packimports(3)
4 // Source File Name: Persistence.java
5
6 package javax.persistence;
7
8 import java.io.*;
9 import java.net.URL;
10 import java.util.*;
11 import java.util.regex.Matcher;
12 import java.util.regex.Pattern;
13 import javax.persistence.spi.PersistenceProvider;
14
15 // Referenced classes of package javax.persistence:
16 // PersistenceException, EntityManagerFactory
17
18 public class Persistence
19 {
20
21 public Persistence()
22 {
23 }
24
25 public static EntityManagerFactory createEntityManagerFactory(String persistenceUnitName)
26 {
27 return createEntityManagerFactory(persistenceUnitName, null);
28 }
29
30 public static EntityManagerFactory createEntityManagerFactory(String persistenceUnitName, Map properties)
31 {
32 EntityManagerFactory emf = null;
33 if(providers.size() == 0)
34 findAllProviders();
35 Iterator i$ = providers.iterator();
36 do
37 {
38 if(!i$.hasNext())
39 break;
40 PersistenceProvider provider = (PersistenceProvider)i$.next();
41 emf = provider.createEntityManagerFactory(persistenceUnitName, properties);
42 } while(emf == null);
43 if(emf == null)
44 throw new PersistenceException((new StringBuilder()).append("No Persistence provider for EntityManager named ").append(persistenceUnitName).toString());
45 else
46 return emf;
47 }
48
49 private static void findAllProviders()
50 {
51 ClassLoader loader;
52 Enumeration resources;
53 Set names;
54 loader = Thread.currentThread().getContextClassLoader();
55 resources = loader.getResources((new StringBuilder()).append("META-INF/services/").append(javax/persistence/spi/PersistenceProvider.getName()).toString());
56 names = new HashSet();
57 _L2:
58 InputStream is;
59 if(!resources.hasMoreElements())
60 break; /* Loop/switch isn't completed */
61 URL url = (URL)resources.nextElement();
62 is = url.openStream();
63 names.addAll(providerNamesFromReader(new BufferedReader(new InputStreamReader(is))));
64 is.close();
65 if(true) goto _L2; else goto _L1
66 Exception exception;
67 exception;
68 is.close();
69 throw exception;
70 _L1:
71 Class providerClass;
72 for(Iterator i$ = names.iterator(); i$.hasNext(); providers.add((PersistenceProvider)providerClass.newInstance()))
73 {
74 String s = (String)i$.next();
75 providerClass = loader.loadClass(s);
76 }
77
78 break MISSING_BLOCK_LABEL_214;
79 IOException e;
80 e;
81 throw new PersistenceException(e);
82 e;
83 throw new PersistenceException(e);
84 e;
85 throw new PersistenceException(e);
86 e;
87 throw new PersistenceException(e);
88 }
89
90 private static Set providerNamesFromReader(BufferedReader reader)
91 throws IOException
92 {
93 Set names = new HashSet();
94 do
95 {
96 String line;
97 if((line = reader.readLine()) == null)
98 break;
99 line = line.trim();
100 Matcher m = nonCommentPattern.matcher(line);
101 if(m.find())
102 names.add(m.group().trim());
103 } while(true);
104 return names;
105 }
106
107 public static final String PERSISTENCE_PROVIDER = "javax.persistence.spi.PeristenceProvider";
108 protected static final Set providers = new HashSet();
109 private static final Pattern nonCommentPattern = Pattern.compile("^([^#]+)");
110
111 }

在如下图所示中:

打开javax.persistence.spi.PersistenceProvider,内容为:org.hibernate.ejb.HibernatePersistence

程序会在类路径地下寻找到这个文件,并读取这个配置文件里面指定的可持久化驱动。Hibernate提供的可持久化驱动就是org.hibernate.ejb.HibernatePersistence这个类,这个类是Hibernate的入口类,类似JDBC里面的驱动类。当然,不同的可持久化产品的入口类是不同的,调用JPA应用,它能使用Hibernate,是因为有这样一个驱动类,它起到了一个桥梁的作用,过渡到Hibernate的产品上,这就是调用EntityManagerFactory factory =Persistence.createEntityManagerFactory("sample");


创建实体管理器方法的一些执行细节
factory 是由Hibernate的可持久化驱动类创建出来的,如果观察Hibernate的实现类的话,会发现实际上EntityManagerFactory 是对SessionFactory这个类进行了一层封装。包括EntityManager类也是对Session对象进行了一层封装而已。

posted @ 2011-11-30 22:44  一直在等  阅读(1925)  评论(0编辑  收藏  举报