1. 环境搭建
代码已经上传至 https://github.com/masteryourself/spring-framework,工程是
tutorial-spring-configurationclasspostprocessor
2. 源码解析
详细的源码注释可参考 https://github.com/masteryourself/spring-framework
2.1 ConfigurationClassPostProcessor 类分析
ConfigurationClassPostProcessor 实现了 BeanDefinitionRegistryPostProcessor 接口,所以重点关注 postProcessBeanDefinitionRegistry()
和 postProcessBeanFactory()
方法
ConfigurationClassPostProcessor 在 postProcessBeanDefinitionRegistry()
方法中完成了 bean 的扫描,并添加到 BeanDefinitionMap 属性中
ConfigurationClassPostProcessor 在 postProcessBeanFactory()
方法中判断是否需要对其进行 cglib 增强处理(判断依据就是是否有 @Configuration
注解)
2.2 postProcessBeanDefinitionRegistry() 方法分析
2.2.1 流程分析
2.2.2 核心代码剖析
1. org.springframework.context.annotation.ConfigurationClassPostProcessor#processConfigBeanDefinitions
public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
// 存放所有的 BeanDefinition 信息,BeanDefinitionHolder 里包含了 BeanDefinition
List<BeanDefinitionHolder> configCandidates = new ArrayList<>();
// 获取容器中所有 bean 的名称,此时有 6 个
// 0 = "org.springframework.context.annotation.internalConfigurationAnnotationProcessor"
// 1 = "org.springframework.context.annotation.internalAutowiredAnnotationProcessor"
// 2 = "org.springframework.context.annotation.internalCommonAnnotationProcessor"
// 3 = "org.springframework.context.event.internalEventListenerProcessor"
// 4 = "org.springframework.context.event.internalEventListenerFactory"
// 5 = "springConfig"
String[] candidateNames = registry.getBeanDefinitionNames();
for (String beanName : candidateNames) {
BeanDefinition beanDef = registry.getBeanDefinition(beanName);
// 如果 beanDef 的 configurationClass 属性为 full 或者 lite,则表示已经处理过了
if (ConfigurationClassUtils.isFullConfigurationClass(beanDef) ||
ConfigurationClassUtils.isLiteConfigurationClass(beanDef)) {
if (logger.isDebugEnabled()) {
logger.debug("Bean definition has already been processed as a configuration class: " + beanDef);
}
}
// 判断是否有注解,如 @Configuration、@Component、@ComponentScan、@Import、@ImportResource、@Bean 注解
else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {
// 满足以上条件才会放到 configCandidates 集合中,这里只有【SpringConfig】
configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
}
}
...
// Parse each @Configuration class
// 初始化 ConfigurationClassParser,用于解析配置类
ConfigurationClassParser parser = new ConfigurationClassParser(
this.metadataReaderFactory, this.problemReporter, this.environment,
this.resourceLoader, this.componentScanBeanNameGenerator, registry);
// 用于去重复
Set<BeanDefinitionHolder> candidates = new LinkedHashSet<>(configCandidates);
// 判断是否处理过
Set<ConfigurationClass> alreadyParsed = new HashSet<>(configCandidates.size());
do {
// 重点,解析配置类,这里就只有【springConfig】
// Bean definition with name 'springConfig': Generic bean: class [pers.masteryourself.tutorial.spring.framework.scan.config.SpringConfig]; scope=singleton; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null
parser.parse(candidates);
parser.validate();
// 获取 parser() 方法解析后的类,这里有 3 个,如下所示:
// 0 = {ConfigurationClass@1471} "ConfigurationClass: beanName 'null', pers.masteryourself.tutorial.spring.framework.scan.bean.Cat"
// 1 = {ConfigurationClass@1272} "ConfigurationClass: beanName 'null', class path resource [pers/masteryourself/tutorial/spring/framework/scan/bean/Dog.class]"
// 2 = {ConfigurationClass@1197} "ConfigurationClass: beanName 'springConfig', pers.masteryourself.tutorial.spring.framework.scan.config.SpringConfig"
Set<ConfigurationClass> configClasses = new LinkedHashSet<>(parser.getConfigurationClasses());
configClasses.removeAll(alreadyParsed);
// Read the model and create bean definitions based on its content
if (this.reader == null) {
this.reader = new ConfigurationClassBeanDefinitionReader(
registry, this.sourceExtractor, this.resourceLoader, this.environment,
this.importBeanNameGenerator, parser.getImportRegistry());
}
// 调用 loadBeanDefinitions() 方法进行注册 BeanDefinition
this.reader.loadBeanDefinitions(configClasses);
alreadyParsed.addAll(configClasses);
...
}
while (!candidates.isEmpty());
...
}
2. org.springframework.context.annotation.ConfigurationClassParser#processConfigurationClass
protected void processConfigurationClass(ConfigurationClass configClass) throws IOException {
...
// Recursively process the configuration class and its superclass hierarchy.
SourceClass sourceClass = asSourceClass(configClass);
do {
// 调用 doProcessConfigurationClass 方法进行解析,这个方法会被递归调用,但是 configClass 一直在变
sourceClass = doProcessConfigurationClass(configClass, sourceClass);
}
// 注意这里的循环条件,只有返回 null 才会结束
while (sourceClass != null);
// 用来存放扫描出来的 bean(这里的 bean 不是对象,仅仅是 bean 的信息,还没有初始化)
this.configurationClasses.put(configClass, configClass);
}
3. org.springframework.context.annotation.ConfigurationClassParser#doProcessConfigurationClass
protected final SourceClass doProcessConfigurationClass(ConfigurationClass configClass, SourceClass sourceClass)
throws IOException {
if (configClass.getMetadata().isAnnotated(Component.class.getName())) {
// Recursively process any member (nested) classes first
// 处理内部类
processMemberClasses(configClass, sourceClass);
}
// Process any @PropertySource annotations
// 处理 @PropertySources 注解
for (AnnotationAttributes propertySource : AnnotationConfigUtils.attributesForRepeatable(
sourceClass.getMetadata(), PropertySources.class,
org.springframework.context.annotation.PropertySource.class)) {
if (this.environment instanceof ConfigurableEnvironment) {
processPropertySource(propertySource);
}
else {
logger.info("Ignoring @PropertySource annotation on [" + sourceClass.getMetadata().getClassName() +
"]. Reason: Environment must implement ConfigurableEnvironment");
}
}
// Process any @ComponentScan annotations
// 处理 @ComponentScans、@ComponentScan 注解
Set<AnnotationAttributes> componentScans = AnnotationConfigUtils.attributesForRepeatable(
sourceClass.getMetadata(), ComponentScans.class, ComponentScan.class);
if (!componentScans.isEmpty() &&
!this.conditionEvaluator.shouldSkip(sourceClass.getMetadata(), ConfigurationPhase.REGISTER_BEAN)) {
for (AnnotationAttributes componentScan : componentScans) {
// The config class is annotated with @ComponentScan -> perform the scan immediately
// 扫描普通类(即用 @Component 注解标注的类),然后注册到 beanDefinitionMap
Set<BeanDefinitionHolder> scannedBeanDefinitions =
this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName());
// Check the set of scanned definitions for any further config classes and parse recursively if needed
for (BeanDefinitionHolder holder : scannedBeanDefinitions) {
// 检查扫描出来的类是否还有 @Configuration 注解
BeanDefinition bdCand = holder.getBeanDefinition().getOriginatingBeanDefinition();
if (bdCand == null) {
bdCand = holder.getBeanDefinition();
}
if (ConfigurationClassUtils.checkConfigurationClassCandidate(bdCand, this.metadataReaderFactory)) {
// 最终调用 processConfigurationClass() 方法进行递归
parse(bdCand.getBeanClassName(), holder.getBeanName());
}
}
}
}
// Process any @Import annotations
// 处理 @Import 注解,这里有三种情况:@Import 类、ImportSelector、ImportBeanDefinitionRegistrar
processImports(configClass, sourceClass, getImports(sourceClass), true);
// Process any @ImportResource annotations
// 处理 @ImportResource 注解
AnnotationAttributes importResource =
AnnotationConfigUtils.attributesFor(sourceClass.getMetadata(), ImportResource.class);
if (importResource != null) {
String[] resources = importResource.getStringArray("locations");
Class<? extends BeanDefinitionReader> readerClass = importResource.getClass("reader");
for (String resource : resources) {
String resolvedResource = this.environment.resolveRequiredPlaceholders(resource);
configClass.addImportedResource(resolvedResource, readerClass);
}
}
// Process individual @Bean methods
// 处理 @Bean 注解
Set<MethodMetadata> beanMethods = retrieveBeanMethodMetadata(sourceClass);
for (MethodMetadata methodMetadata : beanMethods) {
configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));
}
// Process default methods on interfaces
processInterfaces(configClass, sourceClass);
...
return null;
}
4. org.springframework.context.annotation.ConfigurationClassParser#processImports
private void processImports(ConfigurationClass configClass, SourceClass currentSourceClass,
Collection<SourceClass> importCandidates, boolean checkForCircularImports) {
...
else {
this.importStack.push(configClass);
try {
// 循环对 @Import 注解的类进行处理
for (SourceClass candidate : importCandidates) {
// 第一种情况:处理 ImportSelector 情况,如【ExtImportSelector】
if (candidate.isAssignable(ImportSelector.class)) {
// Candidate class is an ImportSelector -> delegate to it to determine imports
Class<?> candidateClass = candidate.loadClass();
// 反射获取实例
ImportSelector selector = BeanUtils.instantiateClass(candidateClass, ImportSelector.class);
// 处理 xxxAware 接口
ParserStrategyUtils.invokeAwareMethods(
selector, this.environment, this.resourceLoader, this.registry);
if (selector instanceof DeferredImportSelector) {
this.deferredImportSelectorHandler.handle(
configClass, (DeferredImportSelector) selector);
}
else {
// 调用 selectImports 方法获取返回值
String[] importClassNames = selector.selectImports(currentSourceClass.getMetadata());
Collection<SourceClass> importSourceClasses = asSourceClasses(importClassNames);
// 递归处理,防止还有 @Import 这种情况
processImports(configClass, currentSourceClass, importSourceClasses, false);
}
}
// 2. 第二种情况:处理 ImportBeanDefinitionRegistrar 情况,如【ExtImportBeanDefinitionRegistrar】
else if (candidate.isAssignable(ImportBeanDefinitionRegistrar.class)) {
// Candidate class is an ImportBeanDefinitionRegistrar ->
// delegate to it to register additional bean definitions
Class<?> candidateClass = candidate.loadClass();
// 反射获取实例
ImportBeanDefinitionRegistrar registrar =
BeanUtils.instantiateClass(candidateClass, ImportBeanDefinitionRegistrar.class);
// 处理 xxxAware 接口
ParserStrategyUtils.invokeAwareMethods(
registrar, this.environment, this.resourceLoader, this.registry);
// 把 registrar 添加到【configClass】的 importBeanDefinitionRegistrars 属性中,后面才会回调 registerBeanDefinitions() 方法进行处理
configClass.addImportBeanDefinitionRegistrar(registrar, currentSourceClass.getMetadata());
}
// 3. 第三种情况:直接导入的类,如【Cat】(第一种情况回调 selectImports() 方法返回的 bean 最终也会进入到这里,如【Dog】)
else {
// Candidate class not an ImportSelector or ImportBeanDefinitionRegistrar ->
// process it as an @Configuration class
// 如果是普通类,则先放到 configurationClasses 属性中(详细见 processConfigurationClass() 方法的最后一步),后面会拿出来解析成 BeanDefinition 然后注册
this.importStack.registerImport(
currentSourceClass.getMetadata(), candidate.getMetadata().getClassName());
// 这里是递归调用,最终会继续调用这个方法
// 所以 ImportSelector 返回的类最终都会走这里,存储在 configurationClasses 属性中
processConfigurationClass(candidate.asConfigClass(configClass));
}
}
}
...
}
}
5. org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader#loadBeanDefinitionsForConfigurationClass
private void loadBeanDefinitionsForConfigurationClass(
ConfigurationClass configClass, TrackedConditionEvaluator trackedConditionEvaluator) {
...
// 如果这个类是被 @Import 导入进来的,【Cat】和【Dog】会进入这个方法
if (configClass.isImported()) {
// 最终调用 registerBeanDefinition() 方法注册到 beanDefinitionMap 属性中
registerBeanDefinitionForImportedConfigurationClass(configClass);
}
// 处理 @Bean 注解的方法,调用这个方法注册到 beanDefinitionMap 属性中
for (BeanMethod beanMethod : configClass.getBeanMethods()) {
loadBeanDefinitionsForBeanMethod(beanMethod);
}
// 处理 @ImportResource 注解导入的 xml 文件
loadBeanDefinitionsFromImportedResources(configClass.getImportedResources());
// configClass.getImportBeanDefinitionRegistrars() 方法获取的是之前存储的【ImportBeanDefinitionRegistrar】集合,如【ExtImportBeanDefinitionRegistrar】
loadBeanDefinitionsFromRegistrars(configClass.getImportBeanDefinitionRegistrars());
}
2.3 postProcessBeanFactory() 方法分析
2.3.1 流程分析
2.3.2 核心代码剖析
1. org.springframework.context.annotation.ConfigurationClassPostProcessor#enhanceConfigurationClasses
public void enhanceConfigurationClasses(ConfigurableListableBeanFactory beanFactory) {
// 定义一个变量存储
Map<String, AbstractBeanDefinition> configBeanDefs = new LinkedHashMap<>();
// 循环所有的 BeanDefinition 类
for (String beanName : beanFactory.getBeanDefinitionNames()) {
BeanDefinition beanDef = beanFactory.getBeanDefinition(beanName);
// 判断是不是 full 属性,所有的 bean 在 postProcessBeanDefinitionRegistry() 方法中已经设置过此属性
// 判断依据就是有没有添加 @Configuration 注解
if (ConfigurationClassUtils.isFullConfigurationClass(beanDef)) {
if (!(beanDef instanceof AbstractBeanDefinition)) {
throw new BeanDefinitionStoreException("Cannot enhance @Configuration bean definition '" +
beanName + "' since it is not stored in an AbstractBeanDefinition subclass");
}
else if (logger.isInfoEnabled() && beanFactory.containsSingleton(beanName)) {
logger.info("Cannot enhance @Configuration bean definition '" + beanName +
"' since its singleton instance has been created too early. The typical cause " +
"is a non-static @Bean method with a BeanDefinitionRegistryPostProcessor " +
"return type: Consider declaring such methods as 'static'.");
}
configBeanDefs.put(beanName, (AbstractBeanDefinition) beanDef);
}
}
// configBeanDefs 只有一个值,即【springConfig】
if (configBeanDefs.isEmpty()) {
// nothing to enhance -> return immediately
return;
}
ConfigurationClassEnhancer enhancer = new ConfigurationClassEnhancer();
for (Map.Entry<String, AbstractBeanDefinition> entry : configBeanDefs.entrySet()) {
AbstractBeanDefinition beanDef = entry.getValue();
// If a @Configuration class gets proxied, always proxy the target class
beanDef.setAttribute(AutoProxyUtils.PRESERVE_TARGET_CLASS_ATTRIBUTE, Boolean.TRUE);
try {
// Set enhanced subclass of the user-specified bean class
Class<?> configClass = beanDef.resolveBeanClass(this.beanClassLoader);
if (configClass != null) {
// 通过 cglib 增强配置类
Class<?> enhancedClass = enhancer.enhance(configClass, this.beanClassLoader);
if (configClass != enhancedClass) {
if (logger.isTraceEnabled()) {
logger.trace(String.format("Replacing bean definition '%s' existing class '%s' with " +
"enhanced class '%s'", entry.getKey(), configClass.getName(), enhancedClass.getName()));
}
beanDef.setBeanClass(enhancedClass);
}
}
}
catch (Throwable ex) {
throw new IllegalStateException("Cannot load configuration class: " + beanDef.getBeanClassName(), ex);
}
}
}
2. org.springframework.context.annotation.ConfigurationClassEnhancer#newEnhancer
private Enhancer newEnhancer(Class<?> configSuperClass, @Nullable ClassLoader classLoader) {
Enhancer enhancer = new Enhancer();
// 设置父类,cglib 是基于继承
enhancer.setSuperclass(configSuperClass);
// 设置接口,EnhancedConfiguration 继承了 BeanFactoryAware 接口,是为了实现 setBeanFactory() 方法获取 beanFactory
enhancer.setInterfaces(new Class<?>[] {EnhancedConfiguration.class});
enhancer.setUseFactory(false);
enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
// 设置 cglib 生成类的策略,主要添加一个自定义的属性 $$beanFactory
enhancer.setStrategy(new BeanFactoryAwareGeneratorStrategy(classLoader));
// CALLBACK_FILTER 中包含三个拦截器,如下:
// 1. BeanMethodInterceptor() -> bean 方法拦截器,不需要每一次都创建对象
// 2. BeanFactoryAwareMethodInterceptor() -> 给 $$beanFactory 属性赋值
// 3. NoOp.INSTANCE -> 无作用
enhancer.setCallbackFilter(CALLBACK_FILTER);
enhancer.setCallbackTypes(CALLBACK_FILTER.getCallbackTypes());
return enhancer;
}
2.3.3 BeanMethodInterceptor 类分析
private static class BeanMethodInterceptor implements MethodInterceptor, ConditionalCallback {
/**
* Enhance a {@link Bean @Bean} method to check the supplied BeanFactory for the
* existence of this bean object.
* @throws Throwable as a catch-all for any exception that may be thrown when invoking the
* super implementation of the proxied method i.e., the actual {@code @Bean} method
*/
@Override
@Nullable
public Object intercept(Object enhancedConfigInstance, Method beanMethod, Object[] beanMethodArgs,
MethodProxy cglibMethodProxy) throws Throwable {
// 获取 beanFactory
ConfigurableBeanFactory beanFactory = getBeanFactory(enhancedConfigInstance);
// 从 @Bean 注解的方法中获取要创建的 beanName
String beanName = BeanAnnotationHelper.determineBeanNameFor(beanMethod);
// Determine whether this bean is a scoped-proxy
if (BeanAnnotationHelper.isScopedProxy(beanMethod)) {
String scopedBeanName = ScopedProxyCreator.getTargetBeanName(beanName);
if (beanFactory.isCurrentlyInCreation(scopedBeanName)) {
beanName = scopedBeanName;
}
}
// To handle the case of an inter-bean method reference, we must explicitly check the
// container for already cached instances.
// First, check to see if the requested bean is a FactoryBean. If so, create a subclass
// proxy that intercepts calls to getObject() and returns any cached bean instance.
// This ensures that the semantics of calling a FactoryBean from within @Bean methods
// is the same as that of referring to a FactoryBean within XML. See SPR-6602.
// 这里会处理 factoryBean 的情况,判断依据就是 beanName 是不是以 & 开头
if (factoryContainsBean(beanFactory, BeanFactory.FACTORY_BEAN_PREFIX + beanName) &&
factoryContainsBean(beanFactory, beanName)) {
Object factoryBean = beanFactory.getBean(BeanFactory.FACTORY_BEAN_PREFIX + beanName);
if (factoryBean instanceof ScopedProxyFactoryBean) {
// Scoped proxy factory beans are a special case and should not be further proxied
}
else {
// It is a candidate FactoryBean - go ahead with enhancement
// 这里会继续对 factoryBean 做增强
return enhanceFactoryBean(factoryBean, beanMethod.getReturnType(), beanFactory, beanName);
}
}
// 调用执行的方法和调用方法是不是一致
if (isCurrentlyInvokedFactoryMethod(beanMethod)) {
// The factory is calling the bean method in order to instantiate and register the bean
// (i.e. via a getBean() call) -> invoke the super implementation of the method to actually
// create the bean instance.
if (logger.isInfoEnabled() &&
BeanFactoryPostProcessor.class.isAssignableFrom(beanMethod.getReturnType())) {
logger.info(String.format("@Bean method %s.%s is non-static and returns an object " +
"assignable to Spring's BeanFactoryPostProcessor interface. This will " +
"result in a failure to process annotations such as @Autowired, " +
"@Resource and @PostConstruct within the method's declaring " +
"@Configuration class. Add the 'static' modifier to this method to avoid " +
"these container lifecycle issues; see @Bean javadoc for complete details.",
beanMethod.getDeclaringClass().getSimpleName(), beanMethod.getName()));
}
// 如果是当前方法方法调用,就直接调用父类的创建方法,这里会有这两种情况【person1()】、【person2()】进入这个方法
// @Bean public Person1 person1() {return new Person1();}
// @Bean public Person2 person2() {this.person1();return new Person2();}
return cglibMethodProxy.invokeSuper(enhancedConfigInstance, beanMethodArgs);
}
// 如果不是,调用这个方法创建,只有【this.person1()】方法会进入
// @Bean public Person2 person2() {this.person1();return new Person2();}
return resolveBeanReference(beanMethod, beanMethodArgs, beanFactory, beanName);
}
private Object resolveBeanReference(Method beanMethod, Object[] beanMethodArgs,
ConfigurableBeanFactory beanFactory, String beanName) {
// The user (i.e. not the factory) is requesting this bean through a call to
// the bean method, direct or indirect. The bean may have already been marked
// as 'in creation' in certain autowiring scenarios; if so, temporarily set
// the in-creation status to false in order to avoid an exception.
boolean alreadyInCreation = beanFactory.isCurrentlyInCreation(beanName);
try {
...
// 从 beanFactory 中获取 bean 实例,即【person1】
Object beanInstance = (useArgs ? beanFactory.getBean(beanName, beanMethodArgs) :
beanFactory.getBean(beanName));
...
return beanInstance;
}
finally {
if (alreadyInCreation) {
beanFactory.setCurrentlyInCreation(beanName, true);
}
}
}
@Override
public boolean isMatch(Method candidateMethod) {
// 判断条件是方法上有 @Bean 注解,且不是 setBeanFactory() 方法
return (candidateMethod.getDeclaringClass() != Object.class &&
!BeanFactoryAwareMethodInterceptor.isSetBeanFactory(candidateMethod) &&
BeanAnnotationHelper.isBeanAnnotated(candidateMethod));
}
/**
* Check whether the given method corresponds to the container's currently invoked
* factory method. Compares method name and parameter types only in order to work
* around a potential problem with covariant return types (currently only known
* to happen on Groovy classes).
*/
private boolean isCurrentlyInvokedFactoryMethod(Method method) {
// 调用执行的方法和调用方法是不是一致
// 比如说我在 a() 方法里调用 b(),那么 currentlyInvoked.getName() 就是 a,method.getName() 就是 b
// 如果我是直接调用 b(),那么这两个就都是 b
Method currentlyInvoked = SimpleInstantiationStrategy.getCurrentlyInvokedFactoryMethod();
return (currentlyInvoked != null && method.getName().equals(currentlyInvoked.getName()) &&
Arrays.equals(method.getParameterTypes(), currentlyInvoked.getParameterTypes()));
}
}
2.3.4 代理类分析
public class SpringConfig$$EnhancerBySpringCGLIB$$7e8e54e2
extends SpringConfig
implements ConfigurationClassEnhancer.EnhancedConfiguration {
...
// 即 BeanMethodInterceptor
private MethodInterceptor CGLIB$CALLBACK_0;
// 即 BeanFactoryAwareMethodInterceptor
...
// Spring 在用 cglib 做增强时添加的 $$beanFactory 属性
public BeanFactory $$beanFactory;
...
public final void setBeanFactory(BeanFactory beanFactory) throws BeansException {
MethodInterceptor methodInterceptor = this.CGLIB$CALLBACK_1;
if (methodInterceptor == null) {
SpringConfig$$EnhancerBySpringCGLIB$$7e8e54e2.CGLIB$BIND_CALLBACKS((Object)this);
methodInterceptor = this.CGLIB$CALLBACK_1;
}
if (methodInterceptor != null) {
// 设置 BeanFactory 属性
Object object = methodInterceptor.intercept((Object)this, CGLIB$setBeanFactory$6$Method, new Object[]{beanFactory}, CGLIB$setBeanFactory$6$Proxy);
return;
}
super.setBeanFactory(beanFactory);
}
public final Person1 person1() {
MethodInterceptor methodInterceptor = this.CGLIB$CALLBACK_0;
if (methodInterceptor == null) {
SpringConfig$$EnhancerBySpringCGLIB$$7e8e54e2.CGLIB$BIND_CALLBACKS((Object)this);
methodInterceptor = this.CGLIB$CALLBACK_0;
}
if (methodInterceptor != null) {
// 调用 intercept 方法做拦截
return (Person1)methodInterceptor.intercept((Object)this, CGLIB$person1$0$Method, CGLIB$emptyArgs, CGLIB$person1$0$Proxy);
}
return super.person1();
}
public final Person2 person2() {
MethodInterceptor methodInterceptor = this.CGLIB$CALLBACK_0;
if (methodInterceptor == null) {
SpringConfig$$EnhancerBySpringCGLIB$$7e8e54e2.CGLIB$BIND_CALLBACKS((Object)this);
methodInterceptor = this.CGLIB$CALLBACK_0;
}
if (methodInterceptor != null) {
// 调用 intercept 方法做拦截
return (Person2)methodInterceptor.intercept((Object)this, CGLIB$person2$1$Method, CGLIB$emptyArgs, CGLIB$person2$1$Proxy);
}
return super.person2();
}
}