assembly将properties打到外面并用spring加载 (以dubbo为例)
来源:互联网 发布:微信 js sdk 多图上传 编辑:程序博客网 时间:2024/05/28 09:32
估计很多朋友用assembly打包的时候可能会遇到一个问题,就是将包打成lib (放jar包),conf(放properties配置文件)和bin(启动bash)三个目录的时候,将工程中的properties配置文件打包到conf目录下,然后lib中的jar包就将那些properties排除掉,当启动方法的时候会发现找不到配置文件了,这是因为配置文件的目录之前在开发的时候用的是classpath,当你把包打成这样的需要指定配置文件的地址为file协议(因为classpath是读取的jar包内部的,file可以读取外部文件)
项目的一部分结构如下:
打包的部分pom:
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" /> <property name="ignoreUnresolvablePlaceholders" value="true" /> <property name="ignoreResourceNotFound" value="true" /> <property name="locations"> <list> #用classpath <value>classpath:**/*.properties</value> #用file <value>file:/user/home/xxxx/*.properties</value> </list> </property> <property name="fileEncoding" value="UTF-8"/> </bean>
并且可以根据开发模式,测试模式,生产模式 境配置三种不同的properties,这样打包的时候不用修改配置文件,只需要修改下pom文件中的profiles的activeByDefault熟悉即可,xml文件里面参数就可以配置为${value}的模式,动态加载外部
下面给个关键部分的代码:
<build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-plugin</artifactId> <version>2.4</version> <configuration> <classesDirectory>target/classes/</classesDirectory> <archive> <addMavenDescriptor>false</addMavenDescriptor> <manifest> <addClasspath>true</addClasspath> <mainClass>cn.toua.profile.present.MainApp</mainClass> </manifest> <manifestEntries> <Class-Path>./</Class-Path> </manifestEntries> </archive> <excludes> <exclude>**/*.properties</exclude> <exclude>**/log4j2.xml</exclude> <exclude>**/dubbo-provider.xml</exclude> <exclude>**/dubbo-test.xml</exclude> </excludes> </configuration> </plugin> <plugin> <artifactId>maven-assembly-plugin</artifactId> <version>3.0.0</version> <configuration> <appendAssemblyId>false</appendAssemblyId> <archive> <manifest> <addClasspath>true</addClasspath> <mainClass>cn.toua.profile.present.MainApp</mainClass> </manifest> </archive> <descriptors> <descriptor>src/main/assembly/assembly.xml</descriptor> </descriptors> </configuration> <executions> <execution> <id>make-assembly</id> <phase>package</phase> <goals> <goal>single</goal> </goals> </execution> </executions> </plugin> </plugins> <filters> <filter>src/main/resources/env/${env}/${env}.properties</filter> </filters> <resources> <resource> <directory>src/main/resources</directory> <includes> <include>**/*.xml</include> <include>**/*.properties</include> </includes> <excludes> <exclude>env/**</exclude> </excludes> <filtering>true</filtering> </resource> </resources> </build>
其中上面的filters就是maven的过滤器,maven 通过过滤器来修改部署时的不同配置。部署时的所有资源的配置,如果根据环境不同,有不同的配置,则需要在资源中使用${value}的方式来取值,并且在resources标签里面添加filtering为true:
<resources> <resource> <directory>src/main/resources</directory> <includes> <include>**/*.xml</include> <include>**/*.properties</include> </includes> <excludes> <exclude>env/**</exclude> </excludes> <filtering>true</filtering> </resource> </resources>
不同的环境配置不同的变量(activeByDefault为true的时候${env}就会取对应的值):
<profiles> <!-- 默认的开发环境 --> <profile> <id>dev</id> <properties> <env>dev</env> <plugin.assembly.phase>none</plugin.assembly.phase> </properties> <activation> <activeByDefault>true</activeByDefault> </activation> </profile> <!-- 测试环境 --> <profile> <id>test</id> <properties> <env>test</env> <plugin.assembly.phase>true</plugin.assembly.phase> </properties> <activation> <activeByDefault>false</activeByDefault> </activation> </profile> <!-- 生产环境 --> <profile> <id>prod</id> <properties> <env>prod</env> <plugin.assembly.phase>true</plugin.assembly.phase> </properties> <activation> <activeByDefault>false</activeByDefault> </activation> </profile> </profiles>
当profile里面dev的activeByDefault设置为true的时候,那么上面
<filter>src/main/resources/env/${env}/${env}.properties</filter>
就会去过滤dev目录下的dev.properties文件,将里面的配置属性添加到下面的
这些配置文件里面
如下是application.properties:
#hbasehbase.zookeeper.quorum=${hbase.zookeeper.quorum}hbase.zookeeper.property.clientPort=${hbase.zookeeper.property.clientPort}hbase.tableName=${hbase.tableName}hbase.history.tableName=${hbase.history.tableName}#jdbcjdbc.driver=${jdbc.driver}jdbc.url=${jdbc.url}jdbc.username=${jdbc.username}jdbc.password=${jdbc.password}#cache 刷新时间env.mysql.cache=${env.mysql.cache}
如下是dubbo.properties:
## 应用配置入口dubbo.spring.config=${dubbo.spring.config}## 应用容器dubbo.container=${dubbo.container}# 服务端过滤器app.config.classpath=${env.config.path}dubbo.protocol.host=${dubbo.protocol.host}dubbo.timeout=${dubbo.timeout}jvm.mem.xmx=2gjvm.mem.xms=2gjvm.mem.new.size=1300m
application.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" xmlns:context="http://www.springframework.org/schema/context" xmlns:util="http://www.springframework.org/schema/util" xmlns:aop="http://www.springframework.org/schema/aop" 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 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd"> <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE"/> <property name="ignoreUnresolvablePlaceholders" value="true"/> <property name="ignoreResourceNotFound" value="true"/> <property name="locations"> <list> <value>${env.config.path.type}:${env.config.path}application.properties</value> </list> </property> <property name="fileEncoding" value="UTF-8"/> </bean> <context:component-scan base-package="cn.toua.profile.present"/> <import resource="${env.config.path.type}:${env.config.path}dubbo-provider.xml"/></beans>
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:dubbo="http://code.alibabatech.com/schema/dubbo" xmlns:context="http://www.springframework.org/schema/context" xmlns:util="http://www.springframework.org/schema/util" xmlns:aop="http://www.springframework.org/schema/aop" 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 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd"> <dubbo:application name="profile-present-service" owner="profile" organization="touna"/> <dubbo:registry protocol="zookeeper" address="${dubbo.registry.address}"/> <!-- 提供RPC服务注入 --> <dubbo:protocol name="dubbo" port="${dubbo.protocol.port}" serialization="hessian2" threadpool="cached" threads="20"/> <dubbo:service interface="cn.touna.profile.present.api.ProfileService" ref="profileService"/> <context:component-scan base-package="cn.toua.profile.present"/></beans>
log4j2.xml:
<?xml version="1.0" encoding="UTF-8"?><configuration status="WARN" shutdownHook="disable" monitorInterval="1800"> <Properties> <Property name="sysName">profile-present-dubbo</Property> <Property name="bizLogLevel">${env.log4j2.biz.level}</Property> <Property name="logFilePath">${env.log4j2.log.path}</Property> <Property name="logSize">${env.log4j2.log.size}MB</Property> <Property name="maxFile">${env.log4j2.log.maxfile}</Property> </Properties> <!--先定义所有的appender--> <appenders> <!--这个输出控制台的配置--> <Console name="Console" target="SYSTEM_OUT"> <!--控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch)--> <ThresholdFilter level="trace" onMatch="ACCEPT" onMismatch="DENY"/> <!--这个都知道是输出日志的格式--> <PatternLayout pattern="%d{HH:mm:ss.SSS} %-5level %class{36} %L %M - %msg%xEx%n"/> </Console> <!--文件会打印出所有信息,这个log每次运行程序会自动清空,由append属性决定,这个也挺有用的,适合临时测试用--> <!--<File name="log" fileName="${logFilePath}/${sysName}-file.log" append="false">--> <!--<PatternLayout pattern="%d{HH:mm:ss.SSS} %-5level %class{36} %L %M - %msg%xEx%n"/>--> <!--</File>--> <!--这个会打印出所有的信息,每次大小超过size,则这size大小的日志会自动存入按年份-月份建立的文件夹下面并进行压缩,作为存档--> <RollingFile name="RollingFile" fileName="${logFilePath}/${sysName}-roll.log" filePattern="${logFilePath}/$${date:yyyy-MM}/app-%d{MM-dd-yyyy}-%i.log.gz"> <PatternLayout pattern="%d{yyyy-MM-dd 'at' HH:mm:ss z} %-5level %class{36} %L %M - %msg%xEx%n"/> <Policies> <TimeBasedTriggeringPolicy modulate="true" interval="1"/> <SizeBasedTriggeringPolicy size="${logSize}"/> </Policies> <DefaultRolloverStrategy max="${maxFile}"/> </RollingFile> </appenders> <!--然后定义logger,只有定义了logger并引入的appender,appender才会生效--> <loggers> <logger name="cn.toua.profile.present" level="${bizLogLevel}"> <appender-ref ref="RollingFile"/> <appender-ref ref="Console"/> </logger> <!--建立一个默认的root的logger--> <root level="${bizLogLevel}"> <appender-ref ref="RollingFile"/> <appender-ref ref="Console"/> </root> </loggers></configuration>
当然, 最终过滤的时候都是将env目录下对应的配置加载到上面那些文件里,如下dev.properties:
env.config.path=env.config.path.type=classpath#kafkabatch=300zk=hadoop01:2181,hadoop03:2181kafka.broker=hadoop02:9092,hadoop03:9092,hadoop04:9092kafka.topic=tianhuaxing_test_topickafka.group=dataPlatformHead#hbasehbase.zookeeper.quorum=hadoop01:2181,hadoop03:2181hbase.zookeeper.property.clientPort=2181hbase.tableName=xxxxhbase.history.tableName=xxxx#mysqljdbc.driver=com.mysql.jdbc.Driverjdbc.url=jdbc:mysql://10.0.4.140:3306/tbd_up?useUnicode=true&allowMultiQueries=true&characterEncoding=UTF-8&useFastDateParsing=false&zeroDateTimeBehavior=convertToNulljdbc.username=xxxxjdbc.password=xxxx#dubbodubbo.spring.config=classpath:dubbo-provider.xmldubbo.container=springdubbo.application.logger=log4jdubbo.log4j.file=logsdubbo.log4j.level=INFOdubbo.registry.address=zookeeper://hadoop01:2181;zookeeper://hadoop02:2181dubbo.protocol.port=20880dubbo.log4j.subdirectory=20880dubbo.application.name=profiledubbo.timeout=60000#logenv.log4j2.log.path=logsenv.log4j2.biz.level=INFOenv.log4j2.log.size=100env.log4j2.log.maxfile=100
env下的生产 prop.properties(注意了env.config.path.type是用的file而不是classpath,且env.config.path根据你的部署路径来配置)
env.config.path=/home/appuser/profile/profile/conf/env.config.path.type=file#其他和上面一样 就是环境不同
当打完包之后,上传到服务器上面,执行start.sh启动,启动脚本需要读取dubbo.properties的配置文件并且通过java -Dxxx=xxx 的形式来将dubbo的配置传入main函数,不然当执行com.alibaba.dubbo.container.Main.main(args)的时候会执行如下一段代码:
if(args == null || args.length == 0) { String e = ConfigUtils.getProperty("dubbo.container", loader.getDefaultExtensionName()); args = Constants.COMMA_SPLIT_PATTERN.split(e); }
大概意思就是 不传入参数就会默认去classpath下加载dubbo.properties文件,当然我们打包成上面三个目录并且已经将dubbo.properties打包出来了,不传入参数就相当于只启动一个空的dubbo工程,所以需要同过-D的方式传入,start.sh(网上一大堆可以搜一下其他几个,这里就不贴出来了)如下:
#!/bin/bashcd `dirname $0`BIN_DIR=`pwd`echo "Bin_Dir ${BIN_DIR}"cd ..DEPLOY_DIR=`pwd`echo "DEPLOY_DIR ${DEPLOY_DIR}"#cd ..APP_DIR=`pwd`echo "APP_DIR ${APP_DIR}"cd $DEPLOY_DIRCONF_DIR=$DEPLOY_DIR/confLOGS_DIR=$DEPLOY_DIR/logsSTDOUT_FILE=$LOGS_DIR/stdout.logSTART_REPORT_FILE=$LOGS_DIR/shell.logREPORT_FILE=$LOGS_DIR/report.flagCONFIG_DIR=$APP_DIR/conf# process system properties to javaSERVER_NAME=`sed '/^dubbo.application.name/!d;s/.*=//' $CONFIG_DIR/dubbo.properties | tr -d '\r'`LOGS_FILE=`sed '/^dubbo.log4j.file/!d;s/.*=//' $CONFIG_DIR/dubbo.properties | tr -d '\r'`APPLICATION_FILE=`sed '/^dubbo.spring.config/!d;s/.*=//' $CONFIG_DIR/dubbo.properties | tr -d '\r'`CONTAINER_INFOR=`sed '/^dubbo.container/!d;s/.*=//' $CONFIG_DIR/dubbo.properties | tr -d '\r'`SERVER_PORT=`sed '/^dubbo.protocol.port/!d;s/.*=//' $CONFIG_DIR/dubbo.properties | tr -d '\r'`JVM_MEM_XMX=`sed '/^jvm.mem.xmx/!d;s/.*=//' $CONFIG_DIR/dubbo.properties | tr -d '\r'`JVM_MEM_XMS=`sed '/^jvm.mem.xms/!d;s/.*=//' $CONFIG_DIR/dubbo.properties | tr -d '\r'`JVM_MEM_NEW_SIZE=`sed '/^jvm.mem.new.size/!d;s/.*=//' $CONFIG_DIR/dubbo.properties | tr -d '\r'`JVM_MEM_PERM_SIZE=`sed '/^jvm.mem.perm.size/!d;s/.*=//' $CONFIG_DIR/dubbo.properties | tr -d '\r'`JVM_MEM_MAX_PERM_SIZE=`sed '/^jvm.mem.max.perm.size/!d;s/.*=//' $CONFIG_DIR/dubbo.properties | tr -d '\r'`if [ -z "$JVM_MEM_XMX" ]; then JVM_MEM_XMX=6gfiif [ -z "$JVM_MEM_XMS" ]; then JVM_MEM_XMS=6gfiif [ -z "$JVM_MEM_NEW_SIZE" ]; then JVM_MEM_NEW_SIZE=4gfiif [ -z "$JVM_MEM_PERM_SIZE" ]; then JVM_MEM_PERM_SIZEM=64mfiif [ -z "$JVM_MEM_MAX_PERM_SIZE" ]; then JVM_MEM_MAX_PERM_SIZE=256mfireportTo(){ echo $* >> "$START_REPORT_FILE"}reportJavaVersion(){ java -version >> "$START_REPORT_FILE" 2>&1}echoReport(){ echo $* | tee -a "$START_REPORT_FILE"}if [ -z "$SERVER_NAME" ]; then SERVER_NAME=`hostname`fiif [ -z "$APPLICATION_FILE" ]; then echo "ERROR: The property of dubbo.application.file is not set!" exit 1fireportTo -e "\n================ Time: `date '+%Y-%m-%d %H:%M:%S'` ================"reportJavaVersionAPP_PID=`ps -ef -ww | grep "java" | grep " -DappName=$SERVER_NAME " | awk '{print $2}'`if [ -n "$APP_PID" ]; then echoReport "INFO: The $SERVER_NAME already started!" echoReport "PID: $APP_PID" exit 0fiif [ ! -d "$LOGS_DIR" ]; then mkdir -p "$LOGS_DIR"fiif [ -e "${REPORT_FILE}" ]; then rm -rf "${REPORT_FILE}"fiLIB_DIR=$DEPLOY_DIR/libLIB_JARS=`ls -1 "$LIB_DIR" | grep -E "\.jar$" | awk '{print "'$LIB_DIR'/"$0}'|tr "\n" ":"`JAVA_OPTS="-DappName=$SERVER_NAME -Djava.awt.headless=true -Djava.net.preferIPv4Stack=true -Ddubbo.shutdown.hook=true -Dapp.started.report=$REPORT_FILE"JAVA_DEBUG_OPTS=""if [ "$1" = "debug" ]; then addressPort=8001 if [ -n "$2" ]; then addressPort=$2 fi JAVA_DEBUG_OPTS=" -Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,address=${addressPort},server=y,suspend=n "fiJAVA_JMX_OPTS=""if [ "$1" = "jmx" ]; then if [ -n "$2" ]; then JAVA_JMX_OPTS="$JAVA_JMX_OPTS -Djava.rmi.server.hostname=$2" fi if [ -n "$3" ]; then JAVA_JMX_OPTS="$JAVA_JMX_OPTS -Dcom.sun.management.jmxremote.port=$3" fi JAVA_JMX_OPTS="$JAVA_JMX_OPTS -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.ssl=false"fiJAVA_MEM_OPTS=""BITS=`java -version 2>&1 | grep -i 64-bit`JAVA_MEM_SIZE_OPTS="-Xmx${JVM_MEM_XMX} -Xms${JVM_MEM_XMS} -XX:MaxNewSize=${JVM_MEM_NEW_SIZE} -Xss256k -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=$APP_DIR/logs"if [ -n "$BITS" ]; then JAVA_MEM_OPTS=" -server $JAVA_MEM_SIZE_OPTS -XX:+DisableExplicitGC -XX:+UseConcMarkSweepGC -XX:+CMSParallelRemarkEnabled -XX:+UseCMSCompactAtFullCollection -XX:LargePageSizeInBytes=128m -XX:+UseFastAccessorMethods -XX:+UseCMSInitiatingOccupancyOnly -XX:CMSInitiatingOccupancyFraction=70 "else JAVA_MEM_OPTS=" -server $JAVA_MEM_SIZE_OPTS -XX:SurvivorRatio=2 -XX:+UseParallelGC "fi#设置gc参数CUR_DATE=`date +%Y%m%d`GC_LOGFILE="$APP_DIR/logs/gc_$CUR_DATE.log"if [ ! -f "$GC_LOGFILE" ]; then touch $GC_LOGFILEfiJAVA_MEM_GC_OPTS="-verbose:gc -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintHeapAtGC -Xloggc:$GC_LOGFILE"# process system properties to javaJAVA_PROPERTIES_OPTS="-Ddubbo.spring.config=$APPLICATION_FILE -Ddubbo.container=$CONTAINER_INFOR"# log4j2.xml file path configJAVA_LOG4J2_FILE_OPTS="-Dlog4j.configurationFile=$CONFIG_DIR/log4j2.xml"echoReport "Starting the $SERVER_NAME ..."reportTo "java $JAVA_OPTS $JAVA_MEM_OPTS $JAVA_MEM_GC_OPTS $JAVA_DEBUG_OPTS $JAVA_JMX_OPTS $JAVA_PROPERTIES_OPTS $JAVA_LOG4J2_FILE_OPTS -classpath $CONF_DIR:$CONFIG_DIR:$LIB_JARS:$CLASSPATH cn.toua.profile.present.MainAppr"nohup java $JAVA_OPTS $JAVA_MEM_OPTS $JAVA_MEM_GC_OPTS $JAVA_DEBUG_OPTS $JAVA_JMX_OPTS $JAVA_PROPERTIES_OPTS $JAVA_LOG4J2_FILE_OPTS -classpath $CONF_DIR:$CONFIG_DIR:$LIB_JARS:$CLASSPATH cn.toua.profile.present.MainApp > $STDOUT_FILE 2>&1 &sleep 1APP_PID=`ps -ef -ww | grep "java" | grep " -DappName=$SERVER_NAME " | awk '{print $2}'`if [ -z "$APP_PID" ]; then echoReport "START APP FAIL!" echoReport "STDOUT: $STDOUT_FILE" exit 1fi# 最长检测 1 分钟,可能的结果是标志文件不存在,这个要开发人员自己检查进程启动是否有问题.CHECK_MAX_COUNT=12COUNT=0echo -e "Checking proccess[${APP_PID}]..\c"while [ $CHECK_MAX_COUNT -gt 0 ]; do echo -e ".\c" sleep 5 COUNT=`ps -p $APP_PID | grep -v "PID" | wc -l` if [ $COUNT -le 0 ]; then break fi # 标志文件存在,则直接跳出检查 if [ -e "${REPORT_FILE}" ]; then break fi ((CHECK_MAX_COUNT--))doneif [ $COUNT -le 0 ]; then echoReport "Start App Failed!" echoReport "STDOUT: $STDOUT_FILE" exit 1elif [ $CHECK_MAX_COUNT -le 0 ]; then echoReport "Flag file: '${REPORT_FILE}' does not exist, maybe have some error!" echoReport "PID: $APP_PID" echoReport "STDOUT: $STDOUT_FILE" exit 0else echoReport "Start App OK!" echoReport "PID: $APP_PID" echoReport "STDOUT: $STDOUT_FILE" exit 0fi
其中如下图就是读取dubbo.properties中的配置:
最后再贴一个assembly.xml:
<assembly xmlns="http://maven.apache.org/ASSEMBLY/3.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/ASSEMBLY/3.0.0 http://maven.apache.org/xsd/assembly-3.0.0.xsd"> <id>assembly</id> <formats> <format>tgz</format> </formats> <includeBaseDirectory>true</includeBaseDirectory> <baseDirectory>profile-present-dubbo</baseDirectory> <fileSets> <fileSet> <directory>${project.basedir}/src/main/bin</directory> <outputDirectory>bin</outputDirectory> <excludes> <exclude>*.bat</exclude> </excludes> <fileMode>0750</fileMode> </fileSet> <fileSet> <directory>${project.build.directory}/classes</directory> <outputDirectory>conf</outputDirectory> <includes> <include>*.properties</include> <include>dubbo-provider.xml</include> <include>log4j2.xml</include> </includes> <fileMode>0640</fileMode> </fileSet> </fileSets> <dependencySets> <dependencySet> <outputDirectory>lib</outputDirectory> <scope>runtime</scope> </dependencySet> </dependencySets> <!--<files>--> <!--<file>--> <!--<source>target/${project.build.finalName}.jar</source>--> <!--<outputDirectory>lib</outputDirectory>--> <!--</file>--> <!--</files>--></assembly>
总结下:
1.通过maven的filters可以过滤配置文件将配置文件中的${value}替换,
2.多环境可以使用maven标签profiles来指定开发环境变量
3.使用spring管理配置文件加载外部的配置使用file:/xxx/xx/*.properties
4.dubbo启动的时候默认加载classpath下的dubbo.properties文件,当在args传入参数就会以传入的为准而不回去加载classpath下的配置.
- assembly将properties打到外面并用spring加载 (以dubbo为例)
- Spring MVC中加载配置properties文件(以配置Redis为例)
- java 将 properties 文件 加载到内存
- spring加载properties文件,并将属性值注入到指定类的指定成员变量
- shell命令:以空格为分隔符截取文件每行的第一个字符串,并用sort排序,再去掉相同的字符串,将结果输出到另一个文件
- spring boot配置dubbo(properties)
- spring-boot:将工程打为jar可执行包
- Spring-boot将项目打为jar包发布
- spring 加载 properties文件
- spring加载properties配置文件
- spring加载properties文件
- Spring加载properties文件
- spring schema 扩增 (dubbo 为例)
- Dubbo集成到Spring
- spring中配置log4j,并将log信息存储在数据库中(以mysql为例)
- 将程序添加到右键菜单(以Sublime Text为例)
- 将任意程序添加到右键菜单—以sublime text为例
- maven将jar及so文件安装到本地使用(以高德为例)
- 最长回文子串(Manacher算法)
- String的常用方法总结
- Oracle 11g软件安装
- Android Application启动流程分析
- 创建对应的运行时类的对象、获取运行时类的所有属性、方法
- assembly将properties打到外面并用spring加载 (以dubbo为例)
- 页面滚动触发css动画效果
- 文档模板引擎/字符串模板
- 沉浸式状态栏
- Encode and Decode TinyURL
- SpringBoot对非关系型数据库NoSql的支持
- HanLP自然语言处理包初步安装与使用
- Android无需root查看数据库
- 敏捷开发之SCRUM的五个活动