收集Hibernate / Ehcache统计信息并在基于Spring的设置中通过JMX公开它们似乎很容易。互联网有很多资源可以帮助,例如http://snippets.dzone.com/posts/show/11159
但是,所有这些文章都假设有人正在使用某种类型的Hibernate会话工厂。我不是 - 我的实体是JPA注释,我使用javax.persistence.EntityManager
。
如果我正在部署到Java EE容器,我可能已经能够通过JNDI获得Hibernate会话工厂,如http://internna.blogspot.com/2007/08/hibernate-statistics-in-enterprise-5.html所述,但我在Tomcat上...
如何解决这个问题?我还没有提出解决方案。
如果我引用了Ehcache CacheManager
,我可以尝试类似:
<context:mbean-server />
<bean class="net.sf.ehcache.management.ManagementService" init-method="init">
<constructor-arg ref="..myCacheManager.."/>
<constructor-arg ref="mbeanServer"/>
<constructor-arg value="true"/>
<constructor-arg value="true"/>
<constructor-arg value="true"/>
<constructor-arg value="true"/>
</bean>
由于缓存管理器是由Hibernate创建的(即它不是Spring bean),因此它不起作用。我尝试用
替换那个引用<constructor-arg><bean id="cacheManager" class="net.sf.ehcache.CacheManager" factory-method="getInstance"/></constructor-arg>
希望我能以某种方式抓住正确的实例。无法工作,因为这实际上会创建一个新的缓存管理器实例。
答案 0 :(得分:3)
我最近构建了一个基于Spring的webapp示例,它非常干净地为JMX提供了最新版本的Spring,Hibernate和Ehcache。
它包含基于EntityManager的访问和DAO访问(包括事务!)的示例。它还展示了如何进行基于注释的注入,以便否定必须使用Spring的bean的xml配置。甚至还有一个基于SpringMVC的示例servlet使用注释。基本上,这是一个基于Spring的版本,它运行在任何servlet引擎之上。
尚未记录,但我很快就会谈到这一点。看一下配置文件和源代码,它应该非常清楚。
这背后的动机是我厌倦了所有疯狂的博客文章,用50种不同的方式进行设置,最后制作了一个人们可以使用的简单来源。它是在github上,所以随意分叉项目并随心所欲地做任何事情。
答案 1 :(得分:2)
JPA EntityManager公开了底层的Hibernate会话,因此您可以访问其工厂:
public static Session getHibernateSession(EntityManager entityManager) {
Session session;
if (entityManager.getDelegate() instanceof EntityManagerImpl) {
EntityManagerImpl entityManagerImpl = (EntityManagerImpl) entityManager.getDelegate();
session = entityManagerImpl.getSession();
} else {
session = (Session) entityManager.getDelegate();
}
return session;
}
然后您可以像enable the statistics
那样使用此会话RHQ project答案 2 :(得分:2)
您实际上可以使用Spring Expression Language公开任何CacheManager。
<bean id="hibernateCacheManagement" class="net.sf.ehcache.management.ManagementService" init-method="init" >
<constructor-arg value="#{T(net.sf.ehcache.CacheManager).getCacheManager('CACHE_NAME')}"/>
<constructor-arg><ref bean="mbeanServer"/></constructor-arg>
<constructor-arg value="true"/>
<constructor-arg value="true"/>
<constructor-arg value="true"/>
<constructor-arg value="true"/>
</bean>
其中CACHE_NAME是ehcache.xml文件中配置的缓存的名称。
<ehcache name="CACHE_NAME">
...
</ehcache>
答案 3 :(得分:1)
我最后写了下面的课程
HibernateStatisticsJmxRegistration
import javax.management.JMException;
import javax.management.MBeanServer;
import javax.management.ObjectName;
import javax.persistence.EntityManagerFactory;
import org.hibernate.SessionFactory;
import org.hibernate.ejb.HibernateEntityManagerFactory;
import org.hibernate.jmx.StatisticsService;
import org.springframework.beans.factory.annotation.Autowired;
/**
* Provides code to register Hibernate's statistics bean with a JMX MBean server. Assumes that both
* the MBeanServer and the EntityManagerFactory are available as Spring-managed beans. Note that
* while registering this class enables the collection of statistics even if that was previously
* disabled.
* <p>
* May become obsolete once <a href="https://hibernate.onjira.com/browse/HHH-6034">HHH-6034</a> is
* implemented. Even if not the confusing situation abround the meanwhile deprecated
* {@link StatisticsService} should be clear then.
*/
@SuppressWarnings({"deprecation", "javadoc" })
public class HibernateStatisticsJmxRegistration {
@Autowired
private EntityManagerFactory entityManagerFactory;
@Autowired
private MBeanServer mbeanServer;
private ObjectName objectName;
private String jmxObjectName = "org.hibernate:name=HibernateStatistics";
/**
* Registers the statistics MBean that wraps a Hibernate session factory. The bean is registered
* under the name provided by {@link HibernateStatisticsJmxRegistration#getJmxObjectName()}.
*
* @throws JMException if anything fails..
* @see HibernateStatisticsJmxRegistration#unregister()
*/
public void register() throws JMException {
final SessionFactory sessionFactory = ((HibernateEntityManagerFactory) entityManagerFactory).getSessionFactory();
objectName = new ObjectName(jmxObjectName);
final StatisticsService statsMBean = new StatisticsService();
statsMBean.setSessionFactory(sessionFactory);
statsMBean.setStatisticsEnabled(true);
mbeanServer.registerMBean(statsMBean, objectName);
}
/**
* Unregisters the MBean that was registered.
*
* @throws JMException if the de-registration fails
* @see HibernateStatisticsJmxRegistration#register()
*/
public void unregister() throws JMException {
mbeanServer.unregisterMBean(objectName);
}
/**
* Override the default JMX object name. Obviously you need to call this method before
* registration for it to have any effect. The string must comply to the rules described in
* {@link ObjectName}. Suggested is {@code <domain>:name=<name>}.
*
* @param jmxObjectName the name to use during registration
*/
public void setJmxObjectName(String jmxObjectName) {
this.jmxObjectName = jmxObjectName;
}
}
春季配置
<!-- Setting up Ehcache manager for various caches (offer facade, images). -->
<bean id="ehCacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
<property name="configLocation" value="classpath:ehcache.xml" />
</bean>
<ehcache:annotation-driven cache-manager="ehCacheManager" />
<!-- Exposing cache statistics through JMX. -->
<context:mbean-server />
<bean class="net.sf.ehcache.management.ManagementService" init-method="init">
<constructor-arg ref="ehCacheManager"/>
<constructor-arg ref="mbeanServer"/>
<constructor-arg value="true"/>
<constructor-arg value="true"/>
<constructor-arg value="true"/>
<constructor-arg value="true"/>
</bean>
<bean class="HibernateStatisticsJmxRegistration"
init-method="register" destroy-method="unregister" />
答案 4 :(得分:0)
非常哎,但这也有效,其中(猜测是什么)mbeanServer是MBean Server的bean名称,entityManagerFactory是EntityManagerFactory的bean名称:
<bean id="managementService-ehcache-hibernate"
class="net.sf.ehcache.management.ManagementService"
init-method="init"
destroy-method="dispose">
<constructor-arg value="#{T(org.springframework.security.util.FieldUtils).getFieldValue(@entityManagerFactory.cache.unwrap(T(org.hibernate.cache.spi.RegionFactory)),'manager')}"/>
<constructor-arg ref="mbeanServer"/>
<constructor-arg index="2" value="true"/>
<constructor-arg index="3" value="true"/>
<constructor-arg index="4" value="true"/>
<constructor-arg index="5" value="true"/>
</bean>
答案 5 :(得分:-1)
Spring只在JMX上暴露了他的bean,但你可以通过MBeanExporter以编程方式导出资源。