001/*
002 * Copyright 2002-2018 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.beans.MutablePropertyValues;
020import org.springframework.beans.factory.config.BeanDefinition;
021import org.springframework.beans.factory.config.BeanReference;
022import org.springframework.beans.factory.parsing.AbstractComponentDefinition;
023import org.springframework.lang.Nullable;
024import org.springframework.util.Assert;
025
026/**
027 * {@link org.springframework.beans.factory.parsing.ComponentDefinition}
028 * that bridges the gap between the advisor bean definition configured
029 * by the {@code <aop:advisor>} tag and the component definition
030 * infrastructure.
031 *
032 * @author Rob Harrop
033 * @author Juergen Hoeller
034 * @since 2.0
035 */
036public class AdvisorComponentDefinition extends AbstractComponentDefinition {
037
038        private final String advisorBeanName;
039
040        private final BeanDefinition advisorDefinition;
041
042        private final String description;
043
044        private final BeanReference[] beanReferences;
045
046        private final BeanDefinition[] beanDefinitions;
047
048
049        public AdvisorComponentDefinition(String advisorBeanName, BeanDefinition advisorDefinition) {
050                this(advisorBeanName, advisorDefinition, null);
051        }
052
053        public AdvisorComponentDefinition(
054                        String advisorBeanName, BeanDefinition advisorDefinition, @Nullable BeanDefinition pointcutDefinition) {
055
056                Assert.notNull(advisorBeanName, "'advisorBeanName' must not be null");
057                Assert.notNull(advisorDefinition, "'advisorDefinition' must not be null");
058                this.advisorBeanName = advisorBeanName;
059                this.advisorDefinition = advisorDefinition;
060
061                MutablePropertyValues pvs = advisorDefinition.getPropertyValues();
062                BeanReference adviceReference = (BeanReference) pvs.get("adviceBeanName");
063                Assert.state(adviceReference != null, "Missing 'adviceBeanName' property");
064
065                if (pointcutDefinition != null) {
066                        this.beanReferences = new BeanReference[] {adviceReference};
067                        this.beanDefinitions = new BeanDefinition[] {advisorDefinition, pointcutDefinition};
068                        this.description = buildDescription(adviceReference, pointcutDefinition);
069                }
070                else {
071                        BeanReference pointcutReference = (BeanReference) pvs.get("pointcut");
072                        Assert.state(pointcutReference != null, "Missing 'pointcut' property");
073                        this.beanReferences = new BeanReference[] {adviceReference, pointcutReference};
074                        this.beanDefinitions = new BeanDefinition[] {advisorDefinition};
075                        this.description = buildDescription(adviceReference, pointcutReference);
076                }
077        }
078
079        private String buildDescription(BeanReference adviceReference, BeanDefinition pointcutDefinition) {
080                return "Advisor <advice(ref)='" +
081                                adviceReference.getBeanName() + "', pointcut(expression)=[" +
082                                pointcutDefinition.getPropertyValues().get("expression") + "]>";
083        }
084
085        private String buildDescription(BeanReference adviceReference, BeanReference pointcutReference) {
086                return "Advisor <advice(ref)='" +
087                                adviceReference.getBeanName() + "', pointcut(ref)='" +
088                                pointcutReference.getBeanName() + "'>";
089        }
090
091
092        @Override
093        public String getName() {
094                return this.advisorBeanName;
095        }
096
097        @Override
098        public String getDescription() {
099                return this.description;
100        }
101
102        @Override
103        public BeanDefinition[] getBeanDefinitions() {
104                return this.beanDefinitions;
105        }
106
107        @Override
108        public BeanReference[] getBeanReferences() {
109                return this.beanReferences;
110        }
111
112        @Override
113        @Nullable
114        public Object getSource() {
115                return this.advisorDefinition.getSource();
116        }
117
118}