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