1、读取配置文件工具类

public class PropUtil {

    public static Properties loadConfig(String configPath) throws Exception {
        Properties prop = new Properties();
        InputStream _file = null;
        try {
            //String file = PropUtil.class.getResource(configPath).getFile();
            //PropUtil.class.getResourceAsStream(configPath);
            //System.out.println("mq_conf:" + file);
            //file = URLDecoder.decode(file);
            //和classes文件夹在同一目录下,因此此处读取的配置文件要放在src目录下,这样编译后的配置文件才能放到classes同级目录下
            _file = PropUtil.class.getResourceAsStream(configPath);
            prop.load(_file);
        } catch (Exception e) {
            e.printStackTrace();
            try {
                System.out.println("读取jar中的配置文件....");
                String currentJarPath = URLDecoder.decode(PropUtil.class.getProtectionDomain()
                        .getCodeSource().getLocation().getFile(), "UTF-8"); // 获取当前Jar文件名
                System.out.println("currentJarPath:" + currentJarPath);
                java.util.jar.JarFile currentJar = new java.util.jar.JarFile(currentJarPath);
                java.util.jar.JarEntry dbEntry = currentJar.getJarEntry("mq_conf.properties");
                InputStream in = currentJar.getInputStream(dbEntry);
                _file = in;
            } catch (Exception e2) {
                e2.printStackTrace();
            }
        }
        return prop;
    }

读取src目录下存储的 properties 配置文件,如果读取失败就默认读取 jar包里面的 mq配置文件 mq_conf.properties。

举例使用工具类读取 src/attribute.properties 配置文件:

// 安检
            Properties prop = PropUtil.loadConfig("/attribute.properties");
            String isCheck = prop.getProperty("isCheck");
            if(!StringUtil.isNull(isCheck) && isCheck.equals("1")){
                vo.setTeacherId(userBean.getUserId());
                vo.setIsCheck(1);
            }

2、dubbo配置文件:

dubbo是阿里提供的一套rpc服务框架,可实现不同服务间的远程调用,也放到这里做下配置说明。

1、provider
生产者开放 rpc服务,供consumer调用。

1定义dubbo.properties文件
dubbo.application.name=cent-dubbo-service
dubbo.application.owner=wang
#测试用 这里是zk的地址
#dubbo.registry.address=zookeeper://192.168.120.155:2181

dubbo.registry.root.password=root
dubbo.registry.guest.password=guest

#use netty4
#dubbo.reference.client=netty4

#peeper config
#peeper.zookeepers=192.168.120.155:2181
peeper.zookeepers=10.136.2.242:2181

#peeper.zookeepers=10.21.67.21:2181
#peeper.zookeepers=121.201.6.195:2181
peeper.zookeeper.session.timeout=60000

#monitor.lucene.directory=/Users/wangpei/dubbo/logs/lucene
#monitor.lucene.directory=/opt/dubbo/monitor
#logger
monitor.log.home=/Users/wangpei/dubbo/logs/dubbo.log
2、定义 dubbo-provider.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
        http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">

    <description>dubbo服务提供配置 </description>

    <!-- 提供方应用信息,用于计算依赖关系 -->
    <dubbo:application name="${dubbo.application.name}"
            />
    <!-- 注册中心暴露服务地址 这里是个dubbo集群-->
    <!--<dubbo:registry address="${dubbo.registry.address}" file="${monitor.log.home}"/>-->
    <dubbo:registry address="${dubbo.registry.address}" file="/tmp/dubbo.cache"/>
    <!--用dubbo协议在20880端口暴露服务-->
    <dubbo:protocol name="dubbo" port="20880" />


    <!--<!–声名暴露服务接口–>-->
    <dubbo:service  interface="cn.qtone.xxt.api.CentAccountInfoServiceAPI"
                   ref="CentAccountInfoServiceAPI" executes="100" timeout="600000" retries="0" />
    <bean id="CentAccountInfoServiceAPI" class="cn.qtone.xxt.cent.service.Impl.CentAccountInfoServiceImpl" />
</beans>


api接口文档 <cn.qtone.xxt.api>:
cn.qtone.xxt.api.CentAccountInfoServiceAPI

2、consumer 实现对开放的接口进行远程调用。

dubbo-consumer.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.xsd
    http://code.alibabatech.com/schema/dubbo
    http://code.alibabatech.com/schema/dubbo/dubbo.xsd">

    <!-- 提供方应用信息,用于计算依赖关系 -->
    <dubbo:application name="dubbo-service-consumer" />

    <!-- 使用multicast广播注册中心暴露服务地址 -->
    <!-- <dubbo:registry address="multicast://224.5.6.7:1234" /> -->

    <!-- 使用zookeeper注册中心暴露服务地址 -->
    <dubbo:registry address="zookeeper://10.10.75.13:2181" file="/tmp/dubbo.cache"/>
    <!--<dubbo:registry address="zookeeper://10.136.2.242:2181" file="/tmp/dubbo.cache"/>-->
    <!--<dubbo:registry address="zookeeper://172.16.170.89:2181" />-->

    <!--服务提供者 端口-->
    <dubbo:protocol name="dubbo" port="20880" />


    <!--声明需要暴露的服务接口-->
    <dubbo:reference id="CentAccountInfoServiceAPI" interface="cn.qtone.xxt.api.CentAccountInfoServiceAPI" />
    </beans>

3、rabbit mq代码框架

代码框架

java文件中如何读取配置文件的内容 java读取配置文件_java文件中如何读取配置文件的内容

Sender–发送消息类
Recver–接收消息类 implements IReceive
Config–mq消息队列信息读取类
Connect–初始化mq消息队列及链接
IReceive–接口,接收消息处理定义接口方法
MQSender–扩展类,暂时不用

Sender:

import com.alibaba.fastjson.JSONObject;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.MessageProperties;

import java.io.IOException;

/**
 * 路由规则:
 * fanout-> 将发送到Exchange路由到绑定的对应的queue的消息
 * direct-> 完全匹配  会把消息路由到那些binding key与routing key完全匹配的Queue中       Routing Key==Binding Key
 * topic-> 模糊匹配   通过通配符满足一部分规则就可以传送
 * headers-> Exchange不依赖于routing key与binding key的匹配规则来路由消息,而是根据发送的消息内容中的headers属性进行匹配。
 */

public class Sender {
    //private static final Logger log = LoggerFactory.getLogger(BossSyncAction.class);
    public static final boolean durable = false; //消息队列持久化
    /**
     * 发送数据
     * 
     * @param obj
     * @return
     */
    public <T> boolean send(T obj) {
        Channel channel = null;
        try {
            channel = Connect.getChannel();
            channel.exchangeDeclare(Config.EXCHANGE_NAME, "topic");
            channel.queueDeclare(Config.QUEUE_NAME, false, false, false, null);
            channel.queueBind(Config.QUEUE_NAME, Config.EXCHANGE_NAME, Config.BINDING_KEY);
            String message = JSONObject.toJSONString(obj);
            channel.basicPublish(Config.EXCHANGE_NAME, Config.ROUTING_KEY, MessageProperties.PERSISTENT_TEXT_PLAIN,
                    message.getBytes());
            // System.out.println(" [x] Sent '" + message + "'");
        } catch (IOException e) {
            StaticCommend.CAT("MQ Send", e);
            e.printStackTrace();
            return false;
        } finally {
            Connect.disConnect();
        }
        return true;
    }
}

Recver:

import com.opensymphony.xwork2.util.logging.Logger;
import com.opensymphony.xwork2.util.logging.LoggerFactory;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.ConsumerCancelledException;
import com.rabbitmq.client.QueueingConsumer;
import com.rabbitmq.client.ShutdownSignalException;

import java.io.IOException;

/*
 * 接收者
 */
public class Recver {

    private boolean isInit = false;
    private QueueingConsumer consumer;
    private static boolean isShutDown = false;
    private static final boolean durable = false; // 消息队列持久化
    public static final boolean autoAck = false; // 是否接收消息即时回复
    Logger log = LoggerFactory.getLogger(Recver.class);

    public static void shutDown() {
        isShutDown = true;
    }

    public void init() {
        System.out.println("MQ开始初始化");
        try {
            Channel channel = Connect.getChannel();
            // channel.queueDeclare(QUEUE_NAME, false, false, false, null);
            //ExchangeType :direct ,fanout和topic  表现不同的路由行为
            //topic:会按照正则表达式,对RoutingKey与BindingKey进行匹配
            channel.exchangeDeclare(Config.EXCHANGE_NAME, "topic");
            channel.queueDeclare(Config.QUEUE_NAME, durable, false, false, null);
            channel.queueBind(Config.QUEUE_NAME, Config.EXCHANGE_NAME, Config.BINDING_KEY);
            // System.out.println(" [*] Waiting for messages. To exit press CTRL+C");
            if (!autoAck) {
                channel.basicQos(1); // 消息分发处理 公平转发
            }
            //consumer通过channel通道获取message
            consumer = new QueueingConsumer(channel);
            //通过订阅的方式被动的从 queue中消费消息
            //向 queue注册consumer,通过rpc向queue server发送注册consumer消息,rabbitmq server在受到消息后,根据消息的内容判断这是一个订阅消息,
            //这样当mq中queue有消息时,会自动把消息通过该socket长连接通道发送出去
            channel.basicConsume(Config.QUEUE_NAME, autoAck, consumer);
            isInit = true;
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        System.out.println("MQ结束初始化");
    }

    /**
     * 监听
     * 
     * @param receive
     * @param clazz
     */
    public void listening(IReceive receive, Class<?> clazz) {
        if (!isInit)
            init();
        System.out.println("MQ开始监听");
        while (true && !isShutDown) {
            QueueingConsumer.Delivery delivery;
            try {
                 //consumer接收消息过程:
                //启动mainloop线程,循环从socket中获取数据包frame,调用channel.handleFrame处理消息,消息最终放在队列中
                //每个consumer都有一个blockQueue,用于缓存从socket中获取消息,之后就可以调用api来从客户端缓存的_queue中依次获取消息进行消费
                delivery = consumer.nextDelivery();
                String message = new String(delivery.getBody());
                log.info(" [x] MQ consumer Received ======= '" + message + "'");
                // 处理
                receive.dealMsg(JSONUtil.toObject(clazz, message));

                if (!autoAck) {
                    consumer.getChannel().basicAck(delivery.getEnvelope().getDeliveryTag(),
                            false);
                }
            } catch (ShutdownSignalException e) {
                System.out.println("MQ 已关闭,5秒后重连");
                e.printStackTrace();
                try {
                    Thread.sleep(5 * 1000);
                    init();

                } catch (InterruptedException e1) {
                    // TODO Auto-generated catch block
                    e1.printStackTrace();
                }
            } catch (ConsumerCancelledException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

        }
    }
}

Config:

//定义消息队列及消息分发策略
public class Config {

public final static String EXCHANGE_NAME = "cent";
public final static String QUEUE_NAME = "xxt_sd.cent";
public final static String ROUTING_KEY = "xxt_sd.cent.sd";
public final static String BINDING_KEY = "xxt_sd.cent.#";


}

IReceive

//声明接口
public interface IReceive<T> {
    /**
     * 消息接收后处理
     * @param <T>
     */
    public void dealMsg(T msg);
}

Connect:

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import org.apache.commons.lang.StringUtils;

import java.io.IOException;
import java.util.Properties;

/**
   用作mq初始化,建立连接
 * mq服务器连接类
 * 
 * @author yonson
 */
public class Connect {

    private static ThreadLocal<Connection> localConnection = new ThreadLocal<Connection>();

    private static ConnectionFactory factory;

    /*
     * 初始化连接工厂
     */
    public static void initConnectionFactory() {
        Properties prop;
        try {
            prop = PropUtil.loadConfig("/mq_cent_conf.properties");
            factory = new ConnectionFactory();
            factory.setHost(prop.getProperty("MQ.HOST"));
            String account = prop.getProperty("MQ.ACCOUNT");
            if (account != null && account.length() > 0) {
                factory.setUsername(account);
            }
            String pwd = prop.getProperty("MQ.PSW");
            if (pwd != null && pwd.length() > 0) {
                factory.setPassword(pwd);
            }
            String port = prop.getProperty("MQ.PORT");
            if (StringUtils.isNotBlank(port))
                factory.setPort(Integer.parseInt(port));

            String vhost = prop.getProperty("MQ.VIRTUALHOST");
            if (vhost != null && vhost.length() > 0) {
                factory.setVirtualHost(vhost);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取连接频道
     * 
     * @return
     */
    public static Channel getChannel() {
        Channel channel = null;
        Connection conn = getConnect();
        try {
            channel = conn.createChannel();
        } catch (IOException e) {
            StaticCommend.CAT("getChannel", e);
            e.printStackTrace();
        }

        return channel;
    }

    /**
     * 建立连接
     * 
     * @return
     * @throws IOException
     */
    public static Connection getConnect() {
        Connection conn = localConnection.get();
        try {
            if (factory == null) {
                initConnectionFactory();
            }
            if (conn == null) {
                conn = factory.newConnection();
                localConnection.set(conn);
            }
        } catch (Exception e) {
            StaticCommend.CAT("读取mq配置文件出现异常", e);
        }
        return conn;
    }

    /**
     * 关闭连接
     * 
     * @throws IOException
     */
    public static void disConnect() {
        Connection conn = localConnection.get();
        if (conn != null) {
            try {
                conn.close();
            } catch (IOException e) {
                StaticCommend.CAT("MQ disConnect", e);
                e.printStackTrace();
            }
            localConnection.set(null);
        }
    }
}

过程中使用到的工具类:

/**
 * json处理工具类
 */
public class JSONUtil {

    /**
     * 将json数据包装成对应实体
     * 
     * @param clazz
     * @param jsonString
     * @return
     */
    public static <T> T toObject(Class<T> clazz, String jsonString) {
        if (isJsonStr(jsonString))
            return JSON.parseObject(jsonString, clazz);
        else
            return null;
    }

    /**
     * 将对应实体包装成json结构
     * 
     * @param obj
     * @return
     */
    public static <T> String toString(T obj) {
        if (obj != null)
            return JSONObject.toJSONString(obj);
        else
            return null;
    }

    /**
     * 判断是否符合json结构
     * 
     * @param jsonString
     * @return
     */
    public static boolean isJsonStr(String jsonString) {
        if (jsonString != null && jsonString.length() > 0) {
            jsonString = jsonString.trim();
            return jsonString.startsWith("{") && jsonString.endsWith("}") ? true : false;
        }
        return false;
    }

}

在接收mq消息时,要对消息进行实时监听,当监听到mq接收到消息时调用处理方法对消息进行业务处理。

声明监听方法:

public class Listener {

    private static Log log = LogFactory.getLog(Listener.class);
    private final Recver recver = new Recver();

    public void listening() {

        // 设置监听处理    匿名内部类监听消息,对消息做处理
        IReceive<MessageData> iReceive = new IReceive<MessageData>() {

            @Override
            public void dealMsg(MessageData msg) {

                try {
                    //对监听到的mq消息进行处理
                    doItem(msg);

                } catch (Exception e) {
                    //todo
                }
            }
        };
        // 开始监听
        recver.listening(iReceive, MessageData.class);

    }

    /**
     *  对接收到的mq消息进行业务处理
     * @param data
     * @return
     */
    private void doItem(MessageData data) throws UnsupportedEncodingException {
        System.out.println("===doItem in...[time]:" + new Date());
        if (data == null){
            return;
        }
        //对消息进行业务处理
        .....
      }

调用监听方法:

/*
ServletContextListener  监听ServletContext对象的生命周期
 */
public class RunListener implements ServletContextListener {

    private static Log log = LogFactory.getLog(RunListener.class);


    /**
     *  * 当Servlet 容器启动Web 应用时调用该方法。在调用完该方法之后,容器再对Filter 初始化,
     * 并且对那些在Web 应用启动时就需要被初始化的Servlet 进行初始化。
     * @param contextEvent
     */
    @Override
    public void contextInitialized(ServletContextEvent contextEvent) {

        try {
             //1、加载log4j配置文件
            String webappHome = contextEvent.getServletContext().getRealPath("/");
            // 设置此系统变量到系统中,供log4j 使用,
            System.setProperty("WEBAPP_HOME", webappHome);
            String logCfgPath = webappHome
                    + contextEvent.getServletContext().getInitParameter("log4j");
            System.out.println("log4j已经配置...");
            DOMConfigurator.configure(logCfgPath);// 初始化log4j

              //一些初始化操作
              ....

            //3、监听mq
            Thread thread = new Thread(new Runnable() {

                @Override
                public void run() {
                    // 运行监听
                    Listener listener = new Listener();
                    listener.listening();
                }
            });
            thread.start();
        } catch (Exception e) {
            e.printStackTrace();
            log.info("[ERROR]:"+e);
        }
    }

    /**
     * 当Servlet 容器终止Web 应用时调用该方法。在调用该方法之前,容器会先销毁所有的Servlet 和Filter 过滤器。
     * @param contextEvent
     */
    @Override
    public void contextDestroyed(ServletContextEvent contextEvent) {

    }
}

web.xml配置此监听器:

<listener>
        <listener-class>cn.qtone.xxt.cent.listener.RunListener</listener-class>
    </listener>