模板模式和反射模式的利用

前些天,写一个监控程序,为了可扩展监控的类型,用反射和模板做了一个插件形式的代码。

1、通过dubbo做远程调用,接口参数CollectCommandBean如下:

package com.cloudeye.common.bean.collect;

import java.util.List;

import com.cloudeye.common.bean.BaseBean;
import com.cloudeye.common.bean.metric.MetricBean;
import com.cloudeye.common.bean.plugin.PluginBean;
import com.cloudeye.common.bean.resource.ConnectionBean;
import com.cloudeye.common.bean.resource.ResourceBean;

public class CollectCommandBean extends BaseBean {

    private static final long serialVersionUID = 1L;

    String commandId;
    ResourceBean resource;
    ConnectionBean connection;

    PluginBean plugin;//这是是存插件类的类名

    List<MetricBean> metricList;

    public CollectCommandBean() {}

    public CollectCommandBean(String commandId) {
        this.commandId = commandId;
    }
    public String getCommandId() {
        return commandId;
    }
    public void setCommandId(String commandId) {
        this.commandId = commandId;
    }
    public ResourceBean getResource() {
        return resource;
    }
    public void setResource(ResourceBean resource) {
        this.resource = resource;
    }
    public ConnectionBean getConnection() {
        return connection;
    }
    public void setConnection(ConnectionBean connection) {
        this.connection = connection;
    }
    public PluginBean getPlugin() {
        return plugin;
    }
    public void setPlugin(PluginBean plugin) {
        this.plugin = plugin;
    }
    public List<MetricBean> getMetricList() {
        return metricList;
    }
    public void setMetricList(List<MetricBean> metricList) {
        this.metricList = metricList;
    }
}

2、创建一个模板接口

public interface AgentBasePlugin<T> {
//获取连接
    T getConnection(ConnectionBean connection);
//返回连接
    void returnConnection(ConnectionBean connection);
//探测指标
    public List<MetricIndividualBean> detect(String commandId, ResourceBean resource,
            ConnectionBean connection, List<MetricProbeBean> metricProbeList);
//采集指标
    public List<MetricMonitorDataBean> collect(String commandId, ConnectionBean connection,
            List<MetricBean> metricList);

}

3、创建一个处理类,来实例化AgentBasePlugin接口

public class AgentProxyHandler extends AbstractInvocationHandler {
    private Object proxied;
    public AgentProxyHandler(Object proxied) {
        this.proxied = proxied;
    }
    @Override
    protected Object handleInvocation(Object proxy, Method method, Object[] args) throws Throwable {
        return method.invoke(proxied, args);
    }

}


4、创建一个service,传入CollectCommandBean ,通过plugin中的类名实例化出的类(这个类必须实现AgentBasePlugin借口),调用模板方法,返回给dubbo接口

package com.cloudeye.agent.core.service.impl;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import com.cloudeye.agent.core.handler.AgentProxyHandler;
import com.cloudeye.agent.core.plugin.base.AgentBasePlugin;
import com.cloudeye.agent.core.service.AgentCallPluginService;
import com.cloudeye.common.bean.collect.CollectCommandBean;
import com.cloudeye.common.bean.collect.CollectResultBean;
import com.cloudeye.common.bean.detect.DetectCommandBean;
import com.cloudeye.common.bean.detect.DetectResultBean;
import com.cloudeye.common.bean.metric.MetricBean;
import com.cloudeye.common.bean.metric.MetricIndividualBean;
import com.cloudeye.common.bean.metric.MetricProbeBean;
import com.cloudeye.common.bean.monitor.MetricMonitorDataBean;
import com.cloudeye.common.bean.resource.ConnectionBean;
import com.cloudeye.common.bean.resource.ResourceBean;
import com.google.common.reflect.AbstractInvocationHandler;
import com.google.common.reflect.Reflection;
@Service
public class AgentCallPluginServiceImpl implements AgentCallPluginService {

    private static final Logger logger = LoggerFactory.getLogger(AgentCallPluginServiceImpl.class);

    public CollectResultBean callCollect(CollectCommandBean collectCommand) {
        logger.debug("Collect:[{}]", collectCommand.toString());
        CollectResultBean result = new CollectResultBean(collectCommand.getCommandId());
        String pluginClass = collectCommand.getPlugin().getPluginClass();
        ConnectionBean connect = collectCommand.getConnection();
        List<MetricBean> metricList = collectCommand.getMetricList();
        ResourceBean resource = collectCommand.getResource();
        result.setResource(resource);
        Class<?> clazz;
        try {
            clazz = Class.forName(pluginClass);
            AbstractInvocationHandler handler = new AgentProxyHandler(clazz.newInstance());
            AgentBasePlugin<?> plugin = Reflection.newProxy(AgentBasePlugin.class, handler);
            List<MetricMonitorDataBean> metricMonitorDataList =
                    plugin.collect(collectCommand.getCommandId(), connect, metricList);
            result.setMetricMonitorDataList(metricMonitorDataList);
        } catch (Exception e) {
            logger.error("Plugin error: [{}]", pluginClass, e);
        }
        return result;
    }

    @Override
    public DetectResultBean callDetect(DetectCommandBean detectCommand) {
        logger.debug("Detect:[{}]", detectCommand.toString());
        DetectResultBean result = new DetectResultBean(detectCommand.getCommandId());
        String pluginClass = detectCommand.getPlugin().getPluginClass();
        ConnectionBean connect = detectCommand.getConnection();
        List<MetricProbeBean> metricProbeList = detectCommand.getMetricProbeList();
        ResourceBean resource = detectCommand.getResource();
        result.setResource(resource);
        Class<?> clazz;
        try {
            clazz = Class.forName(pluginClass);
            AbstractInvocationHandler handler = new AgentProxyHandler(clazz.newInstance());
            AgentBasePlugin<?> plugin = Reflection.newProxy(AgentBasePlugin.class, handler);
            List<MetricIndividualBean> metricIndividualList =
                    plugin.detect(detectCommand.getCommandId(), resource, connect, metricProbeList);
            result.setMetricIndividualList(metricIndividualList);
        } catch (Exception e) {
            logger.error("Plugin error: [{}]", pluginClass, e);
        }
        return result;
    }
}

5、demo插件

package com.cloudeye.agent.plugin.demo;

import java.util.List;

import com.cloudeye.agent.core.plugin.AgentAbstractPlugin;
import com.cloudeye.common.bean.metric.MetricBean;
import com.cloudeye.common.bean.monitor.MetricMonitorDataBean;
import com.cloudeye.common.bean.resource.ConnectionBean;
import com.google.common.collect.Lists;

public class PLUGDemoPlugin implements AgentBasePlugin<String> {
    @Override
    public List<MetricMonitorDataBean> collect(String commandId,ConnectionBean connection,
            List<MetricBean> metricList) {
        List<MetricMonitorDataBean> list = Lists.newArrayList();
        MetricMonitorDataBean bean = new MetricMonitorDataBean();
        bean.setMetId(1l);
        bean.setMetKey("test");
        bean.setMetValue(100.0);
        list.add(bean);
        return list;
    }

    @Override
    public String getConnection(ConnectionBean connection) {
        return null;
    }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值