Spring 为开发者提供了丰富的扩展点,这些扩展点可以在满足“开闭原则”前提下影响单个Bean或者多个Bean,这里总结一类扩展点 —— BeanPostProcessor
。顾名思义,该接口为「Bean后置处理器」,该接口及其子接口可以在Bean生命周期中实现Bean实例定制化功能。Spring Bean 属性赋值、AOP代理等功能均是通过该接口实现,该接口重要性可见一斑。
在该接口中定义了两个方法
public interface BeanPostProcessor {
// 在调用bean任何初始化方法之前调用该方法, 调用方法时, bean已经完成了属性赋值
// 初始化方法主要包括:
// 1. InitializingBean 接口的 afterPropertiesSet方法
// 2. 用户自定义的 init-method
default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
// bean所有初始化方法执行完成后调用该方法
default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
}
BeanPostProcessor
有如下几个子接口,各子接口功能后文介绍
在每个 Bean 生命周期特定时机,Spring 都会取出特定 BeanPostProcessor
子接口执行,所以 BeanFactory
在管理 BeanPostProcessor
时会特殊对待。
AbstractBeanFactory
中与 BeanPostProcessor
存储相关有如下两个字段,
/** BeanPostProcessors to apply. */
// 存储所有 BeanPostProcessor 实现类
private final List<BeanPostProcessor> beanPostProcessors = new BeanPostProcessorCacheAwareList();
/** Cache of pre-filtered post-processors. */
// 分门别类缓存 BeanPostProcessor 子接口实现类
private volatile BeanPostProcessorCache beanPostProcessorCache;
// ...
@Override
public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) {
Assert.notNull(beanPostProcessor, "BeanPostProcessor must not be null");
// Remove from old position, if any
this.beanPostProcessors.remove(beanPostProcessor);
// Add to end of list
this.beanPostProcessors.add(beanPostProcessor);
}
public void addBeanPostProcessors(Collection<? extends BeanPostProcessor> beanPostProcessors) {
this.beanPostProcessors.removeAll(beanPostProcessors);
this.beanPostProcessors.addAll(beanPostProcessors);
}
可以看出 AbstractBeanFactory
使用内部静态类 —— BeanPostProcessorCache
对 BeanPostProcessor
子接口实现类分门别类进行缓存。
/**
* Internal cache of pre-filtered post-processors.
*
* @since 5.3
*/
static class BeanPostProcessorCache {
final List<InstantiationAwareBeanPostProcessor> instantiationAware = new ArrayList<>();
final List<SmartInstantiationAwareBeanPostProcessor> smartInstantiationAware = new ArrayList<>();
final List<DestructionAwareBeanPostProcessor> destructionAware = new ArrayList<>();
final List<MergedBeanDefinitionPostProcessor> mergedDefinition = new ArrayList<>();
}
在获取 BeanPostProcessorCache
时,将 beanPostProcessors
中 BeanPostProcessor
根据实现接口分别缓存到不同字段中
/**
* Return the internal cache of pre-filtered post-processors,
* freshly (re-)building it if necessary.
* @since 5.3
*/
BeanPostProcessorCache getBeanPostProcessorCache() {
BeanPostProcessorCache bpCache = this.beanPostProcessorCache; // 保证线程安全
if (bpCache == null) {
bpCache = new BeanPostProcessorCache();
for (BeanPostProcessor bp : this.beanPostProcessors) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
bpCache.instantiationAware.add((InstantiationAwareBeanPostProcessor) bp);
if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
bpCache.smartInstantiationAware.add((SmartInstantiationAwareBeanPostProcessor) bp);
}
}
if (bp instanceof DestructionAwareBeanPostProcessor) {
bpCache.destructionAware.add((DestructionAwareBeanPostProcessor) bp);
}
if (bp instanceof MergedBeanDefinitionPostProcessor) {
bpCache.mergedDefinition.add((MergedBeanDefinitionPostProcessor) bp);
}
}
this.beanPostProcessorCache = bpCache;
}
return bpCache;
}
注意,beanPostProcessors
并没有使用 JDK 内建 List
,而是创建了继承自 CopyOnWriteArrayList
的 BeanPostProcessorCacheAwareList
,使用该类为了在添加或者删除 BeanPostProcessor
时立即清除缓存,保证缓存有效,
private class BeanPostProcessorCacheAwareList extends CopyOnWriteArrayList<BeanPostProcessor> {
@Override
public BeanPostProcessor set(int index, BeanPostProcessor element) {
BeanPostProcessor result = super.set(index, element);
beanPostProcessorCache = null; // 失效缓存
return result;
}
@Override
public boolean add(BeanPostProcessor o) {
boolean success = super.add(o);
beanPostProcessorCache = null; // 失效缓存
return success;
}
@Override
public void add(int index, BeanPostProcessor element) {
super.add(index, element);
beanPostProcessorCache = null; // 失效缓存
}
// ..., 省略其他方法
}
由于 BeanPostProcessor
和 Bean 生命周期相关,所以 BeanPostProcessor
必定在 Bean 创建之前注册,看下
org.springframework.context.support.AbstractApplicationContext#refresh
函数,
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");
// Prepare this context for refreshing.
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory);
StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
// Invoke factory processors registered as beans in the context.
// 该步骤会调用org.springframework.context.annotation.ConfigurationClassPostProcessor#postProcessBeanDefinitionRegistry方法, 完成 BeanDefinition 注册
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
// 注册 BeanPostProcessor, 拦截 bean 创建过程
registerBeanPostProcessors(beanFactory);
beanPostProcess.end();
// Initialize message source for this context.
initMessageSource();
// Initialize event multicaster for this context.
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
onRefresh();
// Check for listener beans and register them.
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
finishRefresh();
}
catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
// Destroy already created singletons to avoid dangling resources.
destroyBeans();
// Reset 'active' flag.
cancelRefresh(ex);
// Propagate exception to caller.
throw ex;
}
finally {
// Reset common introspection caches in Spring's core, since we
// might not ever need metadata for singleton beans anymore...
resetCommonCaches();
contextRefresh.end();
}
}
}
registerBeanPostProcessors(beanFactory)
内部调用org.springframework.context.support.PostProcessorRegistrationDelegate#registerBeanPostProcessors(org.springframework.beans.factory.config.ConfigurableListableBeanFactory, org.springframework.context.support.AbstractApplicationContext)
方法,该方法内部会根据顺序创建并注册 BeanPostProcessor
,
public static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
// WARNING: Although it may appear that the body of this method can be easily
// refactored to avoid the use of multiple loops and multiple lists, the use
// of multiple lists and multiple passes over the names of processors is
// intentional. We must ensure that we honor the contracts for PriorityOrdered
// and Ordered processors. Specifically, we must NOT cause processors to be
// instantiated (via getBean() invocations) or registered in the ApplicationContext
// in the wrong order.
//
// Before submitting a pull request (PR) to change this method, please review the
// list of all declined PRs involving changes to PostProcessorRegistrationDelegate
// to ensure that your proposal does not result in a breaking change:
// https://github.com/spring-projects/spring-framework/issues?q=PostProcessorRegistrationDelegate+is%3Aclosed+label%3A%22status%3A+declined%22
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
// Register BeanPostProcessorChecker that logs an info message when
// a bean is created during BeanPostProcessor instantiation, i.e. when
// a bean is not eligible for getting processed by all BeanPostProcessors.
int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
// BeanPostProcessorChecker 作用是, 如果在 BeanPostProcessor 实例化期间创建 bean 时打印日志
// 因为之后实例化的 BeanPostProcessor 错过了该bean部分生命周期
// 具体详情参考 https://www.yourbatman.cn/x2y/6abf4a82.html 这篇博文
beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
// Separate between BeanPostProcessors that implement PriorityOrdered,
// Ordered, and the rest.
List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
List<String> orderedPostProcessorNames = new ArrayList<>();
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
priorityOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
}
else {
nonOrderedPostProcessorNames.add(ppName);
}
}
// First, register the BeanPostProcessors that implement PriorityOrdered.
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
// 一. 优先创建完成所有实现 PriorityOrdered 接口 BeanPostProcessor, 再一起注册
registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
// Next, register the BeanPostProcessors that implement Ordered.
List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
for (String ppName : orderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
orderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
sortPostProcessors(orderedPostProcessors, beanFactory);
// 二. 再创建完所有实现 Ordered 接口 BeanPostProcessor, 再一起注册
// 所以实现 PriorityOrdered 接口 BeanPostProcessor 会作用到这些 BeanPostProcessor 完整生命周期中
registerBeanPostProcessors(beanFactory, orderedPostProcessors);
// Now, register all regular BeanPostProcessors.
List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
for (String ppName : nonOrderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
nonOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
// 三. 最后创建完其他 BeanPostProcessor, 再一起注册
// 所以实现 PriorityOrdered 和 Ordered 接口 BeanPostProcessor 都会作用到这些 BeanPostProcessor 完整生命周期中
registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);
// Finally, re-register all internal BeanPostProcessors.
sortPostProcessors(internalPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, internalPostProcessors);
// Re-register post-processor for detecting inner beans as ApplicationListeners,
// moving it to the end of the processor chain (for picking up proxies etc).
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}
所以可以在 org.springframework.context.support.AbstractApplicationContext#registerBeanPostProcessors
之前注册 BeanPostProcessor
BeanDefinition
或者直接注册 BeanPostProcessor
实例。
接下来分享几个重要 BeanPostProcessor
是何时注册的,其实可以看到以上源码中已经注册了一个 BeanPostProcessorChecker
,
如果应用是传统非响应式Web服务,则会创建 AnnotationConfigServletWebServerApplicationContext
应用上下文,默认构造器如下,
public AnnotationConfigServletWebServerApplicationContext() {
this.reader = new AnnotatedBeanDefinitionReader(this);
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
该构造方法在创建 AnnotatedBeanDefinitionReader
最终会调用 org.springframework.context.annotation.AnnotationConfigUtils#registerAnnotationConfigProcessors(org.springframework.beans.factory.support.BeanDefinitionRegistry, java.lang.Object)
, 该方法内部会注册几个重要 BeanDefinition
,
public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
BeanDefinitionRegistry registry, @Nullable Object source) {
DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
if (beanFactory != null) {
if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
}
if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
}
}
Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);
if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
}
if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
}
// Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor.
if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
}
// Check for JPA support, and if present add the PersistenceAnnotationBeanPostProcessor.
if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition();
try {
def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME,
AnnotationConfigUtils.class.getClassLoader()));
}
catch (ClassNotFoundException ex) {
throw new IllegalStateException(
"Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex);
}
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME));
}
if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME));
}
if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME));
}
return beanDefs;
}
几个重要 BeanDefinition
作用为
ConfigurationClassPostProcessor
, 该类非 BeanPostProcessor
实现类,而是 BeanDefinitionRegistryPostProcessor
实现类,只是该类尤为重要,这里顺便提一下,该类以启动类作为引导 @Configuration
, 并通过 org.springframework.context.annotation.ConfigurationClassParser
递归处理配置类内部类,@PropertySource
, @ComponentScan
, @ImportResource
,@Bean
等注册 BeanDefinition
。AutowiredAnnotationBeanPostProcessor
,SmartInstantiationAwareBeanPostProcessor
& MergedBeanDefinitionPostProcessor
接口实现类,处理 Spring @Autowired
和 @Value
注解以及 JSR-330 @Inject
注解属性赋值;CommonAnnotationBeanPostProcessor
,实现 InstantiationAwareBeanPostProcessor
& DestructionAwareBeanPostProcessor
& MergedBeanDefinitionPostProcessor
接口,负责解析@Resource
、@WebServiceRef
、@EJB
三个 JSR-250 注解;org.springframework.context.support.AbstractApplicationContext#refresh
方法调用 org.springframework.context.support.AbstractApplicationContext#prepareBeanFactory
方法准备 Bean 工厂时会注册两个重要 BeanPostProcessor
实例,
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// Tell the internal bean factory to use the context's class loader etc.
beanFactory.setBeanClassLoader(getClassLoader());
if (!shouldIgnoreSpel) {
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
}
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
// Configure the bean factory with context callbacks.
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
beanFactory.ignoreDependencyInterface(ApplicationStartupAware.class);
// BeanFactory interface not registered as resolvable type in a plain factory.
// MessageSource registered (and found for autowiring) as a bean.
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
beanFactory.registerResolvableDependency(ApplicationContext.class, this);
// Register early post-processor for detecting inner beans as ApplicationListeners.
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
// Detect a LoadTimeWeaver and prepare for weaving, if found.
if (!NativeDetector.inNativeImage() && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
// Set a temporary ClassLoader for type matching.
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
// Register default environment beans.
if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
}
if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
}
if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
}
if (!beanFactory.containsLocalBean(APPLICATION_STARTUP_BEAN_NAME)) {
beanFactory.registerSingleton(APPLICATION_STARTUP_BEAN_NAME, getApplicationStartup());
}
}
这两个 BeanPostProcessor
实例作用为,
ApplicationContextAwareProcessor
,BeanPostProcessor
接口实现类。顾名思义,该类将 ApplicationContext
提供给实现ApplicationContextAware
接口的 Bean。但是需要注意的是, ApplicationContext
同时实现了事件发布,国际化,资源加载等功能,所以如果 Bean 实现了 ApplicationEventPublisherAware
| MessageSourceAware
| ResourceLoaderAware
,也需要调用相应回调方法。另外 ApplicationContext
内部包含 Environment
& ApplicationStartup
& BeanFactory
所以也能处理实现 EnvironmentAware
| EmbeddedValueResolverAware
| ApplicationStartupAware
接口 Bean;ApplicationListenerDetector
,MergedBeanDefinitionPostProcessor
接口实现类,ApplicationListener
探测器。用于检测无法被 getBeanNamesForType
可靠检测到的ApplicationListener
;org.springframework.context.annotation.ConfigurationClassPostProcessor#postProcessBeanFactory
将所有配置类处理完成后会注册一个 ImportAwareBeanPostProcessor
,
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
int factoryId = System.identityHashCode(beanFactory);
if (this.factoriesPostProcessed.contains(factoryId)) {
throw new IllegalStateException(
"postProcessBeanFactory already called on this post-processor against " + beanFactory);
}
this.factoriesPostProcessed.add(factoryId);
if (!this.registriesPostProcessed.contains(factoryId)) {
// BeanDefinitionRegistryPostProcessor hook apparently not supported...
// Simply call processConfigurationClasses lazily at this point then.
processConfigBeanDefinitions((BeanDefinitionRegistry) beanFactory);
}
enhanceConfigurationClasses(beanFactory);
beanFactory.addBeanPostProcessor(new ImportAwareBeanPostProcessor(beanFactory));
}
ImportAwareBeanPostProcessor
为 InstantiationAwareBeanPostProcessor
实现类,该类主要完成两件事,
@Configuration
配置类生成 EnhancedConfiguration
代理,该代理内部会使用 $$beanFactory
存储 BeanFactory
,org.springframework.context.annotation.ConfigurationClassPostProcessor.ImportAwareBeanPostProcessor#postProcessProperties
方法中就是将 BeanFactory
设置到该字段中;ImportAware
接口,通过 @Import
导入的配置类如果实现了 ImportAware
接口就可以获取到导入该配置类接口的 AnnotationMetadata
;和其他普通 Bean 一样通过 @Configuration
配置类注入到容器中,注入的几个重要 BeanPostProcessor
如下,
ConfigurationPropertiesBindingPostProcessor
, BeanPostProcessor
接口实现类,处理 @ConfigurationProperties
注解 Spring Boot JavaBean 属性绑定,关于JavaBean 属性绑定参考《Spring Boot v2.4.4源码解析(六)属性绑定篇上 —— 类型安全配置属性》,通过 EnableConfigurationProperties
注解引入;AnnotationAwareAspectJAutoProxyCreator
,SmartInstantiationAwareBeanPostProcessor
接口实现类,处理 Spring AOP,AopAutoConfiguration
配置会引入 AnnotationAwareAspectJAutoProxyCreator
;