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.aop.config;
018
019import org.springframework.aop.aspectj.AspectInstanceFactory;
020import org.springframework.beans.factory.BeanFactory;
021import org.springframework.beans.factory.BeanFactoryAware;
022import org.springframework.beans.factory.config.ConfigurableBeanFactory;
023import org.springframework.core.Ordered;
024import org.springframework.lang.Nullable;
025import org.springframework.util.Assert;
026import org.springframework.util.ClassUtils;
027
028/**
029 * Implementation of {@link AspectInstanceFactory} that locates the aspect from the
030 * {@link org.springframework.beans.factory.BeanFactory} using a configured bean name.
031 *
032 * @author Rob Harrop
033 * @author Juergen Hoeller
034 * @since 2.0
035 */
036public class SimpleBeanFactoryAwareAspectInstanceFactory implements AspectInstanceFactory, BeanFactoryAware {
037
038        @Nullable
039        private String aspectBeanName;
040
041        @Nullable
042        private BeanFactory beanFactory;
043
044
045        /**
046         * Set the name of the aspect bean. This is the bean that is returned when calling
047         * {@link #getAspectInstance()}.
048         */
049        public void setAspectBeanName(String aspectBeanName) {
050                this.aspectBeanName = aspectBeanName;
051        }
052
053        @Override
054        public void setBeanFactory(BeanFactory beanFactory) {
055                this.beanFactory = beanFactory;
056                Assert.notNull(this.aspectBeanName, "'aspectBeanName' is required");
057        }
058
059
060        /**
061         * Look up the aspect bean from the {@link BeanFactory} and returns it.
062         * @see #setAspectBeanName
063         */
064        @Override
065        public Object getAspectInstance() {
066                Assert.state(this.beanFactory != null, "No BeanFactory set");
067                Assert.state(this.aspectBeanName != null, "No 'aspectBeanName' set");
068                return this.beanFactory.getBean(this.aspectBeanName);
069        }
070
071        @Override
072        @Nullable
073        public ClassLoader getAspectClassLoader() {
074                if (this.beanFactory instanceof ConfigurableBeanFactory) {
075                        return ((ConfigurableBeanFactory) this.beanFactory).getBeanClassLoader();
076                }
077                else {
078                        return ClassUtils.getDefaultClassLoader();
079                }
080        }
081
082        @Override
083        public int getOrder() {
084                if (this.beanFactory != null && this.aspectBeanName != null &&
085                                this.beanFactory.isSingleton(this.aspectBeanName) &&
086                                this.beanFactory.isTypeMatch(this.aspectBeanName, Ordered.class)) {
087                        return ((Ordered) this.beanFactory.getBean(this.aspectBeanName)).getOrder();
088                }
089                return Ordered.LOWEST_PRECEDENCE;
090        }
091
092}