EntityManagerFactory factory = Persistence.createEntityManagerFactory("itcast");
讲解下这个方法内部的一些原理(了解下就OK)
打开源代码Persistence.java (用DJ Java Decompiler 3.7反编译的代码)
// Decompiled by DJ v3.7.7.81 Copyright 2004 Atanas Neshkov Date: 2010-7-12 20:30:06
// Home Page : http://members.fortunecity.com/neshkov/dj.html - Check often for new version!
// Decompiler options: packimports(3)
// Source File Name: Persistence.java
package javax.persistence;
import java.io.*;
import java.net.URL;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.persistence.spi.PersistenceProvider;
// Referenced classes of package javax.persistence:
// PersistenceException, EntityManagerFactory
public class Persistence
{
public Persistence()
{
}
public static EntityManagerFactory createEntityManagerFactory(String persistenceUnitName)
{
return createEntityManagerFactory(persistenceUnitName, null);
}
public static EntityManagerFactory createEntityManagerFactory(String persistenceUnitName, Map properties)
{
EntityManagerFactory emf = null;
if(providers.size() == 0)
findAllProviders(); //这个方法是寻找类路径下的所有持久化驱动。
Iterator i$ = providers.iterator();
do
{
if(!i$.hasNext())
break;
PersistenceProvider provider = (PersistenceProvider)i$.next();
emf = provider.createEntityManagerFactory(persistenceUnitName, properties);
} while(emf == null);
if(emf == null)
throw new PersistenceException((new StringBuilder()).append("No Persistence provider for EntityManager named ").append(persistenceUnitName).toString());
else
return emf;
}
private static void findAllProviders()
{
ClassLoader loader;
Enumeration resources;
Set names;
loader = Thread.currentThread().getContextClassLoader();
resources = loader.getResources((new StringBuilder()).append("META-INF/services/").append(javax/persistence/spi/PersistenceProvider.getName()).toString());
//程序会在类路径的这个目录下查找驱动信息所在的文件。这个文件的详细地址如下图所示:
names = new HashSet();
_L2:
InputStream is;
if(!resources.hasMoreElements())
break; /* Loop/switch isn't completed */
URL url = (URL)resources.nextElement();
is = url.openStream();
names.addAll(providerNamesFromReader(new BufferedReader(new InputStreamReader(is))));
is.close();
if(true) goto _L2; else goto _L1
Exception exception;
exception;
is.close();
throw exception;
_L1:
Class providerClass;
for(Iterator i$ = names.iterator(); i$.hasNext(); providers.add((PersistenceProvider)providerClass.newInstance()))
{
String s = (String)i$.next();
providerClass = loader.loadClass(s);
}
break MISSING_BLOCK_LABEL_214;
IOException e;
e;
throw new PersistenceException(e);
e;
throw new PersistenceException(e);
e;
throw new PersistenceException(e);
e;
throw new PersistenceException(e);
}
private static Set providerNamesFromReader(BufferedReader reader)
throws IOException
{
Set names = new HashSet();
do
{
String line;
if((line = reader.readLine()) == null)
break;
line = line.trim();
Matcher m = nonCommentPattern.matcher(line);
if(m.find())
names.add(m.group().trim());
} while(true);
return names;
}
public static final String PERSISTENCE_PROVIDER = "javax.persistence.spi.PeristenceProvider";
protected static final Set providers = new HashSet();
private static final Pattern nonCommentPattern = Pattern.compile("^([^#]+)");
}
这个资源在哪里呢? 看图:
打开,内容为 org.hibernate.ejb.HibernatePersistence
程序会在类路径地下寻找到这个文件,并读取这个配置文件里面指定的可持久化驱动。
Hibernate提供的可持久化驱动就是org.hibernate.ejb.HibernatePersistence这个类,这个类是Hibernate的入口类,类似JDBC里面的驱动类。
当然,不同的可持久化产品的入口类是不同的。
调用JPA应用,它能使用Hibernate,是因为有这样一个驱动类,它起到了一个桥梁的作用,过渡到Hibernate的产品上,这就是调用EntityManagerFactory factory = Persistence.createEntityManagerFactory("itcast"); 创建实体管理器方法的一些执行细节。
factory 是由Hibernate的可持久化驱动类创建出来的,如果观察Hibernate的实现类的话,会发现实际上EntityManagerFactory 是对SessionFactory这个类进行了一层封装。
包括EntityManager类也是对Session对象进行了一层封装而已。
只要研究下Hibernate的JPA实现代码就可以观察出来。