java读取配置文件举例说明
程序员文章站
2022-05-08 09:25:59
...
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代码框架
代码框架
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>
推荐阅读
-
读取配置文件properties并解析xml的main方法
-
java 中Ini格式配置文件读取
-
nginx 源码学习笔记(十三)——文件读写和配置文件读取
-
java读取cvs文件并导入数据库
-
jenkins 读取json文件_干货:.net core实现读取appsettings.json配置文件(建议收藏)...
-
.net core读取配置文件appsettings.json
-
.NET Core读取配置文件appsettings.json
-
.NET Core 读取appsettings.json配置文件
-
Asp .Net Core 读取appsettings.json配置文件
-
Asp .Net Core 读取appsettings.json配置文件