[关闭]
@aloxc 2017-12-05T06:22:33.000000Z 字数 6849 阅读 419

我们一起学ignite之MXBean

一起学 ignite 源码分析


如题,ignite中定义了若干个MXBean及几个和MxBean相关的annotation,这些代码共同构成ignite中jmx想相关功能。
话不多说,直接看代码吧,

  1. @Documented
  2. @Retention(RetentionPolicy.RUNTIME)
  3. @Target({ElementType.TYPE, ElementType.METHOD})
  4. public @interface MXBeanDescription {
  5. public String value();
  6. }
  1. @Documented
  2. @Retention(RetentionPolicy.RUNTIME)
  3. @Target({ElementType.METHOD})
  4. public @interface MXBeanParametersDescriptions {
  5. public String[] value();
  6. }
  1. @Documented
  2. @Retention(RetentionPolicy.RUNTIME)
  3. @Target({ElementType.METHOD})
  4. public @interface MXBeanParametersNames {
  5. public String[] value();
  6. }

这三个注解很简单,一个负责注解MXBean接口定义类和接口中的方法,一个负责注解接口中方法的参数列表,一个负责注解参数的描述。
随便找一个MXBean看一下,比如IgniteMXBean,下面代码节选了一部分

  1. @MXBeanDescription("MBean that provides access to Kernal information.")
  2. public interface IgniteMXBean {
  3. @MXBeanDescription("String presentation of the Ignite version.")
  4. public String getFullVersion();
  5. @MXBeanDescription("A shortcut method that executes given task assuming single " +
  6. "String argument and String return type. Returns Task return value (assumed of String type).")
  7. @MXBeanParametersNames(
  8. {
  9. "taskName",
  10. "arg"
  11. }
  12. )
  13. @MXBeanParametersDescriptions(
  14. {
  15. "Name of the task to execute.",
  16. "Single task execution argument (can be null)."
  17. }
  18. )
  19. public String executeTask(String taskName, String arg) throws JMException;
  20. }

从代码中看到,接口类及接口中方法加了一些注解,这些注解的内容用于jmx相关功能,并使用IgniteStandardMXBean扩展java中StandardMXBean,如下IgniteStandardMXBean代码:

  1. package org.apache.ignite.internal.mxbean;
  2. import java.lang.reflect.Method;
  3. import java.util.HashMap;
  4. import java.util.Map;
  5. import javax.management.MBeanAttributeInfo;
  6. import javax.management.MBeanInfo;
  7. import javax.management.MBeanOperationInfo;
  8. import javax.management.MBeanParameterInfo;
  9. import javax.management.NotCompliantMBeanException;
  10. import javax.management.StandardMBean;
  11. import org.apache.ignite.internal.util.typedef.internal.U;
  12. import org.apache.ignite.mxbean.MXBeanDescription;
  13. import org.apache.ignite.mxbean.MXBeanParametersDescriptions;
  14. import org.apache.ignite.mxbean.MXBeanParametersNames;
  15. /**
  16. * Extension of standard Java MBean. Overrides some hooks to return
  17. * annotation based descriptions.
  18. */
  19. public class IgniteStandardMXBean extends StandardMBean {
  20. private static final Map<String, Class<?>> primCls = new HashMap<>();
  21. static{
  22. primCls.put(Boolean.TYPE.toString().toLowerCase(), Boolean.TYPE);
  23. primCls.put(Character.TYPE.toString().toLowerCase(), Character.TYPE);
  24. primCls.put(Byte.TYPE.toString().toLowerCase(), Byte.TYPE);
  25. primCls.put(Short.TYPE.toString().toLowerCase(), Short.TYPE);
  26. primCls.put(Integer.TYPE.toString().toLowerCase(), Integer.TYPE);
  27. primCls.put(Long.TYPE.toString().toLowerCase(), Long.TYPE);
  28. primCls.put(Float.TYPE.toString().toLowerCase(), Float.TYPE);
  29. primCls.put(Double.TYPE.toString().toLowerCase(), Double.TYPE);
  30. }
  31. public <T> IgniteStandardMXBean(T implementation, Class<T> mbeanInterface)
  32. throws NotCompliantMBeanException {
  33. super(implementation, mbeanInterface);
  34. }
  35. @Override protected String getDescription(MBeanAttributeInfo info) {
  36. String str = super.getDescription(info);
  37. String methodName = (info.isIs() ? "is" : "get") + info.getName();
  38. try {
  39. // Recursively get method.
  40. Method mtd = findMethod(getMBeanInterface(), methodName, new Class[]{});
  41. if (mtd != null) {
  42. MXBeanDescription desc = mtd.getAnnotation(MXBeanDescription.class);
  43. if (desc != null) {
  44. str = desc.value();
  45. assert str != null : "Failed to find method: " + mtd;
  46. assert str.trim().length() > 0 : "Method description cannot be empty: " + mtd;
  47. // Enforce proper English.
  48. assert Character.isUpperCase(str.charAt(0)) == true :
  49. "Description must start with upper case: " + str;
  50. assert str.charAt(str.length() - 1) == '.' : "Description must end with period: " + str;
  51. }
  52. }
  53. }
  54. catch (SecurityException e) {
  55. // No-op. Default value will be returned.
  56. }
  57. return str;
  58. }
  59. @Override protected String getDescription(MBeanInfo info) {
  60. String str = super.getDescription(info);
  61. MXBeanDescription desc = U.getAnnotation(getMBeanInterface(), MXBeanDescription.class);
  62. if (desc != null) {
  63. str = desc.value();
  64. assert str != null;
  65. assert str.trim().length() > 0;
  66. // Enforce proper English.
  67. assert Character.isUpperCase(str.charAt(0)) == true : str;
  68. assert str.charAt(str.length() - 1) == '.' : str;
  69. }
  70. return str;
  71. }
  72. @Override protected String getDescription(MBeanOperationInfo info) {
  73. String str = super.getDescription(info);
  74. try {
  75. Method m = getMethod(info);
  76. MXBeanDescription desc = m.getAnnotation(MXBeanDescription.class);
  77. if (desc != null) {
  78. str = desc.value();
  79. assert str != null;
  80. assert str.trim().length() > 0;
  81. // Enforce proper English.
  82. assert Character.isUpperCase(str.charAt(0)) == true : str;
  83. assert str.charAt(str.length() - 1) == '.' : str;
  84. }
  85. }
  86. catch (SecurityException | ClassNotFoundException e) {
  87. // No-op. Default value will be returned.
  88. }
  89. return str;
  90. }
  91. @Override protected String getDescription(MBeanOperationInfo op, MBeanParameterInfo param, int seq) {
  92. String str = super.getDescription(op, param, seq);
  93. try {
  94. Method m = getMethod(op);
  95. MXBeanParametersDescriptions decsAnn = m.getAnnotation(MXBeanParametersDescriptions.class);
  96. if (decsAnn != null) {
  97. assert decsAnn.value() != null;
  98. assert seq < decsAnn.value().length;
  99. str = decsAnn.value()[seq];
  100. assert str != null;
  101. assert str.trim().length() > 0;
  102. // Enforce proper English.
  103. assert Character.isUpperCase(str.charAt(0)) == true : str;
  104. assert str.charAt(str.length() - 1) == '.' : str;
  105. }
  106. }
  107. catch (SecurityException | ClassNotFoundException e) {
  108. // No-op. Default value will be returned.
  109. }
  110. return str;
  111. }
  112. @Override protected String getParameterName(MBeanOperationInfo op, MBeanParameterInfo param, int seq) {
  113. String str = super.getParameterName(op, param, seq);
  114. try {
  115. Method m = getMethod(op);
  116. MXBeanParametersNames namesAnn = m.getAnnotation(MXBeanParametersNames.class);
  117. if (namesAnn != null) {
  118. assert namesAnn.value() != null;
  119. assert seq < namesAnn.value().length;
  120. str = namesAnn.value()[seq];
  121. assert str != null;
  122. assert str.trim().length() > 0;
  123. }
  124. }
  125. catch (SecurityException | ClassNotFoundException e) {
  126. // No-op. Default value will be returned.
  127. }
  128. return str;
  129. }
  130. private Method getMethod(MBeanOperationInfo op) throws ClassNotFoundException, SecurityException {
  131. String methodName = op.getName();
  132. MBeanParameterInfo[] signature = op.getSignature();
  133. Class<?>[] params = new Class<?>[signature.length];
  134. for (int i = 0; i < signature.length; i++) {
  135. // Parameter type is either a primitive type or class. Try both.
  136. Class<?> type = primCls.get(signature[i].getType().toLowerCase());
  137. if (type == null)
  138. type = Class.forName(signature[i].getType());
  139. params[i] = type;
  140. }
  141. return findMethod(getMBeanInterface(), methodName, params);
  142. }
  143. @SuppressWarnings("unchecked")
  144. private Method findMethod(Class itf, String methodName, Class[] params) {
  145. assert itf.isInterface() == true;
  146. Method res = null;
  147. // Try to get method from given interface.
  148. try {
  149. res = itf.getDeclaredMethod(methodName, params);
  150. if (res != null)
  151. return res;
  152. }
  153. catch (NoSuchMethodException e) {
  154. // No-op. Default value will be returned.
  155. }
  156. // Process recursively super interfaces.
  157. Class[] superItfs = itf.getInterfaces();
  158. for (Class superItf: superItfs) {
  159. res = findMethod(superItf, methodName, params);
  160. if (res != null)
  161. return res;
  162. }
  163. return res;
  164. }
  165. }

有了上面这些后,怎么使用呢,直接注册mxbean就可以了,如下代码

  1. Hello bean = new Hello("aloxcbbbb",34,"tret@gmail.com");
  2. bean.addBook(new Book("abook",34.0));
  3. MBeanServer server = ManagementFactory.getPlatformMBeanServer();
  4. StandardMBean standardMBean = new StandardMBean(bean,HelloMXBean.class);
  5. MBeanInfo info = standardMBean.getMBeanInfo();
  6. server.registerMBean(standardMBean,new ObjectName("com.github.aloxc.mbean:type=Hello"));

接下来可以jconsole来连接ignite的jmx端口查看下有些什么东西~自己去验证看看有些什么,,,,

x

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注