在Tomcat中使用Spring通过JMX公开Hibernate(缓存)统计信息 [英] Exposing Hibernate (cache) statistics through JMX with Spring in Tomcat
问题描述
然而,所有这些文章都假设您正在与某种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.ManagementServiceinit-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 =cacheManagerclass =net.sf替换那个ref .ehcache.CacheManagerfactory-method =getInstance/>< / constructor-arg>
希望我能以某种方式捕捉正确的实例。因为这实际上会创建一个新的缓存管理器实例,所以无法工作。
我最终编写了下面的类
HibernateStatisticsJmxRegistration
$ b
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;
/ **
*提供代码使用JMX MBean服务器注册Hibernate的统计信息bean。假定
* MBeanServer和EntityManagerFactory都可用作Spring管理的bean。请注意,注册此类时
*可以收集统计信息,即使之前为
*禁用。
*< p>
*可能一度过时< a href =https://hibernate.onjira.com/browse/HHH-6034> HHH-6034< / a>是
*实施。即使不是令人困惑的情况,同时弃用的
* {@link StatisticsService}也应该清楚。
* /
@SuppressWarnings({deprecation,javadoc})
public class HibernateStatisticsJmxRegistration {
$ b $ @Autowired
private EntityManagerFactory entityManagerFactory;
@Autowired
private MBeanServer mbeanServer;
private ObjectName objectName;
private String jmxObjectName =org.hibernate:name = HibernateStatistics;
/ **
*注册包装Hibernate会话工厂的统计MBean。该Bean在{@link HibernateStatisticsJmxRegistration#getJmxObjectName()}提供的名称下注册
*。
*
* @ throws JMException如果有任何失败..
* @see HibernateStatisticsJmxRegistration#unregister()
* /
public void register()throws JMException {
final SessionFactory sessionFactory =((HibernateEntityManagerFactory)entityManagerFactory).getSessionFactory();
objectName = new ObjectName(jmxObjectName);
最终StatisticsService statsMBean = new StatisticsService();
statsMBean.setSessionFactory(sessionFactory);
statsMBean.setStatisticsEnabled(true);
mbeanServer.registerMBean(statsMBean,objectName);
}
/ **
*注销已注册的MBean。
*
* @throws JMException如果注销失败
* @see HibernateStatisticsJmxRegistration#register()
* /
public void unregister()throws JMException {
mbeanServer.unregisterMBean(objectName);
}
/ **
*覆盖默认的JMX对象名称。很明显,您需要在
*注册之前调用此方法才能起作用。该字符串必须符合
* {@link ObjectName}中描述的规则。建议使用{@code< domain>:name =< name>}。
*
* @param jmxObjectName注册期间使用的名称
* /
public void setJmxObjectName(String jmxObjectName){
this.jmxObjectName = jmxObjectName;
Spring配置 p>
<! - 为各种缓存设置Ehcache管理器(offer facade,images)。 - >
< bean id =ehCacheManagerclass =org.springframework.cache.ehcache.EhCacheManagerFactoryBean>
< property name =configLocationvalue =classpath:ehcache.xml/>
< / bean>
< ehcache:annotation-driven cache-manager =ehCacheManager/>
<! - 通过JMX公开缓存统计信息。 - >
< context:mbean-server />
< bean class =net.sf.ehcache.management.ManagementServiceinit-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 =registerdestroy-method =unregister/>
Collecting Hibernate/Ehcache statistics and exposing them through JMX in Spring-based setups seems easy. The Internet has lots of resources that help e.g. http://snippets.dzone.com/posts/show/11159
However, all those articles assume one is working with a Hibernate session factory of some sort. I'm not - my entities are JPA annotated and I use a javax.persistence.EntityManager
.
If I were deploying to a Java EE container I might have been able to obtain a Hibernate session factory through JNDI as described here http://internna.blogspot.com/2007/08/hibernate-statistics-in-enterprise-5.html but I'm on Tomcat...
How to go about this? I haven't come up with a solution yet.
If I had a reference to the Ehcache CacheManager
I could try something like:
<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>
Since the cache manager is created by Hibernate (i.e. it's not a Spring bean) it won't work. I tried replacing that ref with
<constructor-arg><bean id="cacheManager" class="net.sf.ehcache.CacheManager" factory-method="getInstance"/></constructor-arg>
hoping I'd somehow catch the right instance. Won't work either as this would in fact create a new cache manager instance.
I ended up writing the following class
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;
}
}
Spring configuration
<!-- 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" />
这篇关于在Tomcat中使用Spring通过JMX公开Hibernate(缓存)统计信息的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!