001/* 002 * Copyright 2002-2018 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * https://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.springframework.core; 018 019import java.io.IOException; 020import java.io.InputStream; 021import java.net.URL; 022import java.util.Properties; 023 024import org.apache.commons.logging.Log; 025import org.apache.commons.logging.LogFactory; 026 027import org.springframework.lang.Nullable; 028 029/** 030 * Static holder for local Spring properties, i.e. defined at the Spring library level. 031 * 032 * <p>Reads a {@code spring.properties} file from the root of the Spring library classpath, 033 * and also allows for programmatically setting properties through {@link #setProperty}. 034 * When checking a property, local entries are being checked first, then falling back 035 * to JVM-level system properties through a {@link System#getProperty} check. 036 * 037 * <p>This is an alternative way to set Spring-related system properties such as 038 * "spring.getenv.ignore" and "spring.beaninfo.ignore", in particular for scenarios 039 * where JVM system properties are locked on the target platform (e.g. WebSphere). 040 * See {@link #setFlag} for a convenient way to locally set such flags to "true". 041 * 042 * @author Juergen Hoeller 043 * @since 3.2.7 044 * @see org.springframework.core.env.AbstractEnvironment#IGNORE_GETENV_PROPERTY_NAME 045 * @see org.springframework.beans.CachedIntrospectionResults#IGNORE_BEANINFO_PROPERTY_NAME 046 * @see org.springframework.jdbc.core.StatementCreatorUtils#IGNORE_GETPARAMETERTYPE_PROPERTY_NAME 047 * @see org.springframework.test.context.cache.ContextCache#MAX_CONTEXT_CACHE_SIZE_PROPERTY_NAME 048 */ 049public final class SpringProperties { 050 051 private static final String PROPERTIES_RESOURCE_LOCATION = "spring.properties"; 052 053 private static final Log logger = LogFactory.getLog(SpringProperties.class); 054 055 private static final Properties localProperties = new Properties(); 056 057 058 static { 059 try { 060 ClassLoader cl = SpringProperties.class.getClassLoader(); 061 URL url = (cl != null ? cl.getResource(PROPERTIES_RESOURCE_LOCATION) : 062 ClassLoader.getSystemResource(PROPERTIES_RESOURCE_LOCATION)); 063 if (url != null) { 064 logger.debug("Found 'spring.properties' file in local classpath"); 065 InputStream is = url.openStream(); 066 try { 067 localProperties.load(is); 068 } 069 finally { 070 is.close(); 071 } 072 } 073 } 074 catch (IOException ex) { 075 if (logger.isInfoEnabled()) { 076 logger.info("Could not load 'spring.properties' file from local classpath: " + ex); 077 } 078 } 079 } 080 081 082 private SpringProperties() { 083 } 084 085 086 /** 087 * Programmatically set a local property, overriding an entry in the 088 * {@code spring.properties} file (if any). 089 * @param key the property key 090 * @param value the associated property value, or {@code null} to reset it 091 */ 092 public static void setProperty(String key, @Nullable String value) { 093 if (value != null) { 094 localProperties.setProperty(key, value); 095 } 096 else { 097 localProperties.remove(key); 098 } 099 } 100 101 /** 102 * Retrieve the property value for the given key, checking local Spring 103 * properties first and falling back to JVM-level system properties. 104 * @param key the property key 105 * @return the associated property value, or {@code null} if none found 106 */ 107 @Nullable 108 public static String getProperty(String key) { 109 String value = localProperties.getProperty(key); 110 if (value == null) { 111 try { 112 value = System.getProperty(key); 113 } 114 catch (Throwable ex) { 115 if (logger.isDebugEnabled()) { 116 logger.debug("Could not retrieve system property '" + key + "': " + ex); 117 } 118 } 119 } 120 return value; 121 } 122 123 /** 124 * Programmatically set a local flag to "true", overriding an 125 * entry in the {@code spring.properties} file (if any). 126 * @param key the property key 127 */ 128 public static void setFlag(String key) { 129 localProperties.put(key, Boolean.TRUE.toString()); 130 } 131 132 /** 133 * Retrieve the flag for the given property key. 134 * @param key the property key 135 * @return {@code true} if the property is set to "true", 136 * {@code} false otherwise 137 */ 138 public static boolean getFlag(String key) { 139 return Boolean.parseBoolean(getProperty(key)); 140 } 141 142}