/**
* 这个接口可以被那些在处理Configuration类型的过程中需要注册额外Bean定义信息的类来实现。
* Interface to be implemented by types that register additional bean definitions when
* processing @{@link Configuration} classes. Useful when operating at the bean definition
* level (as opposed to {@code @Bean} method/instance level) is desired or necessary.
*
* 和@Configuration注解@ImportSelector注解用于,这个类型的类可以提供给@Import注解(也可以
* 直接被ImportSelector返回)
* <p>Along with {@code @Configuration} and {@link ImportSelector}, classes of this type
* may be provided to the @{@link Import} annotation (or may also be returned from an
* {@code ImportSelector}).
*
* 可以同时实现Aware系列接口并且方法调用的优先级高于registerBeanDefinitions
* <p>An {@link ImportBeanDefinitionRegistrar} may implement any of the following
* {@link org.springframework.beans.factory.Aware Aware} interfaces, and their respective
* methods will be called prior to {@link #registerBeanDefinitions}:
* <ul>
* <li>{@link org.springframework.context.EnvironmentAware EnvironmentAware}</li>
* <li>{@link org.springframework.beans.factory.BeanFactoryAware BeanFactoryAware}
* <li>{@link org.springframework.beans.factory.BeanClassLoaderAware BeanClassLoaderAware}
* <li>{@link org.springframework.context.ResourceLoaderAware ResourceLoaderAware}
* </ul>
*
* <p>See implementations and associated unit tests for usage examples.
*
* @author Chris Beams
* @since 3.1
* @see Import
* @see ImportSelector
* @see Configuration
*/publicinterfaceImportBeanDefinitionRegistrar{/**
* 基于导入的@Configuration类给出的注解元信息,在有必要的情况下注册Bean的定义信息
* Register bean definitions as necessary based on the given annotation metadata of
* the importing {@code @Configuration} class.
*
* <p>Note that {@link BeanDefinitionRegistryPostProcessor} types may <em>not</em> be
* registered here, due to lifecycle constraints related to {@code @Configuration}
* class processing.
* @param importingClassMetadata annotation metadata of the importing class
* @param registry current bean definition registry
*/publicvoidregisterBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry);}
/**
* 通过BeanDefinitionRegistry注册一个自动代理创建器。后面一句话大概意思是会基于mode和proxyTargetClass
* 这两个属性来创建Bean
* Registers an auto proxy creator against the current {@link BeanDefinitionRegistry}
* as appropriate based on an {@code @Enable*} annotation having {@code mode} and
* {@code proxyTargetClass} attributes set to the correct values.
*
* @author Chris Beams
* @since 3.1
* @see EnableAspectJAutoProxy
*/publicclassAutoProxyRegistrarimplementsImportBeanDefinitionRegistrar{privatefinal Log logger = LogFactory.getLog(getClass());/**
* 注册,扩展和配置标准的自动代理创建器,通过寻找申明了mode和proxyTargetClass的注解,如果mode是PROXY,则会注册一个自动代理创建器(APC)
* 如果proxyTargetClass设置为true,则会使用CGLIB创建代理
* Register, escalate, and configure the standard auto proxy creator (APC) against the
* given registry. Works by finding the nearest annotation declared on the importing
* {@code @Configuration} class that has both {@code mode} and {@code proxyTargetClass}
* attributes. If {@code mode} is set to {@code PROXY}, the APC is registered; if
* {@code proxyTargetClass} is set to {@code true}, then the APC is forced to use
* subclass (CGLIB) proxying。
* <p>Several {@code @Enable*} annotations expose both {@code mode} and
* {@code proxyTargetClass} attributes. It is important to note that most of these
* capabilities end up sharing a {@linkplain AopConfigUtils#AUTO_PROXY_CREATOR_BEAN_NAME
* single APC}. For this reason, this implementation doesn't "care" exactly which
* annotation it finds -- as long as it exposes the right {@code mode} and
* {@code proxyTargetClass} attributes, the APC can be registered and configured all
* the same.
*/@OverridepublicvoidregisterBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry){boolean candidateFound =false;
Set<String> annoTypes = importingClassMetadata.getAnnotationTypes();for(String annoType : annoTypes){
AnnotationAttributes candidate = AnnotationConfigUtils.attributesFor(importingClassMetadata, annoType);if(candidate == null){continue;}
Object mode = candidate.get("mode");
Object proxyTargetClass = candidate.get("proxyTargetClass");if(mode != null && proxyTargetClass != null && AdviceMode.class== mode.getClass()&&
Boolean.class== proxyTargetClass.getClass()){
candidateFound =true;if(mode == AdviceMode.PROXY){//JDK代理方式
AopConfigUtils.registerAutoProxyCreatorIfNecessary(registry);if((Boolean) proxyTargetClass){
AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);return;}}}}if(!candidateFound){
String name =getClass().getSimpleName();
logger.warn(String.format("%s was imported but no annotations were found "+"having both 'mode' and 'proxyTargetClass' attributes of type "+"AdviceMode and boolean respectively. This means that auto proxy "+"creator registration and configuration may not have occurred as "+"intended, and components may not be proxied as expected. Check to "+"ensure that %s has been @Import'ed on the same class where these "+"annotations are declared; otherwise remove the import of %s "+"altogether.", name, name, name));}}}//AopConfigUtils.registerAutoProxyCreatorIfNecessary(registry);最终调用的是:registerOrEscalateApcAsRequired(InfrastructureAdvisorAutoProxyCreator.class, registry, source);//AUTO_PROXY_CREATOR_BEAN_NAME="org.springframework.aop.config.internalAutoProxyCreator";
说明最终注册的是:registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);
/**
* Registers an {@link org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator
* AnnotationAwareAspectJAutoProxyCreator} against the current {@link BeanDefinitionRegistry}
* as appropriate based on a given @{@link EnableAspectJAutoProxy} annotation.
*
* @author Chris Beams
* @author Juergen Hoeller
* @since 3.1
* @see EnableAspectJAutoProxy
*/classAspectJAutoProxyRegistrarimplementsImportBeanDefinitionRegistrar{/**
* Register, escalate, and configure the AspectJ auto proxy creator based on the value
* of the @{@link EnableAspectJAutoProxy#proxyTargetClass()} attribute on the importing
* {@code @Configuration} class.
*/@OverridepublicvoidregisterBeanDefinitions(
AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry){
AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
AnnotationAttributes enableAspectJAutoProxy =
AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);if(enableAspectJAutoProxy != null){if(enableAspectJAutoProxy.getBoolean("proxyTargetClass")){
AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);}if(enableAspectJAutoProxy.getBoolean("exposeProxy")){
AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);}}}}
AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);//最后调用的是registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.TYPE)@Documented@Import(ApolloConfigRegistrar.class)public @interfaceEnableApolloConfig{/**
* Apollo namespaces to inject configuration into Spring Property Sources.
*/
String[]value()default{ConfigConsts.NAMESPACE_APPLICATION};/**
* The order of the apollo config, default is {@link Ordered#LOWEST_PRECEDENCE}, which is Integer.MAX_VALUE.
* If there are properties with the same name in different apollo configs, the apollo config with smaller order wins.
* @return
*/intorder()default Ordered.LOWEST_PRECEDENCE;}