在基于Spring的设置中收集Hibernate / Ehcache统计信息并通过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 …
javax.persistence.EntityManager
怎么办呢?我还没有想出解决方案。
如果我引用了Ehcache CacheManager,则可以尝试以下操作:
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>
希望我能以某种方式抓住合适的实例。也不起作用,因为这实际上会创建一个新的缓存管理器实例。
我最终写了下面的课
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" />