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方法
找到了入口,剩下的就是具體問題具體分析了,不在詳述,等什麼具體的心得,下次再聊