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 java.util.ArrayList; 020import java.util.List; 021 022import org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator; 023import org.springframework.aop.aspectj.autoproxy.AspectJAwareAdvisorAutoProxyCreator; 024import org.springframework.aop.framework.autoproxy.InfrastructureAdvisorAutoProxyCreator; 025import org.springframework.beans.factory.config.BeanDefinition; 026import org.springframework.beans.factory.support.BeanDefinitionRegistry; 027import org.springframework.beans.factory.support.RootBeanDefinition; 028import org.springframework.core.Ordered; 029import org.springframework.util.Assert; 030 031/** 032 * Utility class for handling registration of AOP auto-proxy creators. 033 * 034 * <p>Only a single auto-proxy creator should be registered yet multiple concrete 035 * implementations are available. This class provides a simple escalation protocol, 036 * allowing a caller to request a particular auto-proxy creator and know that creator, 037 * <i>or a more capable variant thereof</i>, will be registered as a post-processor. 038 * 039 * @author Rob Harrop 040 * @author Juergen Hoeller 041 * @author Mark Fisher 042 * @since 2.5 043 * @see AopNamespaceUtils 044 */ 045public abstract class AopConfigUtils { 046 047 /** 048 * The bean name of the internally managed auto-proxy creator. 049 */ 050 public static final String AUTO_PROXY_CREATOR_BEAN_NAME = 051 "org.springframework.aop.config.internalAutoProxyCreator"; 052 053 /** 054 * Stores the auto proxy creator classes in escalation order. 055 */ 056 private static final List<Class<?>> APC_PRIORITY_LIST = new ArrayList<Class<?>>(3); 057 058 static { 059 // Set up the escalation list... 060 APC_PRIORITY_LIST.add(InfrastructureAdvisorAutoProxyCreator.class); 061 APC_PRIORITY_LIST.add(AspectJAwareAdvisorAutoProxyCreator.class); 062 APC_PRIORITY_LIST.add(AnnotationAwareAspectJAutoProxyCreator.class); 063 } 064 065 066 public static BeanDefinition registerAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry) { 067 return registerAutoProxyCreatorIfNecessary(registry, null); 068 } 069 070 public static BeanDefinition registerAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry, Object source) { 071 return registerOrEscalateApcAsRequired(InfrastructureAdvisorAutoProxyCreator.class, registry, source); 072 } 073 074 public static BeanDefinition registerAspectJAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry) { 075 return registerAspectJAutoProxyCreatorIfNecessary(registry, null); 076 } 077 078 public static BeanDefinition registerAspectJAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry, Object source) { 079 return registerOrEscalateApcAsRequired(AspectJAwareAdvisorAutoProxyCreator.class, registry, source); 080 } 081 082 public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry) { 083 return registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry, null); 084 } 085 086 public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry, Object source) { 087 return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source); 088 } 089 090 public static void forceAutoProxyCreatorToUseClassProxying(BeanDefinitionRegistry registry) { 091 if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) { 092 BeanDefinition definition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME); 093 definition.getPropertyValues().add("proxyTargetClass", Boolean.TRUE); 094 } 095 } 096 097 public static void forceAutoProxyCreatorToExposeProxy(BeanDefinitionRegistry registry) { 098 if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) { 099 BeanDefinition definition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME); 100 definition.getPropertyValues().add("exposeProxy", Boolean.TRUE); 101 } 102 } 103 104 105 private static BeanDefinition registerOrEscalateApcAsRequired(Class<?> cls, BeanDefinitionRegistry registry, Object source) { 106 Assert.notNull(registry, "BeanDefinitionRegistry must not be null"); 107 108 if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) { 109 BeanDefinition apcDefinition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME); 110 if (!cls.getName().equals(apcDefinition.getBeanClassName())) { 111 int currentPriority = findPriorityForClass(apcDefinition.getBeanClassName()); 112 int requiredPriority = findPriorityForClass(cls); 113 if (currentPriority < requiredPriority) { 114 apcDefinition.setBeanClassName(cls.getName()); 115 } 116 } 117 return null; 118 } 119 120 RootBeanDefinition beanDefinition = new RootBeanDefinition(cls); 121 beanDefinition.setSource(source); 122 beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE); 123 beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); 124 registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition); 125 return beanDefinition; 126 } 127 128 private static int findPriorityForClass(Class<?> clazz) { 129 return APC_PRIORITY_LIST.indexOf(clazz); 130 } 131 132 private static int findPriorityForClass(String className) { 133 for (int i = 0; i < APC_PRIORITY_LIST.size(); i++) { 134 Class<?> clazz = APC_PRIORITY_LIST.get(i); 135 if (clazz.getName().equals(className)) { 136 return i; 137 } 138 } 139 throw new IllegalArgumentException( 140 "Class name [" + className + "] is not a known auto-proxy creator class"); 141 } 142 143}