• JMX的MBean和MXBean的区别


    简介

    不了解JMX的可以看上一篇文章JMX简单入门,MBean表示被管理的资源,MXBean其实也是被管理的资源,但MBean的属性中不能包含自定义对象,而MXBean可以。

    MBean

    定义MBean接口,必须以MBean结尾

    public interface HelloMBean {
    
      String getName();
    
      void setName(String name);
    
      String getAge();
    
      void setAge(String age);
    
      User getUser();
    
      void setUser(User user);
    
    }
    

    定义MBean实现类

    public class Hello implements HelloMBean {
    
      private String name;
    
      private String age;
    
      private User user;
    
      public User getUser() {
        System.out.println("get user 123");
        return user;
      }
    
      public void setUser(User user) {
        System.out.println("set user 123");
        this.user = user;
      }
    
      public String getName() {
        System.out.println("get name 123");
        return name;
      }
    
      public void setName(String name) {
        System.out.println("set name 123");
        this.name = name;
      }
    
      public String getAge() {
        System.out.println("get age 123");
        return age;
      }
    
      public void setAge(String age) {
        System.out.println("set age 123");
        this.age = age;
      }
      // 自定义对象
      public static class User {
    
        private String username;
        private String password;
    
        public User() {
    
        }
    
        public User(String username, String password) {
          this.username = username;
          this.password = password;
        }
    
        public void setPassword(String password) {
          this.password = password;
        }
    
        public void setUsername(String username) {
          this.username = username;
        }
    
        public String getPassword() {
          return password;
        }
    
        public String getUsername() {
          return username;
        }
    
    
      }
    }
    

    定义适配层

    public class HelloAgent {
    
      public static void main(String[] args) throws JMException, Exception {
        MBeanServer server = ManagementFactory.getPlatformMBeanServer();
        //规范 域名:name=MBean名称
        ObjectName helloName = new ObjectName("jmxBean:name=hello");
        //注册MBean
        Hello hello = new Hello();
        hello.setAge("12");
        hello.setName("lisi");
        hello.setUser(new User("lisi", "123"));
        server.registerMBean(hello, helloName);
        Thread.sleep(60 * 60 * 1000);
      }
    }
    

    使用jconsole连接

    可以看到MBean中的User对象是不可用的

    MXBean

    定义接口,必须必MXBean结尾或类上有@MXBean注解且value为true,注意不能以MBean结尾

    @MXBean
    public interface HelloBean {
    
      String getName();
    
      void setName(String name);
    
      String getAge();
    
      void setAge(String age);
    
      User getUser();
    
      void setUser(User user);
    
    }
    

    定义实现类

    public class Hello implements HelloBean {
    
      private String name;
    
      private String age;
    
      private User user;
    
      public User getUser() {
        System.out.println("get user 123");
        return user;
      }
    
      public void setUser(User user) {
        System.out.println("set user 123");
        this.user = user;
      }
    
      public String getName() {
        System.out.println("get name 123");
        return name;
      }
    
      public void setName(String name) {
        System.out.println("set name 123");
        this.name = name;
      }
    
      public String getAge() {
        System.out.println("get age 123");
        return age;
      }
    
      public void setAge(String age) {
        System.out.println("set age 123");
        this.age = age;
      }
      //自定义对象
      public static class User {
    
        private String username;
        private String password;
    
        public User() {
    
        }
    
        public User(String username, String password) {
          this.username = username;
          this.password = password;
        }
    
        public void setPassword(String password) {
          this.password = password;
        }
    
        public void setUsername(String username) {
          this.username = username;
        }
    
        public String getPassword() {
          return password;
        }
    
        public String getUsername() {
          return username;
        }
    
      }
    }
    

    定义适配层

    public class HelloAgent {
    
      public static void main(String[] args) throws JMException, Exception {
        MBeanServer server = ManagementFactory.getPlatformMBeanServer();
        //规范 域名:name=MBean名称
        ObjectName helloName = new ObjectName("jmxBean:name=hello");
        //注册MBean
        Hello hello = new Hello();
        hello.setAge("12");
        hello.setName("lisi");
        hello.setUser(new User("lisi", "123"));
        server.registerMBean(hello, helloName);
        Thread.sleep(60 * 60 * 1000);
      }
    }
    

    jconsole连接


    可以看到MXBean中的User属性包装成了CompositeDataSupport对象

    源码解析

    class MXBeanIntrospector extends MBeanIntrospector<ConvertingMethod> {
        @Override
        MBeanAttributeInfo getMBeanAttributeInfo(String attributeName,
                ConvertingMethod getter, ConvertingMethod setter) {
    
            final boolean isReadable = (getter != null);
            final boolean isWritable = (setter != null);
            final boolean isIs = isReadable && getName(getter).startsWith("is");
    
            final String description = attributeName;
    
            final OpenType<?> openType;
            final Type originalType;
            if (isReadable) {
                openType = getter.getOpenReturnType();
                originalType = getter.getGenericReturnType();
            } else {
                openType = setter.getOpenParameterTypes()[0];
                originalType = setter.getGenericParameterTypes()[0];
            }
            Descriptor descriptor = typeDescriptor(openType, originalType);
            if (isReadable) {
                descriptor = ImmutableDescriptor.union(descriptor,
                        getter.getDescriptor());
            }
            if (isWritable) {
                descriptor = ImmutableDescriptor.union(descriptor,
                        setter.getDescriptor());
            }
    
            final MBeanAttributeInfo ai;
            if (canUseOpenInfo(originalType)) {
                ai = new OpenMBeanAttributeInfoSupport(attributeName,
                                                       description,
                                                       openType,
                                                       isReadable,
                                                       isWritable,
                                                       isIs,
                                                       descriptor);
            } else {
                ai = new MBeanAttributeInfo(attributeName,
                                            originalTypeString(originalType),
                                            description,
                                            isReadable,
                                            isWritable,
                                            isIs,
                                            descriptor);
            }
            // could also consult annotations for defaultValue,
            // minValue, maxValue, legalValues
    
            return ai;
        }
        private static boolean canUseOpenInfo(Type type) {
            if (type instanceof GenericArrayType) {
                return canUseOpenInfo(
                    ((GenericArrayType) type).getGenericComponentType());
            } else if (type instanceof Class<?> && ((Class<?>) type).isArray()) {
                return canUseOpenInfo(
                    ((Class<?>) type).getComponentType());
            }
            return (!(type instanceof Class<?> && ((Class<?>) type).isPrimitive()));
        }
    }
    

    MBean中的属性为MBeanAttributeInfo对象,而MXBean中的自定义对象属性为OpenMBeanAttributeInfoSupport对象

    private final class CompositeMapping extends NonNullMXBeanMapping {
            
            @Override
            final Object toNonNullOpenValue(Object value)
                    throws OpenDataException {
                CompositeType ct = (CompositeType) getOpenType();
                if (value instanceof CompositeDataView)
                    return ((CompositeDataView) value).toCompositeData(ct);
                if (value == null)
                    return null;
    
                Object[] values = new Object[getters.length];
                for (int i = 0; i < getters.length; i++) {
                    try {
                        Object got = MethodUtil.invoke(getters[i], value, (Object[]) null);
                        values[i] = getterMappings[i].toOpenValue(got);
                    } catch (Exception e) {
                        throw openDataException("Error calling getter for " +
                                                itemNames[i] + ": " + e, e);
                    }
                }
                return new CompositeDataSupport(ct, itemNames, values);
            }
        }
    }
    

    当jconsole访问User对象时,将User对象转换成CompositeDataSupport对象。

  • 相关阅读:
    C++学习基础十一——子类对象向父类对象的转化
    C++学习基础十——子类构造函数与析构函数的执行
    C++学习基础九——继承
    浅谈OpenGL变换矩阵
    笔记-Ajax[3]-ajax类终极版;
    笔记-Ajax[1]-的整体流程。
    笔记-[js兼容]-滚动条的滚动距离的兼容性问题解决方法。
    JS中的一些不常用的知识点。
    笔记-[面向对象]-JS基于面向对象编程-[2]
    笔记-[面向对象]-JS基于面向对象编程-[1]
  • 原文地址:https://www.cnblogs.com/strongmore/p/14056758.html
Copyright © 2020-2023  润新知