Development environment - test environment - production environment - configuration automatic switching N methods

Development environment - test environment - production environment, the configurations of various environments are different, such as database url, third-party payment url, and some other configurations, etc., and the logic of the code is also related to the environment, such as sending text messages and It is not necessary to verify the verification code offline, then it is necessary to judge the environment in which the project is located. If it is placed in the project, it must be changed every time it is published to a different environment. It is very troublesome to change it, and changing a project will only If there is a problem, I have summarized several methods for your reference, all of which are useful.

First, if only the configuration of the database needs to be changed, then you can use JNDI, that is, configure the DataSource in tomcat, and spring can obtain the DataSource from JNDI. Not to mention the configuration, there are many online.


Second, if there is more than just the configuration of the database, then the method mentioned below should be used.
2.1, using environment variables For
example , the configuration of the data mentioned above, we generally define a properties file , the content is basically like this:
jdbc.driverClass = com.mysql.jdbc.Driver
jdbc.url = jdbc:mysql://xxx/xxx?useUnicode=true&characterEncoding=utf8
jdbc.user = xxx
jdbc.password = xxx
jdbc.maxPoolSize=50
jdbc.minPoolSize=10
jdbc.maxStatements = 100
jdbc.testConnection=true


Then specify this file in the spring configuration file as follows:
<context:property-placeholder location="classpath:config*.properties"/>


To solve this kind of configuration, it is better to use environment variables, and the changes are small.
You only need to define an environment variable, for example, the variable name is MY_CNF, and the value is D:/myconf. Windows needs to restart the computer to obtain this new environment variable, linux Just execute the source command. If you can get it, you can use the main method to print System.getEnv("MY_CNF"); try it out.
In Eclipse, you can set environment variables directly for tomcat without restarting the computer. Setting method:
double-click in the services window Server -->open launch configuration -->Environment-->New can add environment variables.

Then copy the properties file to D:/myconf,
the way specified in spring is not classpath, and it is specified like this:
<context:property-placeholder location="file:${MY_CNF}/config.properties"/>


Multiple configuration files are separated by commas, wildcards such as * are not supported
<context:property-placeholder location="file:${MY_CNF}/config.properties,file:${MY_CNF}/config-redis.properties"/>

The configuration files in the project can be independent.


2.2 A more violent method
Put the configuration files in a certain directory, such as D:/abc. When the project starts, use a script to directly copy the configuration in the D:/abc directory to Tomcat/webapps/your project/WEB-INF/classes/ in the corresponding configuration file directory, replace the original configuration file in the project.
How to copy it before startup? Just change the startup.bat or startup.sh of tomcat, in increase at the beginning
cp -f D:/abc/xxx.propertiets /opt/tomcat/webapps/.....

The configuration files in the project can be left with the configuration of the local development, so that the local development will not be affected. The




above methods can already solve the problem, and the following are some tossing methods, which may seem more laborious.
2.3 Use the profile tag and -P
in maven If the project is maven, you can use this method.
You can configure <profile> in pom.xml, and this tag can define some key and value attributes, such as:
<profiles>
		<profile>
			<id>linux</id>
			<properties>
				<jrepath>${JAVA_HOME}/jre/lib/rt.jar:${JAVA_HOME}/jre/lib/jce.jar</jrepath>
			</properties>
		</profile>
		
		
		<profile>
			<id>win</id>
			<properties>
				<jrepath>${JAVA_HOME}/jre/lib/rt.jar;${JAVA_HOME}/jre/lib/jce.jar</jrepath>
			</properties>
		</profile>
		
	</profiles>


Among them, the tag names of <profiles>, <profile>, <id>, <properties> cannot be changed.
The <jrepath> tag under <properties> is written by myself, and the tag name is the parameter name, tag The body is the value.
The meaning of the above code is to define two sets of values ​​named <jrepath>, one id is called linux, the other is called win,
and then you can use ${jrepath} in other places in pom.xml to get this value, but Specifically, do you want to get the value under liunx or the value under win? This requires specifying <id> with the -P parameter when executing the maven command,
such as: mvn package -Plinux


2.4 Use spring's profile tag.
Similar to maven's profile tag , you can go and see for yourself, but it is also quite frustrating. I don't like to use the


2.5 redis method. It is
suitable for non-project startup parameters and constant data with less changes.
The parameters are stored in redis through background editing (making a management page).
Simple , you can get the configuration from redis every time. The
optimization point is to avoid getting it from redis every time. Use the publish-subscribe mode of redis to get the configuration from redis when the project starts (Listener or Filter or spring's @PostConstrutor is fine). To cache in local memory (such as collections, constants, etc.), if the redis data is changed, the project subscribes to the messages of this channel, and then re-fetches and updates the local cache from redis, which is suitable for cluster environments.


2.6 Using System.setProperty
The value set by System.setProperty("key", "value") can be obtained in the form of ${key} in the spring configuration file or other configuration files. In
this way, all configuration files can be placed in the In the directory corresponding to the defined environment variable, and then read the configuration file when the project starts, cache the configuration information through System.setProperty, and then directly use ${key} in the spring configuration. Example:
public class SysInitListener implements ServletContextListener {

    @Override
    public void contextDestroyed(ServletContextEvent arg0) {

    }

    @Override
    public void contextInitialized(ServletContextEvent arg0) {
        String path = System.getenv("MY_CNF");
        try {
            InputStream in = new BufferedInputStream(new FileInputStream(path + "/xxx.properties"));
            Properties p = new Properties();
            p.load(in);

            /* //Database
            System.setProperty("jdbc.driverClass", p.getProperty("jdbc.driverClass", "com.mysql.jdbc.Driver"));
            System.setProperty("jdbc.url", p.getProperty("jdbc.url", "线上地址"));
            System.setProperty("jdbc.user", p.getProperty("jdbc.user", "线上用户名"));
            System.setProperty("jdbc.password", p.getProperty("jdbc.password", "线上密码"));
                      
            //Environment, default production environment
            SYSConstant.MS_ENV = EnvEnum.getByFlag(p.getProperty("env", "product"));
        } catch (IOException e) {
            e.printStackTrace ();
        }
    }

}




The value can be obtained by using ${key} in the spring configuration file
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
        <property name="driverClassName" value="${jdbc.driverClass}"/>
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.user}"/>
        <property name="password" value="${jdbc.password}"/>
    </bean>


In the above Listener there are also
SYSConstant.MS_ENV = EnvEnum.getByFlag(p.getProperty("env", "product"));

This sentence is to get a value called env from the configuration file and assign it to a constant in the project, so that the constant can be judged in the code to know the environment of the project. What is the use? For example, sending SMS or verifying SMS verification It is not necessary to wait for the code offline, then you can use this constant to judge the business logic


Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326463462&siteId=291194637