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.context.weaving;
018
019import org.springframework.beans.BeansException;
020import org.springframework.beans.factory.BeanFactory;
021import org.springframework.beans.factory.BeanFactoryAware;
022import org.springframework.beans.factory.config.BeanPostProcessor;
023import org.springframework.context.ConfigurableApplicationContext;
024import org.springframework.instrument.classloading.LoadTimeWeaver;
025import org.springframework.lang.Nullable;
026import org.springframework.util.Assert;
027
028/**
029 * {@link org.springframework.beans.factory.config.BeanPostProcessor}
030 * implementation that passes the context's default {@link LoadTimeWeaver}
031 * to beans that implement the {@link LoadTimeWeaverAware} interface.
032 *
033 * <p>{@link org.springframework.context.ApplicationContext Application contexts}
034 * will automatically register this with their underlying {@link BeanFactory bean factory},
035 * provided that a default {@code LoadTimeWeaver} is actually available.
036 *
037 * <p>Applications should not use this class directly.
038 *
039 * @author Juergen Hoeller
040 * @since 2.5
041 * @see LoadTimeWeaverAware
042 * @see org.springframework.context.ConfigurableApplicationContext#LOAD_TIME_WEAVER_BEAN_NAME
043 */
044public class LoadTimeWeaverAwareProcessor implements BeanPostProcessor, BeanFactoryAware {
045
046        @Nullable
047        private LoadTimeWeaver loadTimeWeaver;
048
049        @Nullable
050        private BeanFactory beanFactory;
051
052
053        /**
054         * Create a new {@code LoadTimeWeaverAwareProcessor} that will
055         * auto-retrieve the {@link LoadTimeWeaver} from the containing
056         * {@link BeanFactory}, expecting a bean named
057         * {@link ConfigurableApplicationContext#LOAD_TIME_WEAVER_BEAN_NAME "loadTimeWeaver"}.
058         */
059        public LoadTimeWeaverAwareProcessor() {
060        }
061
062        /**
063         * Create a new {@code LoadTimeWeaverAwareProcessor} for the given
064         * {@link LoadTimeWeaver}.
065         * <p>If the given {@code loadTimeWeaver} is {@code null}, then a
066         * {@code LoadTimeWeaver} will be auto-retrieved from the containing
067         * {@link BeanFactory}, expecting a bean named
068         * {@link ConfigurableApplicationContext#LOAD_TIME_WEAVER_BEAN_NAME "loadTimeWeaver"}.
069         * @param loadTimeWeaver the specific {@code LoadTimeWeaver} that is to be used
070         */
071        public LoadTimeWeaverAwareProcessor(@Nullable LoadTimeWeaver loadTimeWeaver) {
072                this.loadTimeWeaver = loadTimeWeaver;
073        }
074
075        /**
076         * Create a new {@code LoadTimeWeaverAwareProcessor}.
077         * <p>The {@code LoadTimeWeaver} will be auto-retrieved from
078         * the given {@link BeanFactory}, expecting a bean named
079         * {@link ConfigurableApplicationContext#LOAD_TIME_WEAVER_BEAN_NAME "loadTimeWeaver"}.
080         * @param beanFactory the BeanFactory to retrieve the LoadTimeWeaver from
081         */
082        public LoadTimeWeaverAwareProcessor(BeanFactory beanFactory) {
083                this.beanFactory = beanFactory;
084        }
085
086
087        @Override
088        public void setBeanFactory(BeanFactory beanFactory) {
089                this.beanFactory = beanFactory;
090        }
091
092
093        @Override
094        public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
095                if (bean instanceof LoadTimeWeaverAware) {
096                        LoadTimeWeaver ltw = this.loadTimeWeaver;
097                        if (ltw == null) {
098                                Assert.state(this.beanFactory != null,
099                                                "BeanFactory required if no LoadTimeWeaver explicitly specified");
100                                ltw = this.beanFactory.getBean(
101                                                ConfigurableApplicationContext.LOAD_TIME_WEAVER_BEAN_NAME, LoadTimeWeaver.class);
102                        }
103                        ((LoadTimeWeaverAware) bean).setLoadTimeWeaver(ltw);
104                }
105                return bean;
106        }
107
108        @Override
109        public Object postProcessAfterInitialization(Object bean, String name) {
110                return bean;
111        }
112
113}