JMX中MBean实现

对于MBean,存在于动态MBean和静态MBean。


静态:顾名思义,即对象设置好后,聚焦到JAVA的类对象上,则不能进行增加类的属性和方法。

动态:顾名思义,即在程序运行过程中,可以对MBean进行动态的增加属性和方法。


但大多数场景中,使用静态已经足够满足我们的需求。示例代码:

package com.zte.sunquan.demo.jms;

import com.google.common.collect.Lists;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;

import javax.management.AttributeChangeNotification;
import javax.management.MBeanInfo;
import javax.management.MBeanServer;
import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;
import java.lang.management.ManagementFactory;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;


/**
 * Created by sunquan on 2017/9/18.
 */
public class JSMBeanTest {
    String jmxServerName = "SQTestBean";
    private Person person;
    private ObjectName path;

    @Before
    public void init() throws MalformedObjectNameException {
        person = new Person("sunquan", 28, PersonMBean.Gender.boy,
                Lists.newArrayList("Java8", "Netty"),
                new long[]{1L, 2L},
                new Integer[]{3, 4},
                new byte[]{5, 6},
                Lists.newArrayList(new Hobby("running")));
        //eg.SQTestBean:type=Person,name=sunquan
        path = new ObjectName(jmxServerName + ":type=" + Person.class.getSimpleName()
                + ",name=" + person.getName());
    }

    @Test
    public void testMBean() throws Exception {
        CountDownLatch latch = new CountDownLatch(1);
        MBeanServer server = ManagementFactory.getPlatformMBeanServer();
        //将mbean绑定到指定path上
        server.registerMBean(person, path);
        TimeUnit.SECONDS.sleep(2);
        //取数据
        MBeanInfo mBeanInfo = server.getMBeanInfo(path);
        Assert.assertEquals(mBeanInfo.getClassName(), Person.class.getName());

        Assert.assertEquals("sunquan", server.getAttribute(path, "Name"));
        Assert.assertEquals(28, server.getAttribute(path, "Age"));
        Assert.assertEquals(PersonMBean.Gender.boy, server.getAttribute(path, "Gender"));
        Assert.assertTrue(((List<String>) server.getAttribute(path, "Hobby")).size() == 1);
//        latch.await();
    }
    @Test
    public void dynamicMBean()throws Exception {
        CountDownLatch latch = new CountDownLatch(1);
        MBeanServer server = ManagementFactory.getPlatformMBeanServer();
        ObjectName helloName = new ObjectName("jmx:name=dynamicBeanHello");
        server.registerMBean(new BillInfo(), helloName);
        latch.await();
//        HtmlAdaptorServer adaptor  = new HtmlAdaptorServer();
//        ObjectName adaptorName = new ObjectName("jmxAdaptor:name=adaptor,port=5050");
//        server.registerMBean(adaptor, adaptorName);
//        adaptor.setPort(9999);
//        adaptor.start();
        System.out.println("....................jmx server start....................");
    }

    @Test
    public void dynamicMBean2()throws Exception {
        CountDownLatch latch = new CountDownLatch(1);
        MBeanServer server = ManagementFactory.getPlatformMBeanServer();
        ObjectName helloName = new ObjectName("jmx:name=dynamicBeanHello");
        Bill bill = new Bill();
        server.registerMBean(bill, helloName);
        Thread.sleep(10000);
        bill.addAttribute();
        latch.await();
    }

    @Test
    public void notifyMBean()throws Exception {
        CountDownLatch latch = new CountDownLatch(1);
        MBeanServer server = ManagementFactory.getPlatformMBeanServer();
        ObjectName helloName = new ObjectName("jmx:name=notifyBeanHello");
        Account account = new Account();
        server.registerMBean(account, helloName);
        server.addNotificationListener(helloName,(notification,b)->{
            System.out.println("SequenceNumber:" + notification.getSequenceNumber());
            System.out.println("Type:" + notification.getType());
            System.out.println("Message:" + notification.getMessage());
            System.out.println("Source:" + notification.getSource());
            System.out.println("TimeStamp:" + notification.getTimeStamp());
            System.out.println("userData:"+notification.getUserData());
            System.out.println("bach:"+b);
            if(notification instanceof AttributeChangeNotification){
                AttributeChangeNotification no = (AttributeChangeNotification) notification;
                System.out.println("OldValue:"+no.getOldValue());
                System.out.println("NewValue:"+no.getNewValue());
            }
        },null,null);

        latch.await();
    }
}



package com.zte.sunquan.demo.jms;

import java.util.List;

/**
 * Created by sunquan on 2017/9/29.
 */
public interface PersonMBean {
    String getName();

    void setName(String name);

    int getAge();

    Gender getGender();

    List<String> getBooks();

    long[] getLongs();

    Integer[] getIntegers();

    byte[] getBytes();

    List<Hobby> getHobby();

    void printHello();

    void printHello(String whoName);

    enum Gender {
        boy, girl;
    }
}

package com.zte.sunquan.demo.jms;

import java.util.List;

/**
 * Created by sunquan on 2017/9/29.
 */
public class Person implements PersonMBean {


    private String name;
    private int age;
    private Gender gender;
    private List<String> books;
    private long[] longs;
    private Integer[] integers;
    private byte[] bytes;
    private List<Hobby> hobbies;
    public Person(){

    }
    public Person(String name, int age, Gender gender){
        this.name = name;
        this.age = age;
        this.gender = gender;
    }
    public Person(String name, int age, Gender gender, List<String> books, long[] longs, Integer[] integers, byte[] bytes, List<Hobby> hobbies) {
        this.name = name;
        this.age = age;
        this.gender = gender;
        this.books = books;
        this.longs = longs;
        this.integers = integers;
        this.bytes = bytes;
        this.hobbies = hobbies;
    }

    @Override
    public String getName() {
        return name;
    }

    @Override
    public void setName(String name) {
        this.name = name;
    }

    @Override
    public int getAge() {
        return age;
    }

    @Override
    public Gender getGender() {
        return gender;
    }

    @Override
    public List<String> getBooks() {
        return books;
    }

    @Override
    public long[] getLongs() {
        return longs;
    }

    @Override
    public Integer[] getIntegers() {
        return integers;
    }

    @Override
    public byte[] getBytes() {
        return bytes;
    }

    @Override
    public List<Hobby> getHobby() {
        return hobbies;
    }

    @Override
    public void printHello() {
        System.out.println("hello,world");
    }

    @Override
    public void printHello(String whoName) {
        System.out.println("hello,world-" + whoName);
    }
}

package com.zte.sunquan.demo.jms;

import javax.management.Attribute;
import javax.management.AttributeList;
import javax.management.DynamicMBean;
import javax.management.MBeanAttributeInfo;
import javax.management.MBeanConstructorInfo;
import javax.management.MBeanException;
import javax.management.MBeanInfo;
import javax.management.MBeanNotificationInfo;
import javax.management.MBeanOperationInfo;
import javax.management.MBeanParameterInfo;
import javax.management.ReflectionException;
import java.lang.reflect.Constructor;
import java.util.Iterator;

/**
 * Created by sunquan on 2017/9/29.
 */
public class BillInfo implements DynamicMBean {
    //attributes
    private String name;
    private MBeanInfo mBeanInfo = null;
    private String className;
    private String description;
    private MBeanAttributeInfo[] attributes;
    private MBeanConstructorInfo[] constructors;
    private MBeanOperationInfo[] operations;
    MBeanNotificationInfo[] mBeanNotificationInfoArray;

    public BillInfo() {
        init();
        buildDynamicMBean();
    }

    private void init() {
        className = this.getClass().getName();
        description = "Simple implementation of a MBean.";

        //initial attributes
        attributes = new MBeanAttributeInfo[1];
        //initial constructors
        constructors = new MBeanConstructorInfo[1];
        //initial method
        operations = new MBeanOperationInfo[1];

        mBeanNotificationInfoArray = new MBeanNotificationInfo[0];
    }

    private void buildDynamicMBean() {
        //create constructor
        Constructor[] thisconstructors = this.getClass().getConstructors();
        constructors[0] = new MBeanConstructorInfo("HelloDynamic(): Constructs a HelloDynamic object", thisconstructors[0]);

        //create attribute
        attributes[0] = new MBeanAttributeInfo("Name", "java.lang.String", "Name: name string.", true, true, false);

        //create operate method
        MBeanParameterInfo[] params = null;//no parameter
        operations[0] = new MBeanOperationInfo("print", "print(): print the name", params, "void", MBeanOperationInfo.INFO);

        //create mbean
        mBeanInfo = new MBeanInfo(className, description, attributes, constructors, operations, mBeanNotificationInfoArray);
    }

    //dynamically add a print1 method
    private void dynamicAddOperation() {
        init();
        operations = new MBeanOperationInfo[2];
        buildDynamicMBean();
        operations[1] = new MBeanOperationInfo("print1", "print1(): print the name", null, "void", MBeanOperationInfo.INFO);
        mBeanInfo = new MBeanInfo(className, description, attributes, constructors, operations, mBeanNotificationInfoArray);
    }

    @Override
    public Object getAttribute(String attribute_name) {
        if (attribute_name == null) {
            return null;
        }

        if (attribute_name.equals("Name")) {
            return name;
        }

        return null;
    }

    @Override
    public void setAttribute(Attribute attribute) {
        if (attribute == null) {
            return;
        }

        String Name = attribute.getName();
        Object value = attribute.getValue();
        try {
            if (Name.equals("Name")) {
                // if null value, try and if the setter returns any exception
                if (value == null) {
                    name = null;
                    // if non null value, make sure it is assignable to the attribute
                } else if ((Class.forName("java.lang.String")).isAssignableFrom(value.getClass())) {
                    name = (String) value;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public AttributeList getAttributes(String[] attributeNames) {
        if (attributeNames == null) {
            return null;
        }

        AttributeList resultList = new AttributeList();
        // if attributeNames is empty, return anempty result list
        if (attributeNames.length == 0) {
            return resultList;
        }

        for (int i = 0; i < attributeNames.length; i++) {
            try {
                Object value = getAttribute(attributeNames[i]);
                resultList.add(new Attribute(attributeNames[i], value));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return resultList;
    }

    @Override
    public AttributeList setAttributes(AttributeList attributes) {
        if (attributes == null) {
            return null;
        }

        AttributeList resultList = new AttributeList();
        // if attributeNames is empty, nothing more to do
        if (attributes.isEmpty()) {
            return resultList;
        }

        // for each attribute, try to set it and add to the result list if successfull
        for (Iterator i = attributes.iterator(); i.hasNext(); ) {
            Attribute attr = (Attribute) i.next();
            try {
                setAttribute(attr);
                String name = attr.getName();
                Object value = getAttribute(name);
                resultList.add(new Attribute(name, value));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return resultList;
    }

    @Override
    public Object invoke(String operationName, Object params[], String signature[]) throws MBeanException, ReflectionException {
        // Check for a recognized operationname and call the corresponding operation
        if (operationName.equals("print")) {
            System.out.println("Hello, " + name + ", this is HelloDynamic!");

            //dynamic add a method
            dynamicAddOperation();
            return null;
        } else if (operationName.equals("print1")) {
            System.out.println("dynamically add a print1 method");
            return null;
        } else {
            // unrecognized operation name:
            throw new ReflectionException(new NoSuchMethodException(operationName), "Cannot find the operation " + operationName + " in " + className);
        }

    }

    public MBeanInfo getMBeanInfo() {
        return mBeanInfo;
    }
}

package com.zte.sunquan.demo.jms;

import javax.management.Attribute;
import javax.management.AttributeList;
import javax.management.AttributeNotFoundException;
import javax.management.DynamicMBean;
import javax.management.InvalidAttributeValueException;
import javax.management.MBeanAttributeInfo;
import javax.management.MBeanConstructorInfo;
import javax.management.MBeanException;
import javax.management.MBeanInfo;
import javax.management.ReflectionException;
import java.lang.reflect.Constructor;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Optional;

/**
 * Created by sunquan on 2017/9/30.
 * 新增属性
 */
public class Bill implements DynamicMBean {

    private Map<String, Long> prices = new HashMap<>();
    private MBeanInfo mBeanInfo;
    private MBeanAttributeInfo[] attributes;

    private MBeanConstructorInfo[] mBeanConstructorInfos;

    public Bill() {
        Constructor[] constructors = this.getClass().getConstructors();
        MBeanConstructorInfo mBeanConstructorInfo = new MBeanConstructorInfo("constructors", constructors[0]);
        mBeanConstructorInfos = new MBeanConstructorInfo[1];
        mBeanConstructorInfos[0] = mBeanConstructorInfo;
        mBeanInfo = new MBeanInfo(this.getClass().getName(),
                "description", attributes, mBeanConstructorInfos,
                null, null);
    }

    /**
     * 方法 动态新增属性,需要重新实例化mBeanInfo
     */
    public void addAttribute() {
        attributes = new MBeanAttributeInfo[1];
        attributes[0] = new MBeanAttributeInfo("price1", "java.lang.String", "price11", true, true, false);
        prices.put("price1", 100L);
        mBeanInfo = new MBeanInfo(this.getClass().getName(),
                "description", attributes, mBeanConstructorInfos,
                null, null);
    }

    @Override
    public Object getAttribute(String attribute) throws AttributeNotFoundException, MBeanException, ReflectionException {
        System.out.println("getAttribute");
        return Optional.ofNullable(prices.get(attribute)).orElse(0L);
    }

    @Override
    public void setAttribute(Attribute attribute) throws AttributeNotFoundException, InvalidAttributeValueException, MBeanException, ReflectionException {
        System.out.println("setAttribute");
        prices.put(attribute.getName(), Long.parseLong(attribute.getValue().toString()));
    }

    @Override
    public AttributeList getAttributes(String[] attributes) {
        //通过该方法获取属性名与值
        System.out.println("getAttributes");
        AttributeList resultList = new AttributeList();
        for (String attr : attributes) {
            try {
                resultList.add(new Attribute(attr, getAttribute(attr)));
            } catch (AttributeNotFoundException e) {
                e.printStackTrace();
            } catch (MBeanException e) {
                e.printStackTrace();
            } catch (ReflectionException e) {
                e.printStackTrace();
            }
        }
        return resultList;
    }

    @Override
    public AttributeList setAttributes(AttributeList attributes) {
        AttributeList resultList = new AttributeList();
        for (Iterator i = attributes.iterator(); i.hasNext(); ) {
            Attribute attr = (Attribute) i.next();
            try {
                setAttribute(attr);
                String name = attr.getName();
                Object value = getAttribute(name);
                resultList.add(new Attribute(name, value));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return resultList;
    }

    @Override
    public Object invoke(String actionName, Object[] params, String[] signature) throws MBeanException, ReflectionException {
        return null;
    }

    @Override
    public MBeanInfo getMBeanInfo() {
        return mBeanInfo;
    }
}

package com.zte.sunquan.demo.jms;

import javax.management.AttributeChangeNotification;
import javax.management.NotificationBroadcasterSupport;
import java.util.concurrent.atomic.AtomicLong;

/**
 * Created by sunquan on 2017/9/30.
 */
public class Account extends NotificationBroadcasterSupport implements AccountMBean {
    private AtomicLong sequenceNumber = new AtomicLong(1);
    private String name;

    @Override
    public void setName(String name) {
        AttributeChangeNotification notification = new AttributeChangeNotification(
                this, sequenceNumber.getAndIncrement(),
                System.currentTimeMillis(),
                AttributeChangeNotification.ATTRIBUTE_CHANGE,
                "name",
                "java.lang.String",
                this.name,
                name
        );
        this.name = name;
        super.sendNotification(notification);
    }

    @Override
    public String getName() {
        return name;
    }
}

package com.zte.sunquan.demo.jms;

/**
 * Created by sunquan on 2017/9/30.
 */
public interface AccountMBean {
    void setName(String name);

    String getName();
}


为使MBEAN可以远程访问,需要增加程序的启动参数

-Dcom.sun.management.jmxremote -Djava.rmi.server.hostname=127.0.0.1 -Dcom.sun.management.jmxremote.port=911 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false

代码中远程获取Bean  关于jmxUrl  如

service:jmx:rmi:///jndi/rmi://0.0.0.0:1099/jmxrmi

    public static MBeanServerConnection getMBeanServerConnection(final String rmiJmxUrl, final String user, final String password) {
        try {
            if (rmiJmxUrl == null) {
                MBeanServerConnection mbeanServer = ManagementFactory.getPlatformMBeanServer();
                return mbeanServer;
            } else {
                HashMap<String, String[]> environment = new HashMap<String, String[]>();
                if ((user == null) || (password == null)) {
                    String[] creds = {"karaf", "karaf"};
                    environment.put(JMXConnector.CREDENTIALS, creds);
                } else {
                    String[] creds = {user, password};
                    environment.put(JMXConnector.CREDENTIALS, creds);
                }

                if (rmiJmxUrl != null) {
                    JMXServiceURL url = new JMXServiceURL(rmiJmxUrl);
                    JMXConnector connector = JMXConnectorFactory.connect(url, environment);
                    MBeanServerConnection mbeanServer = connector.getMBeanServerConnection();
                    return mbeanServer;
                }
            }
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

测试用例:Path SQTestBean:type=Person,name=sunquan

    @Test
    public void testRemoteMBean() throws Exception {
        CountDownLatch latch = new CountDownLatch(1);
        MBeanServer server = ManagementFactory.getPlatformMBeanServer();
        //将mbean绑定到指定path上
        server.registerMBean(person, path);
        TimeUnit.SECONDS.sleep(2);
        //取数据

        MBeanServerConnection mBeanServerConnection =
                getMBeanServerConnection("service:jmx:rmi:///jndi/rmi://10.42.197.153:1099/jmxrmi", "a", "b");
        MBeanInfo mBeanInfo = mBeanServerConnection.getMBeanInfo(path);

        Assert.assertEquals(mBeanInfo.getClassName(), Person.class.getName());
        Assert.assertEquals("sunquan", server.getAttribute(path, "Name"));
        Assert.assertEquals(28, server.getAttribute(path, "Age"));
        Assert.assertEquals(PersonMBean.Gender.boy, server.getAttribute(path, "Gender"));
        Assert.assertTrue(((List<String>) server.getAttribute(path, "Hobby")).size() == 1);
//        latch.await();
    }

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值