001/* 002 * Copyright 2002-2017 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.beans.factory.config; 018 019import java.io.IOException; 020import java.util.Properties; 021 022import org.springframework.beans.factory.FactoryBean; 023import org.springframework.beans.factory.InitializingBean; 024import org.springframework.core.io.support.PropertiesLoaderSupport; 025import org.springframework.lang.Nullable; 026 027/** 028 * Allows for making a properties file from a classpath location available 029 * as Properties instance in a bean factory. Can be used to populate 030 * any bean property of type Properties via a bean reference. 031 * 032 * <p>Supports loading from a properties file and/or setting local properties 033 * on this FactoryBean. The created Properties instance will be merged from 034 * loaded and local values. If neither a location nor local properties are set, 035 * an exception will be thrown on initialization. 036 * 037 * <p>Can create a singleton or a new object on each request. 038 * Default is a singleton. 039 * 040 * @author Juergen Hoeller 041 * @see #setLocation 042 * @see #setProperties 043 * @see #setLocalOverride 044 * @see java.util.Properties 045 */ 046public class PropertiesFactoryBean extends PropertiesLoaderSupport 047 implements FactoryBean<Properties>, InitializingBean { 048 049 private boolean singleton = true; 050 051 @Nullable 052 private Properties singletonInstance; 053 054 055 /** 056 * Set whether a shared 'singleton' Properties instance should be 057 * created, or rather a new Properties instance on each request. 058 * <p>Default is "true" (a shared singleton). 059 */ 060 public final void setSingleton(boolean singleton) { 061 this.singleton = singleton; 062 } 063 064 @Override 065 public final boolean isSingleton() { 066 return this.singleton; 067 } 068 069 070 @Override 071 public final void afterPropertiesSet() throws IOException { 072 if (this.singleton) { 073 this.singletonInstance = createProperties(); 074 } 075 } 076 077 @Override 078 @Nullable 079 public final Properties getObject() throws IOException { 080 if (this.singleton) { 081 return this.singletonInstance; 082 } 083 else { 084 return createProperties(); 085 } 086 } 087 088 @Override 089 public Class<Properties> getObjectType() { 090 return Properties.class; 091 } 092 093 094 /** 095 * Template method that subclasses may override to construct the object 096 * returned by this factory. The default implementation returns the 097 * plain merged Properties instance. 098 * <p>Invoked on initialization of this FactoryBean in case of a 099 * shared singleton; else, on each {@link #getObject()} call. 100 * @return the object returned by this factory 101 * @throws IOException if an exception occurred during properties loading 102 * @see #mergeProperties() 103 */ 104 protected Properties createProperties() throws IOException { 105 return mergeProperties(); 106 } 107 108}