docs/Spring全家桶/Spring源码分析/Spring重要机制探秘/ConfigurationClassPostProcessor(二):处理@Bean注解.md
ConfigurationClassPostProcessor ĵڶƪҪǷ spring @Bean עĴ̡
@Bean עģнģǼ spring @Bean עĴ̡
Ϊ˵⣬ֱϴ룺
Bean:
public class BeanObj1 {
public BeanObj1() {
System.out.println("beanObj1Ĺ췽");
}
@Override
public String toString() {
return "BeanObj1{}";
}
}
public class BeanObj2 {
public BeanObj2() {
System.out.println("beanObj2Ĺ췽");
}
@Override
public String toString() {
return "BeanObj2{}";
}
}
ע⣺û Component``@Service ע⡣
һ࣬ͨ @Bean עķ bean
@Component
public class BeanConfigs {
@Bean
public BeanObj1 beanObj1() {
return new BeanObj1();
}
@Bean
public BeanObj2 beanObj2() {
// beanObj1()
beanObj1();
return new BeanObj2();
}
}
ࣺ
@ComponentScan
public class Demo02Main {
public static void main(String[] args) {
ApplicationContext context
= new AnnotationConfigApplicationContext(Demo02Main.class);
Object obj1 = context.getBean("beanObj1");
Object obj2 = context.getBean("beanObj2");
System.out.println("obj1:" + obj1);
System.out.println("obj2:" + obj2);
System.out.println(context.getBean("beanConfigs"));
}
}
룬¼Ҫ˵
BeanConfigs ʹõע @Componentһƪķ@Component Ҳ࣬ͬ @Configuration ע⣻Demo02Main У AnnotationConfigApplicationContext Ϊ Demo02Mainһע @ComponentScanעûָɨ·һƪķָɨ·spring ĬɨڰBeanConfigs עᵽУ new AnnotationConfigApplicationContext(BeanConfigs.class) һƪķ֪spring Ƚ Demo02Main ࣬ϵ @Component ע⣬Ӷɨ赽 BeanConfigs ࣬Ȼ BeanConfigsڲ @Bean ǽҲͨԵķʽ֤ϴ룬£
beanObj1Ĺ췽
beanObj1Ĺ췽
beanObj2Ĺ췽
obj1:BeanObj1{}
obj2:BeanObj2{}
org.springframework.learn.explore.demo05.BeanConfigs@2b71e916
demo з
ע ConfigurationClassPostProcessor ĵڶƪһƪͬĴ룬ֻһʴٽϸ
ֱӽ ConfigurationClassPostProcessor#processConfigBeanDefinitions £
AnnotationConfigApplicationContext#AnnotationConfigApplicationContext(Class)
|-AbstractApplicationContext#refresh
|-AbstractApplicationContext#invokeBeanFactoryPostProcessors
|-PostProcessorRegistrationDelegate
#invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory, List)
|-PostProcessorRegistrationDelegate#invokeBeanDefinitionRegistryPostProcessors
|-ConfigurationClassPostProcessor#postProcessBeanDefinitionRegistry
|-ConfigurationClassPostProcessor#processConfigBeanDefinitions
ʱ candidates ֻһ Ԫأ
demo02MainConfigurationClassParser#doProcessConfigurationClassһǽ @ComponentScan עḶ́һƪϸֻջ
AnnotationConfigApplicationContext#AnnotationConfigApplicationContext(Class)
|-AbstractApplicationContext#refresh
|-AbstractApplicationContext#invokeBeanFactoryPostProcessors
|-PostProcessorRegistrationDelegate
#invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory, List)
|-PostProcessorRegistrationDelegate#invokeBeanDefinitionRegistryPostProcessors
|-ConfigurationClassPostProcessor#postProcessBeanDefinitionRegistry
|-ConfigurationClassPostProcessor#processConfigBeanDefinitions
|-ConfigurationClassParser#parse(Set<BeanDefinitionHolder>)
|-ConfigurationClassParser#parse(AnnotationMetadata, String)
|-ConfigurationClassParser#processConfigurationClass
|-ConfigurationClassParser#doProcessConfigurationClass
Demo02Main @ComponentScan ֮Կ beanConfigs Ѿɨ赽ˣ
beanConfigs ࣬˻н
ջǻص ConfigurationClassParser#doProcessConfigurationClassеĵ£
AnnotationConfigApplicationContext#AnnotationConfigApplicationContext(Class)
|-AbstractApplicationContext#refresh
|-AbstractApplicationContext#invokeBeanFactoryPostProcessors
|-PostProcessorRegistrationDelegate
#invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory, List)
|-PostProcessorRegistrationDelegate#invokeBeanDefinitionRegistryPostProcessors
|-ConfigurationClassPostProcessor#postProcessBeanDefinitionRegistry
|-ConfigurationClassPostProcessor#processConfigBeanDefinitions
|-ConfigurationClassParser#parse(Set<BeanDefinitionHolder>)
|-ConfigurationClassParser#parse(AnnotationMetadata, String)
|-ConfigurationClassParser#processConfigurationClass
|-ConfigurationClassParser#doProcessConfigurationClass
|-ConfigurationClassParser#parse(String, String)
|-ConfigurationClassParser#processConfigurationClass
|-ConfigurationClassParser#doProcessConfigurationClass
ʱ ConfigurationClassParser#doProcessConfigurationClassǾͲ demo02Main beanConfigs ˡ
beanConfigsConfigurationClassParser#doProcessConfigurationClassConfigurationClassParser#doProcessConfigurationClass @Bean עĴ£
/**
* ķ
*/
protected final SourceClass doProcessConfigurationClass(ConfigurationClass configClass,
SourceClass sourceClass) throws IOException {
// 1\. @Component ע⣬ݹ鴦ڲ࣬IJע
...
// 2\. @PropertySourceע⣬IJע
...
// 3\. @ComponentScan/@ComponentScans ע⣬IJע
...
// 4\. @Importע⣬IJע
...
// 5\. @ImportResourceע⣬IJע
...
// 6\. @Beanע
// Ľ
Set<MethodMetadata> beanMethods = retrieveBeanMethodMetadata(sourceClass);
for (MethodMetadata methodMetadata : beanMethods) {
// ӵ configClass Уٴ
configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));
}
// 7\. ĸ࣬ processConfigurationClass(...) һѭʱ
...
return null;
}
ȡ @Bean ķõ retrieveBeanMethodMetadata(...)Ǹȥ
private Set<MethodMetadata> retrieveBeanMethodMetadata(SourceClass sourceClass) {
AnnotationMetadata original = sourceClass.getMetadata();
// ȡ @Bean עķ
Set<MethodMetadata> beanMethods = original.getAnnotatedMethods(Bean.class.getName());
...
return beanMethods;
}
ٸȥյõ StandardAnnotationMetadata#getAnnotatedMethods:
public Set<MethodMetadata> getAnnotatedMethods(String annotationName) {
Set<MethodMetadata> annotatedMethods = null;
if (AnnotationUtils.isCandidateClass(getIntrospectedClass(), annotationName)) {
try {
// 1\. ͨĻȡеķ
Method[] methods = ReflectionUtils.getDeclaredMethods(getIntrospectedClass());
for (Method method : methods) {
// 2\. жǷ @Bean ע
if (isAnnotatedMethod(method, annotationName)) {
if (annotatedMethods == null) {
annotatedMethods = new LinkedHashSet<>(4);
}
annotatedMethods.add(new StandardMethodMetadata(
method, this.nestedAnnotationsAsMap));
}
}
}
catch (Throwable ex) {
throw new IllegalStateException();
}
}
return annotatedMethods != null ? annotatedMethods : Collections.emptySet();
}
ܺ⣬ؼ
@Bean ע⣻beanConfigs еڻȡˣ ConfigurationClass beanMethods ԣ
@Bean ǵķص BeanDefinitionMapȡ beanMethod ʱֻ ConfigurationClass beanMethods Уûмص beanFactory BeanDefinitionMap УС̽Ǻʱ뵽 BeanDefinitionMap С
ǵ ConfigurationClassPostProcessor#processConfigBeanDefinition ôһд룺
public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
...
// ν
// @Import ࡢд@Beanķ@ImportResource ԴתBeanDefinition
this.reader.loadBeanDefinitions(configClasses);
...
}
Ǽ BeanDefinition ĵط @Import ࡢд @Bean ķ@ImportResource Դת BeanDefinitionصע @Bean Ĵ£
ConfigurationClassBeanDefinitionReader
public void loadBeanDefinitions(Set<ConfigurationClass> configurationModel) {
TrackedConditionEvaluator trackedConditionEvaluator = new TrackedConditionEvaluator();
// configurationModel
for (ConfigurationClass configClass : configurationModel) {
loadBeanDefinitionsForConfigurationClass(configClass, trackedConditionEvaluator);
}
}
/**
* ظ ConfigurationClass BeanDefinition
* 1\. @Import
* 2\. е @Bean
* 3\. @ImportResource Դ
* 4\. @Import ImportBeanDefinitionRegistrar
*/
private void loadBeanDefinitionsForConfigurationClass(
ConfigurationClass configClass, TrackedConditionEvaluator trackedConditionEvaluator) {
if (trackedConditionEvaluator.shouldSkip(configClass)) {
...
}
// @Import
if (configClass.isImported()) {
registerBeanDefinitionForImportedConfigurationClass(configClass);
}
// @Bean
for (BeanMethod beanMethod : configClass.getBeanMethods()) {
loadBeanDefinitionsForBeanMethod(beanMethod);
}
// @ImportResource Դ
loadBeanDefinitionsFromImportedResources(configClass.getImportedResources());
// @Import ImportBeanDefinitionRegistrar
loadBeanDefinitionsFromRegistrars(configClass.getImportBeanDefinitionRegistrars());
}
/**
* @Bean
* 1\. BeanDefinitionbeanMethod ʹõ ConfigurationClassBeanDefinition
* 2\. @Bean ĸԣõ BeanDefinition
* 3\. BeanDefinition עᵽ beanFactory
*/
private void loadBeanDefinitionsForBeanMethod(BeanMethod beanMethod) {
ConfigurationClass configClass = beanMethod.getConfigurationClass();
MethodMetadata metadata = beanMethod.getMetadata();
String methodName = metadata.getMethodName();
...
// 1\. beanMethodʹõConfigurationClassBeanDefinition
ConfigurationClassBeanDefinition beanDef =
new ConfigurationClassBeanDefinition(configClass, metadata);
beanDef.setResource(configClass.getResource());
beanDef.setSource(this.sourceExtractor.extractSource(metadata, configClass.getResource()));
// 2\. @Bean ĸ
if (metadata.isStatic()) {
// ̬ @Bean
if (configClass.getMetadata() instanceof StandardAnnotationMetadata) {
beanDef.setBeanClass(
((StandardAnnotationMetadata) configClass.getMetadata()).getIntrospectedClass());
}
else {
beanDef.setBeanClassName(configClass.getMetadata().getClassName());
}
beanDef.setUniqueFactoryMethodName(methodName);
}
else {
// ͨ @Bean
beanDef.setFactoryBeanName(configClass.getBeanName());
beanDef.setUniqueFactoryMethodName(methodName);
}
if (metadata instanceof StandardMethodMetadata) {
beanDef.setResolvedFactoryMethod(
((StandardMethodMetadata) metadata).getIntrospectedMethod());
}
beanDef.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_CONSTRUCTOR);
beanDef.setAttribute(
org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor.
SKIP_REQUIRED_CHECK_ATTRIBUTE, Boolean.TRUE);
AnnotationConfigUtils.processCommonDefinitionAnnotations(beanDef, metadata);
Autowire autowire = bean.getEnum("autowire");
if (autowire.isAutowire()) {
beanDef.setAutowireMode(autowire.value());
}
boolean autowireCandidate = bean.getBoolean("autowireCandidate");
if (!autowireCandidate) {
beanDef.setAutowireCandidate(false);
}
String initMethodName = bean.getString("initMethod");
if (StringUtils.hasText(initMethodName)) {
beanDef.setInitMethodName(initMethodName);
}
String destroyMethodName = bean.getString("destroyMethod");
beanDef.setDestroyMethodName(destroyMethodName);
...
// 3\. BeanDefinitionעᵽbeanFactory
this.registry.registerBeanDefinition(beanName, beanDefToRegister);
}
ConfigurationClassBeanDefinitionReader#loadBeanDefinitions ֵմ ConfigurationClassBeanDefinitionReader#loadBeanDefinitionsForBeanMethodⲿ£
configClass ϣÿ configClass Definitions شconfigClass Definitions شʱһ @Import/@Bean/@ImportResource ע⣬Сǽע @Bean Ĵ@Bean ʱȴ BeanDefinition(@Bean Ӧ BeanDefinition ConfigurationClassBeanDefinition)Ȼ @Bean ԣõ BeanDefinition Уǰ BeanDefinition עᵽ beanFactory .ˣִ ConfigurationClassBeanDefinitionReader#loadBeanDefinitions BeanDefinition ͼص beanFactory ˣӦ BeanDefinition ConfigurationClassBeanDefinition.
@Bean ʵʵĴͬͨ @Component һ£ͬͨ @Component õǹ췽 @Bean ʹõ factoryMethod£
AbstractAutowireCapableBeanFactory#createBeanInstance
/**
* ʵĴʽ
* 1\. ʹ instanceSupplierSupplierjava8ṩ࣬Դһlambdaʽ
* 2\. ʹù @Bean עӦķ
* 3\. ʹõǹ췽ע룬췽 @Autowired ע
* 4\. 췽ע룬ι죬Ҳвι
*
*/
protected BeanWrapper createBeanInstance(String beanName,
RootBeanDefinition mbd, @Nullable Object[] args) {
// ȷѾ˴ class
Class<?> beanClass = resolveBeanClass(mbd, beanName);
...
// ǷbeanSupplierSupplierjava8ṩ࣬Դһlambdaʽ
// AbstractBeanDefinition#setInstanceSupplier ָ
Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
if (instanceSupplier != null) {
return obtainFromSupplier(instanceSupplier, beanName);
}
if (mbd.getFactoryMethodName() != null) {
// ùʵ
return instantiateUsingFactoryMethod(beanName, mbd, args);
}
// Ƿһ
boolean resolved = false;
// Ƿù캯ע
boolean autowireNecessary = false;
...
if (resolved) {
if (autowireNecessary) {
return autowireConstructor(beanName, mbd, null, null);
}
else {
// ι캯
return instantiateBean(beanName, mbd);
}
}
// Candidate constructors for autowiring?
// жǷвι캯
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(
beanClass, beanName);
if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
return autowireConstructor(beanName, mbd, ctors, args);
}
ctors = mbd.getPreferredConstructors();
if (ctors != null) {
// 캯ע
return autowireConstructor(beanName, mbd, ctors, null);
}
// ι캯
return instantiateBean(beanName, mbd);
}
Ӵspring ʵķʽ 4 ֣
instanceSupplier``Supplier java8 ṩ࣬Դһ lambda ʽ@Bean עӦķ@Autowired עҪע @Bean ʵʽҲǹʵʽǽȥ£
public BeanWrapper instantiateUsingFactoryMethod(String beanName,
RootBeanDefinition mbd, @Nullable Object[] explicitArgs) {
BeanWrapperImpl bw = new BeanWrapperImpl();
this.beanFactory.initBeanWrapper(bw);
Object factoryBean;
Class<?> factoryClass;
boolean isStatic;
String factoryBeanName = mbd.getFactoryBeanName();
if (factoryBeanName != null) {
factoryBean = this.beanFactory.getBean(factoryBeanName);
factoryClass = factoryBean.getClass();
isStatic = false;
}
...
Method factoryMethodToUse = null;
ArgumentsHolder argsHolderToUse = null;
Object[] argsToUse = null;
// factoryMethod IJ
if (explicitArgs != null) {
argsToUse = explicitArgs;
}
else {
...
}
if (factoryMethodToUse == null || argsToUse == null) {
factoryClass = ClassUtils.getUserClass(factoryClass);
List<Method> candidates = null;
if (mbd.isFactoryMethodUnique) {
if (factoryMethodToUse == null) {
factoryMethodToUse = mbd.getResolvedFactoryMethod();
}
if (factoryMethodToUse != null) {
candidates = Collections.singletonList(factoryMethodToUse);
}
}
// ʡ˺ö
...
}
bw.setBeanInstance(instantiate(beanName, mbd,
factoryBean, factoryMethodToUse, argsToUse));
return bw;
}
ϷǾĴ룬ԭȽ϶ִ࣬ڴ argsToUse factoryMethodToUse ϸڷdz࣬ͲչˣҪע¼
factoryBean @Bean ʵ beanConfig;factoryMethodToUse: ʵõķҲDZ @Bean עķ BeanConfigs#beanObj1;argsToUse @Bean עķҪõIJ BeanConfigs#beanObj1 ûָ null;ʵıʵʽҲ뵽ˣʵˣǵ÷ʵˣ
ConstructorResolver#instantiate(...)
private Object instantiate(String beanName, RootBeanDefinition mbd,
@Nullable Object factoryBean, Method factoryMethod, Object[] args) {
try {
return this.beanFactory.getInstantiationStrategy().instantiate(
mbd, beanName, this.beanFactory, factoryBean, factoryMethod, args);
}
catch (Throwable ex) {
...
}
}
SimpleInstantiationStrategy#instantiate(...)
@Override
public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner,
@Nullable Object factoryBean, final Method factoryMethod, Object... args) {
try {
...
try {
currentlyInvokedFactoryMethod.set(factoryMethod);
// ൱ڵ beanConfigs.beanObj1()
Object result = factoryMethod.invoke(factoryBean, args);
if (result == null) {
result = new NullBean();
}
return result;
}
finally {
...
}
}
catch (...) {
...
}
}
SimpleInstantiationStrategy#instantiate(...) нзʵˣ
ʵɺע롢ʼȶͨ spring bean һ£Ͳٷˡ
@Configuration @Bean ʹ@Component @Bean ʹʱĴ
@Component
public class BeanConfigs {
@Bean
public Xxx xxx() {
...
}
}
ʵϣʹõ @Configuration @Bean ϣ
@Configuration
public class BeanConfigs {
@Bean
public Xxx xxx() {
...
}
}
ǰʹõ @Component кβأǾ¡
demo
//@Component
@Configuration
public class BeanConfigs {
@Bean
public BeanObj1 beanObj1() {
return new BeanObj1();
}
@Bean
public BeanObj2 beanObj2() {
// beanObj1()
beanObj1();
return new BeanObj2();
}
}
demo ֻǽ @Component 滻Ϊ @Configurationִ££
beanObj1Ĺ췽
beanObj2Ĺ췽
obj1:BeanObj1{}
obj2:BeanObj2{}
org.springframework.learn.explore.demo02.BeanConfigs$$EnhancerBySpringCGLIB$$dca1c55b@75c072cb
ǽ֮ǰִҲ
Ƚϣͬ
beanObj1 Ĺ췽һΣbeanConfigs Ӧ BeanConfigs$$EnhancerBySpringCGLIB$$dca1c55b@75c072cb˵һʹ cglibʵϣͬ㶼ԹΪһԭspring beanConfigs ˴ BeanConfigs#beanObj1 ʵʵõǴ **spring Ա @Configuration ǵ cglib **
ôôеأǼ̽
ConfigurationClassPostProcessor#enhanceConfigurationClassesһƪĿƪǾᵽ ConfigurationClassPostProcessor ִʱõprocessConfigBeanDefinitions(...) enhanceConfigurationClasses(...)``processConfigBeanDefinitions(...) spring @Import``@Configuration עĽǰѾˣ enhanceConfigurationClasses(...) DZ @Configuration ǵĹؼڣ
enhanceConfigurationClasses(...) £
ConfigurationClassPostProcessor#enhanceConfigurationClasses
public void enhanceConfigurationClasses(ConfigurableListableBeanFactory beanFactory) {
Map<String, AbstractBeanDefinition> configBeanDefs = new LinkedHashMap<>();
for (String beanName : beanFactory.getBeanDefinitionNames()) {
BeanDefinition beanDef = beanFactory.getBeanDefinition(beanName);
Object configClassAttr = beanDef.getAttribute(
ConfigurationClassUtils.CONFIGURATION_CLASS_ATTRIBUTE);
...
// 1\. жǷΪһȫ
if (ConfigurationClassUtils.CONFIGURATION_CLASS_FULL.equals(configClassAttr)) {
...
configBeanDefs.put(beanName, (AbstractBeanDefinition) beanDef);
}
}
// ȫࣺ
ConfigurationClassEnhancer enhancer = new ConfigurationClassEnhancer();
for (Map.Entry<String, AbstractBeanDefinition> entry : configBeanDefs.entrySet()) {
AbstractBeanDefinition beanDef = entry.getValue();
beanDef.setAttribute(AutoProxyUtils.PRESERVE_TARGET_CLASS_ATTRIBUTE, Boolean.TRUE);
// BeanClass
Class<?> configClass = beanDef.getBeanClass();
// 2\. enhancedClass
Class<?> enhancedClass = enhancer.enhance(configClass, this.beanClassLoader);
if (configClass != enhancedClass) {
// 3\. BeanClassֵΪenhancedClass
beanDef.setBeanClass(enhancedClass);
}
}
}
Ƚϼ£
@Configuration ע proxyBeanMethods != false Ϊ Full ࣬ǸǰıжϷΪȫ࣬ԣʱ beanConfigs һȫࣻconfigClass ɶӦ enhancedClassenhancedClass õ beanDefinition beanClass Сִ˷beanConfigs Ӧ beanDefinition beanClass Ǵˣ
洴 beanConfigs ʵˡ
ɴִеأ spring ִ beanConfigs.beanObj1() أ˵Ҫ̸ cglib ķִˡֱɣ enhancer.enhance(configClass, this.beanClassLoader)
public Class<?> enhance(Class<?> configClass, @Nullable ClassLoader classLoader) {
if (EnhancedConfiguration.class.isAssignableFrom(configClass)) {
return configClass;
}
// newEnhancer(...) ǹؼ
Class<?> enhancedClass = createClass(newEnhancer(configClass, classLoader));
return enhancedClass;
}
룺
private static final Callback[] CALLBACKS = new Callback[] {
// ֤ @Bean ĵ
new BeanMethodInterceptor(),
new BeanFactoryAwareMethodInterceptor(),
NoOp.INSTANCE
};
// CallbackFilterĶΪCallback
private static final ConditionalCallbackFilter CALLBACK_FILTER
= new ConditionalCallbackFilter(CALLBACKS);
// cglibǿ
private Enhancer newEnhancer(Class<?> configSuperClass, @Nullable ClassLoader classLoader) {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(configSuperClass);
enhancer.setInterfaces(new Class<?>[] {EnhancedConfiguration.class});
enhancer.setUseFactory(false);
enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
enhancer.setStrategy(new BeanFactoryAwareGeneratorStrategy(classLoader));
// callbackFilter
enhancer.setCallbackFilter(CALLBACK_FILTER);
enhancer.setCallbackTypes(CALLBACK_FILTER.getCallbackTypes());
return enhancer;
}
cglib ݣ spring aop ֮ cglib һϸˣⲻٷֱ˵ۣcglib ִдʱִе Enhancer callbackFilter Ե MethodInterceptor#intercept CALLBACKS е BeanMethodInterceptorǾݣ
ConfigurationClassEnhancer.BeanMethodInterceptor
private static class BeanMethodInterceptor implements MethodInterceptor, ConditionalCallback {
@Override
@Nullable
public Object intercept(Object enhancedConfigInstance, Method beanMethod, Object[] beanMethodArgs,
MethodProxy cglibMethodProxy) throws Throwable {
ConfigurableBeanFactory beanFactory = getBeanFactory(enhancedConfigInstance);
String beanName = BeanAnnotationHelper.determineBeanNameFor(beanMethod);
...
// ǵõǰ factoryMethod ֱӵøķ
if (isCurrentlyInvokedFactoryMethod(beanMethod)) {
// øķҲĿ귽
return cglibMethodProxy.invokeSuper(enhancedConfigInstance, beanMethodArgs);
}
// ֱӻȡ beanFactoryеĶ
return resolveBeanReference(beanMethod, beanMethodArgs, beanFactory, beanName);
}
private Object resolveBeanReference(Method beanMethod, Object[] beanMethodArgs,
ConfigurableBeanFactory beanFactory, String beanName) {
try {
...
// õĵ beanFactory.getBean(...) ѾdzϤ
Object beanInstance = (useArgs ? beanFactory.getBean(beanName, beanMethodArgs) :
beanFactory.getBean(beanName));
...
return beanInstance;
}
finally {
...
}
}
/**
* жִܷеǰ MethodInterceptor
*/
@Override
public boolean isMatch(Method candidateMethod) {
return (candidateMethod.getDeclaringClass() != Object.class &&
!BeanFactoryAwareMethodInterceptor.isSetBeanFactory(candidateMethod) &&
BeanAnnotationHelper.isBeanAnnotated(candidateMethod));
}
}
BeanMethodInterceptor ʵ MethodInterceptor ConditionalCallback``ConditionalCallback#isMatch жϵǰ MethodInterceptor ִܷУMethodInterceptor#intercept ִеķݣִΪ
factoryMethod ֱӵøķҲ beanConfigs.beanObj1()̻ʵ beanObj1 ʱãfactoryMethod ڱķеã beanFactory.getBean(...) ȡ bean̻ʵ beanObj1 ʱ áϾΪʲô beanObj1 Ĺ췽ֻһΣԼΪʲô beanConfigs Ǵԭˡ
һ䣬@Configuration ṩ proxyBeanMethods() ѡǷĴĬֵ trueã
@Configuration(proxyBeanMethods=false)
public class BeanConfigs {
...
}
BeanConfigs Ͳдˣнͬ @Component עһͲչʾˡ
ʾУõģ
@Bean
public BeanObj2 beanObj2() {
// beanObj1()
beanObj1();
return new BeanObj2();
}
beanObj2() е beanObj1()ڲãbeanObj1() Ҳܱ
شcglib ĵ÷֣
@Override
public Object intercept(Object proxyObj, Method method, Object[] objects,
MethodProxy proxy) throws Throwable {
// 1 ʹĿֱӵĿķ
// return proxy.invoke(target, objects);
// 2 ʹô丸ķ
return proxy.invokeSuper(proxyObj, objects);
}
beanObj2() ĵʹ2Ҳʹô beanObj2()``beanObj2() this Ϊ
beanObj2() ֱӵ beanObj1()൱ʹô beanObj1()Ȼܱˡ
ӡУڲòܱΪ spring ڴ Aop ʱʹõǷ 1 ĵ÷ʽʱ this ΪԭʼȻܱˡ
磬һ BeanObj3:
@Component
public class BeanObj3 {
public BeanObj3() {
System.out.println("beanObj3Ĺ췽");
}
@Override
public String toString() {
return "BeanObj3{}";
}
}
Ȼ BeanConfigs ע룺
@Configuration
public class BeanConfigs {
@Autowired
private BeanObj3 beanObj3;
@Bean
public BeanObj1 beanObj1() {
return new BeanObj1();
}
@Bean
public BeanObj2 beanObj2() {
// beanObj1()
beanObj1();
System.out.println("beanObj3" + this.beanObj3);
return new BeanObj2();
}
}
BeanConfigs Զע beanObj3 ԣȻ beanObj2() ִӡ beanObj3 ԡУ£
Կע beanObj3 ҲܻȡˡиˣbeanObj3 Ŀģ this ǴѲɴõĿ˽ԣ
ȣӵ beanFactory beanDefinitionMap е BeanConfigs$$EnhancerBySpringCGLIB$$Xxx ࣩࣨ BeanConfigsspring ڽעʱҵǰ༰丸еעԽע룬ˣȻӵ spring е BeanConfigs$$EnhancerBySpringCGLIB$$Xxx ࣬ BeanConfigs е beanObj3 һᱻע룬ԭ cglib ĴϵBeanConfigs BeanConfigs$$EnhancerBySpringCGLIB$$Xxx ĸࡣ
BeanConfigs$$EnhancerBySpringCGLIB$$Xxx ̳ beanObj3 ֱӿнɣ
յõ beanConfigs Կһ beanObj3 ԣһֵ
Ҫ ConfigurationClassPostProcessor @Bean עḶ́ܽ£
@Bean ǵķBeanDefinition עᵽ beanFactory УӦ BeanDefinition Ϊ ConfigurationClassBeanDefinition@Bean еõǰ @Bean ʱǰ @Bean ڵȫ࣬ȥ beanFactory вҶӦ bean(ҵĹǣҵأҲٷأ**ص bean spring bean ) cglib ɣǰ @Bean ڵȫ࣬ᰴͨķã bean ʵأص bean û spring bean **ĵķ͵ˣǼ ConfigurationClassPostProcessor ע̡
ԭӣhttps://my.oschina.net/funcy/blog/4492878 ߸ˮƽд֮ӭָԭףҵתϵȨҵתע