001/*
002 * Copyright 2002-2019 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.context.support;
018
019import java.util.Locale;
020
021import org.springframework.beans.BeansException;
022import org.springframework.beans.MutablePropertyValues;
023import org.springframework.beans.factory.config.BeanDefinition;
024import org.springframework.beans.factory.support.GenericBeanDefinition;
025import org.springframework.context.ApplicationContext;
026import org.springframework.lang.Nullable;
027
028/**
029 * {@link org.springframework.context.ApplicationContext} implementation
030 * which supports programmatic registration of beans and messages,
031 * rather than reading bean definitions from external configuration sources.
032 * Mainly useful for testing.
033 *
034 * @author Rod Johnson
035 * @author Juergen Hoeller
036 * @see #registerSingleton
037 * @see #registerPrototype
038 * @see #registerBeanDefinition
039 * @see #refresh
040 */
041public class StaticApplicationContext extends GenericApplicationContext {
042
043        private final StaticMessageSource staticMessageSource;
044
045
046        /**
047         * Create a new StaticApplicationContext.
048         * @see #registerSingleton
049         * @see #registerPrototype
050         * @see #registerBeanDefinition
051         * @see #refresh
052         */
053        public StaticApplicationContext() throws BeansException {
054                this(null);
055        }
056
057        /**
058         * Create a new StaticApplicationContext with the given parent.
059         * @see #registerSingleton
060         * @see #registerPrototype
061         * @see #registerBeanDefinition
062         * @see #refresh
063         */
064        public StaticApplicationContext(@Nullable ApplicationContext parent) throws BeansException {
065                super(parent);
066
067                // Initialize and register a StaticMessageSource.
068                this.staticMessageSource = new StaticMessageSource();
069                getBeanFactory().registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.staticMessageSource);
070        }
071
072
073        /**
074         * Overridden to turn it into a no-op, to be more lenient towards test cases.
075         */
076        @Override
077        protected void assertBeanFactoryActive() {
078        }
079
080        /**
081         * Return the internal StaticMessageSource used by this context.
082         * Can be used to register messages on it.
083         * @see #addMessage
084         */
085        public final StaticMessageSource getStaticMessageSource() {
086                return this.staticMessageSource;
087        }
088
089        /**
090         * Register a singleton bean with the underlying bean factory.
091         * <p>For more advanced needs, register with the underlying BeanFactory directly.
092         * @see #getDefaultListableBeanFactory
093         */
094        public void registerSingleton(String name, Class<?> clazz) throws BeansException {
095                GenericBeanDefinition bd = new GenericBeanDefinition();
096                bd.setBeanClass(clazz);
097                getDefaultListableBeanFactory().registerBeanDefinition(name, bd);
098        }
099
100        /**
101         * Register a singleton bean with the underlying bean factory.
102         * <p>For more advanced needs, register with the underlying BeanFactory directly.
103         * @see #getDefaultListableBeanFactory
104         */
105        public void registerSingleton(String name, Class<?> clazz, MutablePropertyValues pvs) throws BeansException {
106                GenericBeanDefinition bd = new GenericBeanDefinition();
107                bd.setBeanClass(clazz);
108                bd.setPropertyValues(pvs);
109                getDefaultListableBeanFactory().registerBeanDefinition(name, bd);
110        }
111
112        /**
113         * Register a prototype bean with the underlying bean factory.
114         * <p>For more advanced needs, register with the underlying BeanFactory directly.
115         * @see #getDefaultListableBeanFactory
116         */
117        public void registerPrototype(String name, Class<?> clazz) throws BeansException {
118                GenericBeanDefinition bd = new GenericBeanDefinition();
119                bd.setScope(BeanDefinition.SCOPE_PROTOTYPE);
120                bd.setBeanClass(clazz);
121                getDefaultListableBeanFactory().registerBeanDefinition(name, bd);
122        }
123
124        /**
125         * Register a prototype bean with the underlying bean factory.
126         * <p>For more advanced needs, register with the underlying BeanFactory directly.
127         * @see #getDefaultListableBeanFactory
128         */
129        public void registerPrototype(String name, Class<?> clazz, MutablePropertyValues pvs) throws BeansException {
130                GenericBeanDefinition bd = new GenericBeanDefinition();
131                bd.setScope(BeanDefinition.SCOPE_PROTOTYPE);
132                bd.setBeanClass(clazz);
133                bd.setPropertyValues(pvs);
134                getDefaultListableBeanFactory().registerBeanDefinition(name, bd);
135        }
136
137        /**
138         * Associate the given message with the given code.
139         * @param code lookup code
140         * @param locale the locale message should be found within
141         * @param defaultMessage message associated with this lookup code
142         * @see #getStaticMessageSource
143         */
144        public void addMessage(String code, Locale locale, String defaultMessage) {
145                getStaticMessageSource().addMessage(code, locale, defaultMessage);
146        }
147
148}