Netbeans中包含一个HibernateJPA库,是由很多jar包组成的,一次业务需要查内部代码,于是有了下面的分析:
加入该库后发现导入的包太多了,因为项目中使用实体管理器时导入的包是javax.persistence.EntityManager ,
不是hibernate的,这个包肯定也不是hibernate的,所以分析入口先不用找hibernate的包,
根据这个类路径,首先找到的是ejb3-persistence,在这个包里找到了javax.persistence.EntityManager类,但该类是个接口,
并没有实现的代码,推测hibernate肯定有一个该接口的实现,至于实现类叫什么,应该通过其他方式获得,继续找下一个
javax.persistence.PersistenceException,也在这个包下面,这个不是接口,里面有实现代码,主要代码如下:
public static EntityManagerFactory createEntityManagerFactory(String persistenceUnitName, Map properties)
{
EntityManagerFactory emf = null;
if (providers.size() == 0) {
findAllProviders();
}
for (PersistenceProvider provider : providers) {
emf = provider.createEntityManagerFactory(persistenceUnitName, properties);
if (emf != null) break;
}
if (emf == null) {
throw new PersistenceException("No Persistence provider for EntityManager named " + persistenceUnitName);
}
return emf;
}
private static void findAllProviders ()
{
ClassLoader loader;
try {
loader = Thread.currentThread().getContextClassLoader();
Enumeration resources = loader.getResources("META-INF/services/" + PersistenceProvider.class.getName() );
Set names = new HashSet();
while (resources.hasMoreElements()) {
URL url = (URL)resources.nextElement();
InputStream is = url.openStream();
try {
names.addAll(providerNamesFromReader(new BufferedReader(new InputStreamReader(is))));
}
finally {
is.close();
}
}
for (String s : names) {
Class providerClass = loader.loadClass(s);
providers.add((PersistenceProvider)providerClass.newInstance());
}
}
里面有一个很重要的地方就是 loader.getResources("META-INF/services/" + PersistenceProvider.class.getName());
看来是读取配置文件,接下来就找这个配置文件,肯定在某一个包里,挨个看把,
最后找到是在hibernate-entitymanager.jar包中
里面有一个配置文件javax.persistence.spi.PersistencePrivider,回头去看看那个PersistenceProvider类,果然就是它,
打开之后,只有一行 org.hibernate.ejb.HibernatePersistence,这才是真正的入口
找到这个类,在hibernate-entitymanager.jar包中,
发现这个类前面定义了好多静态变量,而且还包含createEntityManagerFactory方法
找到了入口,剩下的就是具体问题具体分析了,不在详述,等什么具体的心得,下次再聊