Full Code of xuchengsheng/spring-reading for AI

master 9911cbb4df10 cached
774 files
2.3 MB
645.7k tokens
968 symbols
1 requests
Download .txt
Showing preview only (2,576K chars total). Download the full file or copy to clipboard to get everything.
Repository: xuchengsheng/spring-reading
Branch: master
Commit: 9911cbb4df10
Files: 774
Total size: 2.3 MB

Directory structure:
gitextract_1jka44ep/

├── .gitignore
├── LICENSE
├── README.md
├── index.html
├── pom.xml
├── spring-annotation/
│   ├── pom.xml
│   ├── spring-annotation-autowired/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── AutowiredApplication.java
│   │                           ├── config/
│   │                           │   └── MyConfiguration.java
│   │                           ├── controller/
│   │                           │   └── MyController.java
│   │                           └── service/
│   │                               └── MyService.java
│   ├── spring-annotation-bean/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── BeanApplication.java
│   │                           ├── bean/
│   │                           │   └── MyBean.java
│   │                           └── config/
│   │                               └── MyConfiguration.java
│   ├── spring-annotation-componentScan/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── ComponentScanApplication.java
│   │                           ├── config/
│   │                           │   └── MyConfiguration.java
│   │                           ├── repository/
│   │                           │   └── UserRepository.java
│   │                           ├── service/
│   │                           │   ├── AdminService.java
│   │                           │   └── UserService.java
│   │                           └── special/
│   │                               └── SpecialComponent.java
│   ├── spring-annotation-conditional/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── bean/
│   │                           │   ├── ConditionBeanApplication.java
│   │                           │   ├── condition/
│   │                           │   │   └── BeanPropertyCondition.java
│   │                           │   ├── config/
│   │                           │   │   └── MyBeanConfiguration.java
│   │                           │   └── entity/
│   │                           │       ├── User1.java
│   │                           │       └── User2.java
│   │                           ├── configuration/
│   │                           │   ├── ConditionConfigurationApplication.java
│   │                           │   ├── condition/
│   │                           │   │   └── ConfigPropertyCondition.java
│   │                           │   ├── config/
│   │                           │   │   └── MyConfigConfiguration.java
│   │                           │   └── entity/
│   │                           │       ├── User3.java
│   │                           │       └── User4.java
│   │                           └── custom/
│   │                               ├── ConditionCustomApplication.java
│   │                               ├── annotation/
│   │                               │   └── ConditionalOnCustomActive.java
│   │                               ├── condition/
│   │                               │   └── CustomActiveCondition.java
│   │                               ├── config/
│   │                               │   └── MyCustomConfiguration.java
│   │                               └── entity/
│   │                                   ├── User5.java
│   │                                   └── User6.java
│   ├── spring-annotation-configuration/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── ConfigurationApplication.java
│   │                           ├── bean/
│   │                           │   └── MyBean.java
│   │                           └── config/
│   │                               └── MyConfiguration.java
│   ├── spring-annotation-dependsOn/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── DependsOnApplication.java
│   │                           ├── bean/
│   │                           │   ├── BeanA.java
│   │                           │   ├── BeanB.java
│   │                           │   └── BeanC.java
│   │                           └── config/
│   │                               └── MyConfiguration.java
│   ├── spring-annotation-import/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── ImportApplication.java
│   │                           ├── bean/
│   │                           │   ├── MyBean.java
│   │                           │   ├── MyBeanA.java
│   │                           │   ├── MyBeanB.java
│   │                           │   └── MyBeanC.java
│   │                           └── config/
│   │                               ├── MyConfiguration.java
│   │                               ├── MyDeferredImportSelector.java
│   │                               ├── MyImportBeanDefinitionRegistrar.java
│   │                               └── MyImportSelector.java
│   ├── spring-annotation-lazy/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── LazyApplication.java
│   │                           ├── bean/
│   │                           │   └── MyBean.java
│   │                           ├── config/
│   │                           │   └── MyConfiguration.java
│   │                           └── service/
│   │                               └── MyService.java
│   ├── spring-annotation-profile/
│   │   ├── README.md
│   │   └── pom.xml
│   ├── spring-annotation-propertySource/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           ├── java/
│   │           │   └── com/
│   │           │       └── xcs/
│   │           │           └── spring/
│   │           │               ├── PropertySourceApplication.java
│   │           │               └── config/
│   │           │                   └── MyConfiguration.java
│   │           └── resources/
│   │               └── my-application.yml
│   └── spring-annotation-value/
│       ├── README.md
│       ├── pom.xml
│       └── src/
│           └── main/
│               ├── java/
│               │   └── com/
│               │       └── xcs/
│               │           └── spring/
│               │               ├── ValueApplication.java
│               │               ├── config/
│               │               │   └── MyConfiguration.java
│               │               └── service/
│               │                   └── MyService.java
│               └── resources/
│                   └── application.properties
├── spring-aop/
│   ├── pom.xml
│   ├── spring-aop-advice/
│   │   ├── README.md
│   │   └── pom.xml
│   ├── spring-aop-advice-afterReturningAdvice/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── AfterReturningAdviceDemo.java
│   │                           ├── MyAfterReturningAdvice.java
│   │                           └── MyService.java
│   ├── spring-aop-advice-introductionInterceptor/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── IntroductionInterceptorDemo.java
│   │                           ├── MyMonitoringCapable.java
│   │                           ├── MyMonitoringIntroductionAdvice.java
│   │                           └── MyService.java
│   ├── spring-aop-advice-methodBeforeAdvice/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── MethodBeforeAdviceDemo.java
│   │                           ├── MyMethodBeforeAdvice.java
│   │                           └── MyService.java
│   ├── spring-aop-advice-methodInterceptor/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── MethodInterceptorDemo.java
│   │                           ├── MyMethodInterceptor.java
│   │                           └── MyService.java
│   ├── spring-aop-advice-throwsAdvice/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── MyService.java
│   │                           ├── MyThrowsAdvice.java
│   │                           └── ThrowsAdviceDemo.java
│   ├── spring-aop-advised/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── AdvisedDemo.java
│   │                           ├── MyService.java
│   │                           └── MyServiceImpl.java
│   ├── spring-aop-advisor/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── AdvisorDemo.java
│   │                           ├── MyAdvice.java
│   │                           ├── MyCustomAdvisor.java
│   │                           ├── MyCustomAnnotation.java
│   │                           └── MyService.java
│   ├── spring-aop-advisorAdapter/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── AdvisorAdapterDemo.java
│   │                           ├── MyNullReturningAdvice.java
│   │                           ├── MyService.java
│   │                           ├── NullReturningAdvice.java
│   │                           ├── NullReturningAdviceAdapter.java
│   │                           └── NullReturningAdviceInterceptor.java
│   ├── spring-aop-advisorAdapterRegistry/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── AdvisorAdapterRegistryDemo.java
│   │                           └── MyMethodBeforeAdvice.java
│   ├── spring-aop-advisorChainFactory/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── AdvisorChainFactoryDemo.java
│   │                           ├── MyAfterReturningAdvice.java
│   │                           ├── MyMethodBeforeAdvice.java
│   │                           └── MyService.java
│   ├── spring-aop-annotationAwareAspectJAutoProxyCreator/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── AnnotationAwareAspectJAutoProxyCreatorDemo.java
│   │                           ├── AppConfig.java
│   │                           ├── MyAspect.java
│   │                           └── MyService.java
│   ├── spring-aop-aopContext/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── AopContextDemo.java
│   │                           ├── MyAnnotation.java
│   │                           ├── MyMethodBeforeAdvice.java
│   │                           └── MyService.java
│   ├── spring-aop-aopProxy/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── AopProxyDemo.java
│   │                           ├── MyMethodInterceptor.java
│   │                           ├── MyService.java
│   │                           └── MyServiceImpl.java
│   ├── spring-aop-aopProxyFactory/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── AopProxyFactoryDemo.java
│   │                           ├── MyService.java
│   │                           └── MyServiceImpl.java
│   ├── spring-aop-aspectInstanceFactory/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── AspectInstanceFactoryDemo.java
│   │                           └── MyAspect.java
│   ├── spring-aop-aspectJAdvisorFactory/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── AspectJAdvisorFactoryDemo.java
│   │                           ├── MyAspect.java
│   │                           └── MyService.java
│   ├── spring-aop-beanFactoryAdvisorRetrievalHelper/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── AppConfig.java
│   │                           ├── BeanFactoryAdvisorRetrievalHelperDemo.java
│   │                           ├── MyAdvice.java
│   │                           ├── MyAdvisor.java
│   │                           └── MyService.java
│   ├── spring-aop-beanFactoryAspectJAdvisorsBuilder/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── AppConfig.java
│   │                           ├── BeanFactoryAspectJAdvisorsBuilderDemo.java
│   │                           ├── MyAspect.java
│   │                           └── MyService.java
│   ├── spring-aop-cglibProxy/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── CglibProxyDemo.java
│   │                           ├── MyMethodInterceptor.java
│   │                           ├── MyService.java
│   │                           └── MyServiceImpl.java
│   ├── spring-aop-classFilter/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── ClassFilterDemo.java
│   │                           ├── MyClassAnnotation.java
│   │                           ├── MyService.java
│   │                           └── MySubService.java
│   ├── spring-aop-enableAspectJAutoProxy/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── AppConfig.java
│   │                           ├── EnableAspectJAutoProxyDemo.java
│   │                           ├── MyAspect.java
│   │                           └── MyService.java
│   ├── spring-aop-enableLoadTimeWeaving/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           ├── java/
│   │           │   └── com/
│   │           │       └── xcs/
│   │           │           └── spring/
│   │           │               ├── AppConfig.java
│   │           │               ├── EnableLoadTimeWeavingDemo.java
│   │           │               ├── MyLTWAspect.java
│   │           │               └── MyService.java
│   │           └── resources/
│   │               └── META-INF/
│   │                   └── aop.xml
│   ├── spring-aop-exposeInvocationInterceptor/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── AppConfig.java
│   │                           ├── ExposeInvocationInterceptorDemo.java
│   │                           ├── LogUtil.java
│   │                           ├── MyMethodInterceptor.java
│   │                           └── MyService.java
│   ├── spring-aop-jdkProxy/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── JdkProxyDemo.java
│   │                           ├── MyInvocationHandler.java
│   │                           ├── MyService.java
│   │                           └── MyServiceImpl.java
│   ├── spring-aop-metadataAwareAspectInstanceFactory/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── MetadataAwareAspectInstanceFactoryDemo.java
│   │                           └── MyAspect.java
│   ├── spring-aop-methodMatcher/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── MethodMatcherDemo.java
│   │                           ├── MyMethodAnnotation.java
│   │                           └── MyService.java
│   ├── spring-aop-pointcut/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── MyClassAnnotation.java
│   │                           ├── MyCustomAdvice.java
│   │                           ├── MyCustomPointcut.java
│   │                           ├── MyMethodAnnotation.java
│   │                           ├── MyService.java
│   │                           └── PointcutDemo.java
│   ├── spring-aop-proxyFactory/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── MyService.java
│   │                           └── ProxyFactoryDemo.java
│   ├── spring-aop-proxyMethodInvocation/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── MyInvocationHandler.java
│   │                           ├── MyMethodInterceptor.java
│   │                           ├── MyReflectiveMethodInvocation.java
│   │                           ├── MyService.java
│   │                           ├── MyServiceImpl.java
│   │                           └── ProxyMethodInvocationDemo.java
│   ├── spring-aop-targetSource/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── ConnectionPoolTargetSource.java
│   │                           ├── MyConnection.java
│   │                           └── TargetSourceDemo.java
│   └── spring-aop-targetSourceCreator/
│       ├── README.md
│       ├── pom.xml
│       └── src/
│           └── main/
│               └── java/
│                   └── com/
│                       └── xcs/
│                           └── spring/
│                               ├── AppConfig.java
│                               ├── ConnectionPoolTargetSource.java
│                               ├── MyConnection.java
│                               ├── MyTargetSourceCreator.java
│                               ├── SetMyTargetSourceCreator.java
│                               └── TargetSourceCreatorDemo.java
├── spring-aware/
│   ├── pom.xml
│   ├── spring-aware-applicationContextAware/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── ApplicationContextAwareApplication.java
│   │                           └── config/
│   │                               ├── MyApplicationContextAware.java
│   │                               └── MyConfiguration.java
│   ├── spring-aware-applicationEventPublisherAware/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── ApplicationEventPublisherAwareApplication.java
│   │                           ├── config/
│   │                           │   ├── MyApplicationEventPublisherAware.java
│   │                           │   └── MyConfiguration.java
│   │                           └── event/
│   │                               ├── MyEvent.java
│   │                               └── MyEventListener.java
│   ├── spring-aware-applicationStartupAware/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── ApplicationStartupAwareApplication.java
│   │                           └── config/
│   │                               ├── MyApplicationStartupAware.java
│   │                               └── MyConfiguration.java
│   ├── spring-aware-beanClassLoaderAware/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── BeanClassLoaderAwareApplication.java
│   │                           ├── config/
│   │                           │   ├── MyBeanClassLoaderAware.java
│   │                           │   └── MyConfiguration.java
│   │                           └── service/
│   │                               ├── UserService.java
│   │                               └── UserServiceImpl.java
│   ├── spring-aware-beanFactoryAware/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── BeanFactoryAwareApplication.java
│   │                           ├── config/
│   │                           │   └── MyConfiguration.java
│   │                           ├── service/
│   │                           │   └── UserService.java
│   │                           └── validate/
│   │                               ├── ComplexUserValidator.java
│   │                               ├── SimpleUserValidator.java
│   │                               └── UserValidator.java
│   ├── spring-aware-beanNameAware/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── BeanNameAwareApplication.java
│   │                           ├── config/
│   │                           │   └── MyConfiguration.java
│   │                           └── service/
│   │                               ├── MyAliPayService.java
│   │                               ├── MyBasePayService.java
│   │                               └── MyWeChatPayService.java
│   ├── spring-aware-embeddedValueResolverAware/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── EmbeddedValueResolverAwareApplication.java
│   │                           └── config/
│   │                               ├── MyConfiguration.java
│   │                               └── MyEmbeddedValueResolverAware.java
│   ├── spring-aware-environmentAware/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           ├── java/
│   │           │   └── com/
│   │           │       └── xcs/
│   │           │           └── spring/
│   │           │               ├── EnvironmentAwareApplication.java
│   │           │               └── config/
│   │           │                   ├── MyConfiguration.java
│   │           │                   └── MyEnvironmentAware.java
│   │           └── resources/
│   │               └── application.properties
│   ├── spring-aware-importAware/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── ImportAwareApplication.java
│   │                           ├── annotation/
│   │                           │   └── EnableXcs.java
│   │                           └── config/
│   │                               ├── MyConfiguration.java
│   │                               └── MyImportAware.java
│   ├── spring-aware-messageSourceAware/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           ├── java/
│   │           │   └── com/
│   │           │       └── xcs/
│   │           │           └── spring/
│   │           │               ├── MessageSourceAwareApplication.java
│   │           │               └── config/
│   │           │                   ├── MyConfiguration.java
│   │           │                   └── MyMessageSourceAware.java
│   │           └── resources/
│   │               └── i18n/
│   │                   ├── messages_en.properties
│   │                   └── messages_zh_CN.properties
│   └── spring-aware-resourceLoaderAware/
│       ├── README.md
│       ├── pom.xml
│       └── src/
│           └── main/
│               ├── java/
│               │   └── com/
│               │       └── xcs/
│               │           └── spring/
│               │               ├── ResourceLoaderAwareApplication.java
│               │               └── config/
│               │                   ├── MyConfiguration.java
│               │                   └── MyResourceLoaderAware.java
│               └── resources/
│                   └── xcs.txt
├── spring-beans/
│   ├── pom.xml
│   ├── spring-bean-annotatedBeanDefinitionReader/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── AnnotatedBeanDefinitionReaderDemo.java
│   │                           └── bean/
│   │                               └── MyBean.java
│   ├── spring-bean-beanDefinition/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── BeanDefinitionDemo.java
│   │                           └── bean/
│   │                               └── MyBean.java
│   ├── spring-bean-beanDefinitionHolder/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── BeanDefinitionHolderDemo.java
│   │                           └── bean/
│   │                               └── MyBean.java
│   ├── spring-bean-beanDefinitionRegistry/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── BeanDefinitionRegistryDemo.java
│   │                           └── bean/
│   │                               └── MyBean.java
│   ├── spring-bean-classPathBeanDefinitionScanner/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── ClassPathBeanDefinitionScannerDemo.java
│   │                           ├── controller/
│   │                           │   └── MyController.java
│   │                           ├── repository/
│   │                           │   └── MyRepository.java
│   │                           └── service/
│   │                               └── MyService.java
│   ├── spring-bean-groovyBeanDefinitionReader/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           ├── java/
│   │           │   └── com/
│   │           │       └── xcs/
│   │           │           └── spring/
│   │           │               ├── GroovyBeanDefinitionReaderDemo.java
│   │           │               └── service/
│   │           │                   └── MyService.java
│   │           └── resources/
│   │               └── my-beans.groovy
│   ├── spring-bean-propertiesBeanDefinitionReader/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           ├── java/
│   │           │   └── com/
│   │           │       └── xcs/
│   │           │           └── spring/
│   │           │               ├── PropertiesBeanDefinitionReaderDemo.java
│   │           │               └── bean/
│   │           │                   └── MyBean.java
│   │           └── resources/
│   │               └── bean-definitions.properties
│   └── spring-bean-xmlBeanDefinitionReader/
│       ├── README.md
│       ├── pom.xml
│       └── src/
│           └── main/
│               ├── java/
│               │   └── com/
│               │       └── xcs/
│               │           └── spring/
│               │               ├── XmlBeanDefinitionReaderDemo.java
│               │               └── bean/
│               │                   └── MyBean.java
│               └── resources/
│                   └── beans.xml
├── spring-context/
│   ├── pom.xml
│   ├── spring-context-annotationConfigApplicationContext/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── AnnotationConfigApplicationContextDemo.java
│   │                           ├── bean/
│   │                           │   └── MyBean.java
│   │                           ├── controller/
│   │                           │   └── MyController.java
│   │                           ├── repository/
│   │                           │   └── MyRepository.java
│   │                           └── service/
│   │                               └── MyService.java
│   ├── spring-context-classPathXmlApplicationContext/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           ├── java/
│   │           │   └── com/
│   │           │       └── xcs/
│   │           │           └── spring/
│   │           │               ├── ClassPathXmlApplicationContextDemo.java
│   │           │               └── bean/
│   │           │                   └── MyBean.java
│   │           └── resources/
│   │               └── beans.xml
│   └── spring-context-genericApplicationContext/
│       └── pom.xml
├── spring-core/
│   ├── pom.xml
│   ├── spring-core-destroyBean/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── DestroyBeanApplication.java
│   │                           └── bean/
│   │                               └── MyBean.java
│   ├── spring-core-getBean/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── GetBeanApplication.java
│   │                           ├── config/
│   │                           │   └── MyConfiguration.java
│   │                           └── service/
│   │                               ├── MyServiceA.java
│   │                               └── MyServiceB.java
│   ├── spring-core-registerBeanDefinition/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── RegisterBeanDefinitionApplication.java
│   │                           ├── bean/
│   │                           │   └── MyBean.java
│   │                           ├── controller/
│   │                           │   └── MyController.java
│   │                           ├── repository/
│   │                           │   └── MyRepository.java
│   │                           └── service/
│   │                               └── MyService.java
│   └── spring-core-resolveDependency/
│       ├── README.md
│       ├── pom.xml
│       └── src/
│           └── main/
│               ├── java/
│               │   └── com/
│               │       └── xcs/
│               │           └── spring/
│               │               ├── ResolveDependencyApplication.java
│               │               ├── config/
│               │               │   └── MyConfiguration.java
│               │               └── service/
│               │                   ├── MyServiceA.java
│               │                   └── MyServiceB.java
│               └── resources/
│                   └── application.properties
├── spring-dataops/
│   ├── pom.xml
│   ├── spring-dataops-conditionalConverter/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── ConditionalConverterDemo.java
│   │                           └── converter/
│   │                               └── StringToIntegerConditionalConverter.java
│   ├── spring-dataops-conversionService/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           └── ConversionServiceDemo.java
│   ├── spring-dataops-converter/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── ConverterDemo.java
│   │                           └── converter/
│   │                               ├── StringToBooleanConverter.java
│   │                               └── StringToLocalDateConverter.java
│   ├── spring-dataops-converterFactory/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── CharacterToNumberFactoryDemo.java
│   │                           └── converter/
│   │                               └── StringToNumberConverterFactory.java
│   ├── spring-dataops-genericConverter/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── GenericConverterDemo.java
│   │                           ├── annotation/
│   │                           │   └── DateFormat.java
│   │                           ├── bean/
│   │                           │   └── MyBean.java
│   │                           └── convert/
│   │                               └── AnnotatedStringToDateConverter.java
│   ├── spring-dataops-parser/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── ParserDemo.java
│   │                           └── parser/
│   │                               └── CurrencyParser.java
│   ├── spring-dataops-printer/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── PrinterDemo.java
│   │                           └── printer/
│   │                               └── CurrencyPrinter.java
│   ├── spring-dataops-propertyEditor/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── MyCustomDateEditor.java
│   │                           ├── PropertyEditorDemo.java
│   │                           └── bean/
│   │                               └── MyBean.java
│   └── spring-dataops-validator/
│       ├── README.md
│       ├── pom.xml
│       └── src/
│           └── main/
│               └── java/
│                   └── com/
│                       └── xcs/
│                           └── spring/
│                               ├── Person.java
│                               ├── PersonValidator.java
│                               └── ValidatorDemo.java
├── spring-env/
│   ├── pom.xml
│   ├── spring-env-configurableEnvironment/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           └── ConfigurableEnvironmentDemo.java
│   ├── spring-env-configurablePropertyResolver/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           └── ConfigurablePropertyResolverDemo.java
│   ├── spring-env-environment/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           └── EnvironmentDemo.java
│   ├── spring-env-propertyResolver/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           └── SimplePropertyResolverDemo.java
│   ├── spring-env-propertySource/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           ├── java/
│   │           │   └── com/
│   │           │       └── xcs/
│   │           │           └── spring/
│   │           │               └── PropertySourceDemo.java
│   │           └── resources/
│   │               └── application.properties
│   └── spring-env-propertySources/
│       ├── README.md
│       ├── pom.xml
│       └── src/
│           └── main/
│               └── java/
│                   └── com/
│                       └── xcs/
│                           └── spring/
│                               └── PropertySourcesDemo.java
├── spring-factory/
│   ├── pom.xml
│   ├── spring-factory-autowireCapableBeanFactory/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── AutowireCapableBeanFactoryDemo.java
│   │                           ├── config/
│   │                           │   ├── MyBeanPostProcessor.java
│   │                           │   └── MyConfiguration.java
│   │                           ├── repository/
│   │                           │   └── MyRepository.java
│   │                           └── service/
│   │                               └── MyService.java
│   ├── spring-factory-beanFactory/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           ├── java/
│   │           │   └── com/
│   │           │       └── xcs/
│   │           │           └── spring/
│   │           │               ├── BeanFactoryDemo.java
│   │           │               └── bean/
│   │           │                   └── MyBean.java
│   │           └── resources/
│   │               └── beans.xml
│   ├── spring-factory-configurableBeanFactory/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── ConfigurableBeanFactoryDemo.java
│   │                           ├── config/
│   │                           │   └── MyConfiguration.java
│   │                           └── service/
│   │                               ├── MyService.java
│   │                               └── impl/
│   │                                   └── MyServiceImpl.java
│   ├── spring-factory-configurableListableBeanFactory/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── ConfigurableListableBeanFactoryDemo.java
│   │                           ├── config/
│   │                           │   └── MyConfiguration.java
│   │                           ├── controller/
│   │                           │   └── MyController.java
│   │                           └── service/
│   │                               ├── MyService.java
│   │                               └── impl/
│   │                                   └── MyServiceImpl.java
│   ├── spring-factory-hierarchicalBeanFactory/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── HierarchicalBeanFactoryDemo.java
│   │                           └── bean/
│   │                               └── MyBean.java
│   └── spring-factory-listableBeanFactory/
│       ├── README.md
│       ├── pom.xml
│       └── src/
│           └── main/
│               └── java/
│                   └── com/
│                       └── xcs/
│                           └── spring/
│                               ├── ListableBeanFactoryDemo.java
│                               ├── config/
│                               │   └── MyConfiguration.java
│                               └── service/
│                                   └── MyService.java
├── spring-interface/
│   ├── pom.xml
│   ├── spring-interface-beanDefinitionRegistryPostProcessor/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── BeanDefinitionRegistryPostProcessorApplication.java
│   │                           └── config/
│   │                               ├── MyBeanDefinitionRegistryPostProcessor.java
│   │                               ├── MyConfiguration.java
│   │                               └── MySimpleBean.java
│   ├── spring-interface-beanFactoryPostProcessor/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── BeanFactoryPostProcessorApplication.java
│   │                           └── config/
│   │                               ├── MyBeanFactoryPostProcessor.java
│   │                               ├── MyConfiguration.java
│   │                               └── MySimpleBean.java
│   ├── spring-interface-beanPostProcessor/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── BeanPostProcessorApplication.java
│   │                           ├── config/
│   │                           │   ├── MyBeanPostProcessor.java
│   │                           │   └── MyConfiguration.java
│   │                           └── service/
│   │                               ├── MyService.java
│   │                               └── MyServiceImpl.java
│   ├── spring-interface-destructionAwareBeanPostProcessor/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── DestructionAwareBeanPostProcessorApplication.java
│   │                           ├── config/
│   │                           │   ├── MyConfiguration.java
│   │                           │   └── MyDestructionAwareBeanPostProcessor.java
│   │                           └── service/
│   │                               ├── ConnectionService.java
│   │                               └── ConnectionServiceImpl.java
│   ├── spring-interface-disposableBean/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── DisposableBeanApplication.java
│   │                           └── config/
│   │                               ├── MyConfiguration.java
│   │                               └── MyDisposableBean.java
│   ├── spring-interface-initializingBean/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── InitializingBeanApplication.java
│   │                           └── config/
│   │                               ├── MyConfiguration.java
│   │                               └── MyInitializingBean.java
│   ├── spring-interface-instantiationAwareBeanPostProcessor/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── InstantiationAwareBeanPostProcessorApplication.java
│   │                           ├── config/
│   │                           │   ├── MyConfiguration.java
│   │                           │   └── MyInstantiationAwareBeanPostProcessor.java
│   │                           └── service/
│   │                               ├── DataBase.java
│   │                               └── DataBaseImpl.java
│   ├── spring-interface-mergedBeanDefinitionPostProcessor/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── MergedBeanDefinitionPostProcessorApplication.java
│   │                           ├── annotation/
│   │                           │   └── MyValue.java
│   │                           ├── bean/
│   │                           │   └── MyBean.java
│   │                           └── config/
│   │                               ├── MyConfiguration.java
│   │                               └── MyMergedBeanDefinitionPostProcessor.java
│   ├── spring-interface-smartInitializingSingleton/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── SmartInitializingSingletonApplication.java
│   │                           ├── config/
│   │                           │   ├── MyConfiguration.java
│   │                           │   └── MySmartInitializingSingleton.java
│   │                           └── service/
│   │                               └── MyService.java
│   └── spring-interface-smartInstantiationAwareBeanPostProcessor/
│       ├── README.md
│       ├── pom.xml
│       └── src/
│           └── main/
│               └── java/
│                   └── com/
│                       └── xcs/
│                           └── spring/
│                               ├── SmartInstantiationAwareBeanPostProcessorApplication.java
│                               ├── annotation/
│                               │   └── MyAutowired.java
│                               ├── config/
│                               │   ├── MyConfiguration.java
│                               │   └── MySmartInstantiationAwareBeanPostProcessor.java
│                               └── service/
│                                   ├── MyService.java
│                                   ├── MyServiceA.java
│                                   └── MyServiceB.java
├── spring-jsr/
│   ├── pom.xml
│   ├── spring-jsr250-postConstruct/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── PostConstructApplication.java
│   │                           ├── config/
│   │                           │   └── MyConfiguration.java
│   │                           └── service/
│   │                               └── MyService.java
│   ├── spring-jsr250-preDestroy/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── PreDestroyApplication.java
│   │                           ├── config/
│   │                           │   └── MyConfiguration.java
│   │                           └── service/
│   │                               └── MyService.java
│   ├── spring-jsr250-resource/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── ResourceApplication.java
│   │                           ├── config/
│   │                           │   └── MyConfiguration.java
│   │                           ├── controller/
│   │                           │   └── MyController.java
│   │                           └── service/
│   │                               └── MyService.java
│   ├── spring-jsr330-inject/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── InjectApplication.java
│   │                           ├── config/
│   │                           │   └── MyConfiguration.java
│   │                           ├── controller/
│   │                           │   └── MyController.java
│   │                           └── service/
│   │                               └── MyService.java
│   ├── spring-jsr330-named/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── NamedApplication.java
│   │                           ├── config/
│   │                           │   └── MyConfiguration.java
│   │                           ├── controller/
│   │                           │   └── MyController.java
│   │                           └── service/
│   │                               ├── MyService.java
│   │                               ├── MyServiceA.java
│   │                               └── MyServiceB.java
│   ├── spring-jsr330-provider/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── ProviderApplication.java
│   │                           ├── config/
│   │                           │   └── MyConfiguration.java
│   │                           ├── controller/
│   │                           │   └── MyController.java
│   │                           └── service/
│   │                               └── MyService.java
│   ├── spring-jsr330-qualifier/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── QualifierApplication.java
│   │                           ├── annotation/
│   │                           │   ├── Email.java
│   │                           │   └── SMS.java
│   │                           ├── config/
│   │                           │   └── MyConfiguration.java
│   │                           ├── controller/
│   │                           │   └── MessageController.java
│   │                           └── service/
│   │                               ├── MessageService.java
│   │                               └── impl/
│   │                                   ├── EmailServiceImpl.java
│   │                                   └── SMSServiceImpl.java
│   ├── spring-jsr330-scope/
│   │   ├── README.md
│   │   └── pom.xml
│   └── spring-jsr330-singleton/
│       ├── README.md
│       └── pom.xml
├── spring-metadata/
│   ├── pom.xml
│   ├── spring-metadata-annotationMetadata/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── AnnotationMetadataDemoByASM.java
│   │                           ├── AnnotationMetadataDemoByReflection.java
│   │                           └── bean/
│   │                               └── MyBean.java
│   ├── spring-metadata-condition/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── ConditionDemo.java
│   │                           ├── bean/
│   │                           │   ├── MyBeanA.java
│   │                           │   └── MyBeanB.java
│   │                           └── condition/
│   │                               └── MyOnClassCondition.java
│   ├── spring-metadata-metadataReader/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── MetadataReaderDemo.java
│   │                           ├── annotation/
│   │                           │   ├── MyAnnotation.java
│   │                           │   └── MyClassAnnotation.java
│   │                           └── bean/
│   │                               ├── MyAbstract.java
│   │                               └── MyBean.java
│   └── spring-metadata-typeFilter/
│       ├── README.md
│       ├── pom.xml
│       └── src/
│           └── main/
│               └── java/
│                   └── com/
│                       └── xcs/
│                           └── spring/
│                               ├── TypeFilterDemo.java
│                               ├── annotation/
│                               │   └── MyAnnotation.java
│                               ├── component/
│                               │   └── MyComponent.java
│                               ├── controller/
│                               │   └── MyController.java
│                               ├── repository/
│                               │   └── MyRepository.java
│                               └── service/
│                                   └── MyService.java
├── spring-mvc/
│   └── pom.xml
├── spring-resources/
│   ├── pom.xml
│   ├── spring-resource/
│   │   ├── README.md
│   │   ├── myfile.txt
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           ├── java/
│   │           │   └── com/
│   │           │       └── xcs/
│   │           │           └── spring/
│   │           │               ├── ByteArrayResourceDemo.java
│   │           │               ├── ClassPathResourceDemo.java
│   │           │               ├── FileSystemResourceDemo.java
│   │           │               ├── InputStreamResourceDemo.java
│   │           │               └── UrlResourceDemo.java
│   │           └── resources/
│   │               └── application.properties
│   ├── spring-resource-documentLoader/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           ├── java/
│   │           │   └── com/
│   │           │       └── xcs/
│   │           │           └── spring/
│   │           │               ├── DocumentLoaderDemo.java
│   │           │               └── bean/
│   │           │                   └── MyBean.java
│   │           └── resources/
│   │               └── sample.xml
│   ├── spring-resource-resourceLoader/
│   │   ├── README.md
│   │   ├── myfile1.txt
│   │   ├── myfile2.txt
│   │   ├── myfile3.txt
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           ├── java/
│   │           │   └── com/
│   │           │       └── xcs/
│   │           │           └── spring/
│   │           │               ├── DefaultResourceLoaderDemo.java
│   │           │               └── PathMatchingResourcePatternResolverDemo.java
│   │           └── resources/
│   │               ├── application.properties
│   │               └── bootstrap.properties
│   └── spring-resource-resourcePatternResolver/
│       ├── README.md
│       ├── myfile1.txt
│       ├── myfile2.txt
│       ├── myfile3.txt
│       ├── pom.xml
│       └── src/
│           └── main/
│               ├── java/
│               │   └── com/
│               │       └── xcs/
│               │           └── spring/
│               │               └── ResourcePatternResolverDemo.java
│               └── resources/
│                   ├── application.properties
│                   └── bootstrap.properties
├── spring-spel/
│   ├── pom.xml
│   ├── spring-spel-beanResolver/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── BeanResolverDemo.java
│   │                           └── MyBean.java
│   ├── spring-spel-constructorResolver/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── ConstructorResolverDemo.java
│   │                           └── MyBean.java
│   ├── spring-spel-evaluationContext/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           └── EvaluationContextDemo.java
│   ├── spring-spel-expression/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           └── ExpressionDemo.java
│   ├── spring-spel-expressionParser/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           └── ExpressionParserDemo.java
│   ├── spring-spel-methodResolver/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── MethodResolverDemo.java
│   │                           └── MyBean.java
│   ├── spring-spel-operatorOverloader/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               ├── CustomOperatorOverloader.java
│   │               ├── MyBean.java
│   │               └── OperatorOverloaderDemo.java
│   ├── spring-spel-propertyAccessor/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── MyBean.java
│   │                           └── PropertyAccessorDemo.java
│   ├── spring-spel-typeComparator/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           └── TypeComparatorDemo.java
│   ├── spring-spel-typeConverter/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           └── TypeConverterDemo.java
│   └── spring-spel-typeLocator/
│       ├── README.md
│       ├── pom.xml
│       └── src/
│           └── main/
│               └── java/
│                   └── com/
│                       └── xcs/
│                           └── spring/
│                               └── TypeLocatorDemo.java
└── spring-transaction/
    ├── pom.xml
    ├── spring-transaction-connection/
    │   ├── README.md
    │   ├── pom.xml
    │   └── src/
    │       └── main/
    │           └── java/
    │               └── com/
    │                   └── xcs/
    │                       └── spring/
    │                           └── ConnectionDemo.java
    ├── spring-transaction-dataSource/
    │   ├── README.md
    │   ├── pom.xml
    │   └── src/
    │       └── main/
    │           └── java/
    │               └── com/
    │                   └── xcs/
    │                       └── spring/
    │                           └── DataSourceDemo.java
    ├── spring-transaction-driverManager/
    │   ├── README.md
    │   ├── pom.xml
    │   └── src/
    │       └── main/
    │           └── java/
    │               └── com/
    │                   └── xcs/
    │                       └── spring/
    │                           └── DriverManagerDemo.java
    ├── spring-transaction-enableTransactionManagement/
    │   ├── README.md
    │   ├── pom.xml
    │   └── src/
    │       └── main/
    │           └── java/
    │               └── com/
    │                   └── xcs/
    │                       └── spring/
    │                           ├── AppConfig.java
    │                           ├── EnableTransactionManagementDemo.java
    │                           ├── ScoresService.java
    │                           └── ScoresServiceImpl.java
    ├── spring-transaction-jdbcTemplate/
    │   ├── README.md
    │   ├── pom.xml
    │   └── src/
    │       └── main/
    │           └── java/
    │               └── com/
    │                   └── xcs/
    │                       └── spring/
    │                           ├── JdbcTemplateDemo.java
    │                           └── Scores.java
    ├── spring-transaction-platformTransactionManager/
    │   ├── README.md
    │   ├── pom.xml
    │   └── src/
    │       └── main/
    │           └── java/
    │               └── com/
    │                   └── xcs/
    │                       └── spring/
    │                           └── PlatformTransactionManagerDemo.java
    ├── spring-transaction-springTransactionAnnotationParser/
    │   ├── README.md
    │   ├── pom.xml
    │   └── src/
    │       └── main/
    │           └── java/
    │               └── com/
    │                   └── xcs/
    │                       └── spring/
    │                           ├── ScoresService.java
    │                           ├── ScoresServiceImpl.java
    │                           └── SpringTransactionAnnotationParserDemo.java
    ├── spring-transaction-transactionAttributeSource/
    │   ├── README.md
    │   ├── pom.xml
    │   └── src/
    │       └── main/
    │           └── java/
    │               └── com/
    │                   └── xcs/
    │                       └── spring/
    │                           ├── ScoresService.java
    │                           ├── ScoresServiceImpl.java
    │                           └── TransactionAttributeSourceDemo.java
    ├── spring-transaction-transactionDefinition/
    │   ├── README.md
    │   ├── pom.xml
    │   └── src/
    │       └── main/
    │           └── java/
    │               └── com/
    │                   └── xcs/
    │                       └── spring/
    │                           └── TransactionDefinitionDemo.java
    ├── spring-transaction-transactionInterceptor/
    │   ├── README.md
    │   ├── pom.xml
    │   └── src/
    │       └── main/
    │           └── java/
    │               └── com/
    │                   └── xcs/
    │                       └── spring/
    │                           ├── ScoresService.java
    │                           ├── ScoresServiceImpl.java
    │                           └── TransactionInterceptorDemo.java
    ├── spring-transaction-transactionTemplate/
    │   ├── README.md
    │   ├── pom.xml
    │   └── src/
    │       └── main/
    │           └── java/
    │               └── com/
    │                   └── xcs/
    │                       └── spring/
    │                           └── TransactionTemplateDemo.java
    └── sql/
        └── test.sql

================================================
FILE CONTENTS
================================================

================================================
FILE: .gitignore
================================================
HELP.md
target/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**/target/
!**/src/test/**/target/

### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache

### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr

### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/
!**/src/main/**/build/
!**/src/test/**/build/

### VS Code ###
.vscode/


================================================
FILE: LICENSE
================================================
MIT License

Copyright (c) 2024 xuchengsheng

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.


================================================
FILE: README.md
================================================
<div align="center">
    <img alt="logo" src="image/banner.png" style="height: 80px">
</div>
<div align="center">
    <h2>深入Spring,从源码开始!</h2>
    <h4>探索Java最受欢迎的框架,理解它的内部机制,带大家从入门到精通。</h4>
</div>
<p align="center">
    <a href="https://github.com/xuchengsheng/spring-reading/stargazers"><img src="https://img.shields.io/github/stars/xuchengsheng/spring-reading?logo=github&logoColor=%23EF2D5E&label=Stars&labelColor=%23000000&color=%23EF2D5E&cacheSeconds=3600" alt="Stars Badge"/></a>
    <a href="https://github.com/xuchengsheng"><img src="https://img.shields.io/github/followers/xuchengsheng?label=Followers&logo=github&logoColor=%23FC521F&labelColor=%231A2477&color=%23FC521F&cacheSeconds=3600" alt="Follow Badge"></a>
    <a href="https://github.com/xuchengsheng/spring-reading/fork"><img src="https://img.shields.io/github/forks/xuchengsheng/spring-reading?label=Forks&logo=github&logoColor=%23F2BB13&labelColor=%23BE2323&color=%23F2BB13" alt="Fork Badge"></a>
    <a href="https://github.com/xuchengsheng/spring-reading/watchers"><img src="https://img.shields.io/github/watchers/xuchengsheng/spring-reading?label=Watchers&logo=github&logoColor=%23FF4655&labelColor=%234169E1&color=%23FF4655&cacheSeconds=3600" alt="Watchers Badge"></a>
</p>
<p align="center">
    <img src="https://visitor-badge.lithub.cc/badge?page_id=github.com/xuchengsheng&left_text=Visitors" alt="Visitor Badge"/>
    <img src="https://img.shields.io/badge/WeChat-spring_reading-%2307C160?logo=wechat" alt="Wechat Badge"/>
    <a href="https://blog.csdn.net/duzhuang2399"><img src="https://img.shields.io/badge/dynamic/xml?url=https%3A%2F%2Fblog.csdn.net%2Fduzhuang2399&query=%2F%2F*%5B%40id%3D%22userSkin%22%5D%2Fdiv%5B1%5D%2Fdiv%5B2%5D%2Fdiv%5B1%5D%2Fdiv%2Fdiv%5B2%5D%2Fdiv%5B1%5D%2Fdiv%5B1%5D%2Fdiv%5B2%5D%2Fspan&logo=C&logoColor=red&label=CSDN&color=red&cacheSeconds=3600" alt="CSDN Badge"></a>
        <a href="https://hellogithub.com/repository/f43b683fa175499ca3af4e9b1684e88b" target="_blank"><img src="https://api.hellogithub.com/v1/widgets/recommend.svg?rid=f43b683fa175499ca3af4e9b1684e88b&claim_uid=AVv4KeNnZs2Ig3a&theme=small" alt="Featured|HelloGitHub"/></a>
</p>
<p align="center">
    ⚡ <a href="#技术">技术</a>
    |
    👋 <a href="#简介">简介</a>
    |
    🍵 <a href="#为何做Spring源码分析">Why</a>
    |
    🙏 <a href="#顺手点个星">点个星</a>
    |
    🌱 <a href="#spring-源码阅读系列">Spring源码</a>
    |
    💬 <a href="#与我联系">联系我</a>
    |
    ⛵ <a href="#欢迎贡献">贡献</a>
    |
    🔄 <a href="#持续更新中">更新</a>
    |
    💻 <a href="#我的-github-统计">统计</a>
</p>


---

## ⚡技术

<div align="left">
    <img src="https://img.shields.io/badge/Java-1.8%2B-%23437291?logo=openjdk&logoColor=%23437291"/>
    <img src="https://img.shields.io/badge/Spring-5.3.10-%23437291?logo=Spring&logoColor=%236DB33F&color=%236DB33F"/>
    <img src="https://img.shields.io/badge/SpringBoot-2.5.5-%23437291?logo=SpringBoot&logoColor=%236DB33F&color=%236DB33F"/>
    <img src="https://img.shields.io/badge/Maven-3.6.3-%23437291?logo=Apache%20Maven&logoColor=%23C71A36&color=%23C71A36"/>
    <img src="https://img.shields.io/badge/JSR-330-%2366CCFF?logo=OpenJDK&logoColor=%2366CCFF&color=%2366CCFF"/>
    <img src="https://img.shields.io/badge/JSR-250-%23FF9900?logo=OpenJDK&logoColor=%23FF9900&color=%23FF9900"/>
</div>

## 👋简介
大家好呀,我是Lex👨‍💻。我是一名拥有8年经验的Java 后端开发人员👨‍💼,也是一个对 Spring 框架充满热情❤️的程序员。为了帮助那些希望深入了解 Spring 框架的程序员们🧑‍💻,我创建了这个 “Spring 源码阅读系列”📖。通过这个系列,我希望能够与你们共同探索 Spring 的内部工作机制⚙️。如果您有同样的兴趣或问题🤔,请联系我📩!

## 🍵**为何做Spring源码分析**
在我作为框架研发的开发者👨‍🔬的工作中,我经常遇到需要深入理解和调整框架行为的情况🔧。这些工作不只是简单地使用框架的API,更多地是需要对框架的内部工作方式有详细的了解🔍。虽然Github上有关于Spring的简化版本📦,这些对于入门学习确实有很大的帮助✅,但当涉及到真实的项目应用时,与真正的Spring框架还是有很大的差异❌。因此,我开始深入研究Spring的源码,希望能够更透彻地理解其内部的工作机制,以便更好地应用到我的实际工作中🧰。分享我的源码分析📝,也是为了给那些希望真正理解Spring,而不仅仅是使用它的开发者提供一些参考和帮助🙌。

## 🙏顺手点个星
亲爱的朋友们👥,我真的花了很多心思💭去研究和整理这个“Spring 源码阅读系列”📘。如果你觉得这东西还不错👍,或者给你带来了一点点帮助🤗,麻烦点一下星星吧🌟。这真的对我意义重大🎖,每一颗星✨都能让我觉得所有的努力都是值得的💪。我知道这是小事一桩,但你的那一下点击🖱,对我来说就是最好的鼓励🎉。无论如何,都要感谢你抽时间🕰阅读我的内容,真的很感激🙏!

## 🌱Spring 源码阅读系列

+ Spring Core
  + 资源加载与访问
    - [Resource](spring-resources/spring-resource/README.md):抽象接口,表示文件、类路径等,用于访问不同来源的资源。<img src="https://img.shields.io/badge/Level-%E7%AE%80%E5%8D%95-0099ff"></img>
    - [ResourceLoader](spring-resources/spring-resource-resourceLoader/README.md):资源获取核心接口,实现统一加载不同位置资源的策略。<img src="https://img.shields.io/badge/Level-%E7%AE%80%E5%8D%95-0099ff"></img>
    - [ResourcePatternResolver](spring-resources/spring-resource-resourcePatternResolver/README.md):资源模式解析接口,用于灵活加载应用中的多种资源。<img src="https://img.shields.io/badge/Level-%E7%AE%80%E5%8D%95-0099ff"></img>
    - [DocumentLoader](spring-resources/spring-resource-documentLoader/README.md):XML文档加载解析核心接口,支持后台自动配置Spring应用。<img src="https://img.shields.io/badge/Level-%E7%AE%80%E5%8D%95-0099ff"></img>

  + 元数据与过滤
    - [MetadataReader](spring-metadata/spring-metadata-metadataReader/README.md):类元数据获取核心,支持组件扫描、条件化注解、AOP等高级功能。<img src="https://img.shields.io/badge/Level-%E7%AE%80%E5%8D%95-0099ff"></img>
    - [AnnotationMetadata](spring-metadata/spring-metadata-annotationMetadata/README.md):动态获取和操作运行时类注解信息。<img src="https://img.shields.io/badge/Level-%E7%AE%80%E5%8D%95-0099ff"></img>
    - [TypeFilter](spring-metadata/spring-metadata-typeFilter/README.md):组件扫描时自定义类筛选,支持复杂条件和精确过滤。<img src="https://img.shields.io/badge/Level-%E7%AE%80%E5%8D%95-0099ff"></img>
    - [Condition](spring-metadata/spring-metadata-condition/README.md):条件判断,决定Bean创建和配置的灵活机制。<img src="https://img.shields.io/badge/Level-%E7%AE%80%E5%8D%95-0099ff"></img>

  + 验证、数据绑定和类型转换
    - [Validator](spring-dataops/spring-dataops-validator/README.md):提供自定义数据验证逻辑,确保模型对象满足业务规则。<img src="https://img.shields.io/badge/Level-%E7%AE%80%E5%8D%95-0099ff"></img>
    - [PropertyEditor](spring-dataops/spring-dataops-propertyEditor/README.md):自定义JavaBean属性的转换逻辑,处理属性类型转换。<img src="https://img.shields.io/badge/Level-%E7%AE%80%E5%8D%95-0099ff"></img>
    - [Converter](spring-dataops/spring-dataops-converter/README.md):用于不同类型间的转换,定义简单的源至目标类型转换规则。<img src="https://img.shields.io/badge/Level-%E7%AE%80%E5%8D%95-0099ff"></img>
    - [ConverterFactory](spring-dataops/spring-dataops-converterFactory/README.md):创建针对特定源类型的转换器,用于类型转换。<img src="https://img.shields.io/badge/Level-%E7%AE%80%E5%8D%95-0099ff"></img>
    - [GenericConverter](spring-dataops/spring-dataops-genericConverter/README.md):更复杂的转换器,支持多种源和目标类型转换。<img src="https://img.shields.io/badge/Level-%E7%AE%80%E5%8D%95-0099ff"></img>
    - [ConditionalConverter](spring-dataops/spring-dataops-conditionalConverter/README.md):根据条件选择是否执行转换的转换器。<img src="https://img.shields.io/badge/Level-%E7%AE%80%E5%8D%95-0099ff"></img>
    - [ConversionService](spring-dataops/spring-dataops-conversionService/README.md):提供统一的类型转换服务接口,管理转换器。<img src="https://img.shields.io/badge/Level-%E7%AE%80%E5%8D%95-0099ff"></img>
    - [Printer](spring-dataops/spring-dataops-printer/README.md):用于将对象格式化为文本,专注于格式化输出。<img src="https://img.shields.io/badge/Level-%E7%AE%80%E5%8D%95-0099ff"></img>
    - [Parser](spring-dataops/spring-dataops-parser/README.md):用于将文本解析为对象,专注于解析逻辑。<img src="https://img.shields.io/badge/Level-%E7%AE%80%E5%8D%95-0099ff"></img>

  + Spring 表达式语言(SpEL)
    - [ExpressionParser](spring-spel/spring-spel-expressionParser/README.md): 解析字符串形式的 SpEL 表达式,创建并返回 Expression 实例。<img src="https://img.shields.io/badge/Level-%E5%9B%B0%E9%9A%BE-%23FF3030"></img>
    - [Expression](spring-spel/spring-spel-expression/README.md): 对表达式字符串进行求值的功能,支持类型转换、获取原始字符串等操作。<img src="https://img.shields.io/badge/Level-%E5%9B%B0%E9%9A%BE-%23FF3030"></img>
    - [EvaluationContext](spring-spel/spring-spel-evaluationContext/README.md): 管理SpEL表达式的上下文信息。<img src="https://img.shields.io/badge/Level-%E7%AE%80%E5%8D%95-0099ff"></img>
    - [PropertyAccessor](spring-spel/spring-spel-propertyAccessor/README.md): 用于读取和写入对象的属性,可用于实现自定义的属性访问逻辑。<img src="https://img.shields.io/badge/Level-%E7%AE%80%E5%8D%95-0099ff"></img>
    - [ConstructorResolver](spring-spel/spring-spel-constructorResolver/README.md): 解析构造函数确定bean的实例化方式。<img src="https://img.shields.io/badge/Level-%E7%AE%80%E5%8D%95-0099ff"></img>
    - [MethodResolver](spring-spel/spring-spel-methodResolver/README.md): 解析类方法,确保正确调用,处理重载和参数匹配。<img src="https://img.shields.io/badge/Level-%E7%AE%80%E5%8D%95-0099ff"></img>
    - [BeanResolver](spring-spel/spring-spel-beanResolver/README.md): 解析bean定义,包括依赖、属性设置,实例化并返回。<img src="https://img.shields.io/badge/Level-%E7%AE%80%E5%8D%95-0099ff"></img>
    - [TypeLocator](spring-spel/spring-spel-typeLocator/README.md): 动态查找类,返回Class对象,在表达式解析、类型转换等。<img src="https://img.shields.io/badge/Level-%E7%AE%80%E5%8D%95-0099ff"></img>
    - [TypeConverter](spring-spel/spring-spel-typeLocator/README.md): 类型转换功能,将表达式中的数据从一种类型转换为另一种类型。<img src="https://img.shields.io/badge/Level-%E7%AE%80%E5%8D%95-0099ff"></img>
    - [TypeComparator](spring-spel/spring-spel-typeLocator/README.md): 类型比较功能,定义了比较两个对象是否相等的方法。<img src="https://img.shields.io/badge/Level-%E7%AE%80%E5%8D%95-0099ff"></img>
    - [OperatorOverloader](spring-spel/spring-spel-typeLocator/README.md): 运算符重载功能,对表达式中的运算符进行自定义操作的方法。<img src="https://img.shields.io/badge/Level-%E7%AE%80%E5%8D%95-0099ff"></img>

  + Bean定义与注册
    - [BeanDefinition](spring-beans/spring-bean-beanDefinition/README.md):详细描述Bean,支持依赖注入、AOP、作用域控制等核心功能。<img src="https://img.shields.io/badge/Level-%E7%AE%80%E5%8D%95-0099ff"></img>
    - [BeanDefinitionHolder](spring-beans/spring-bean-beanDefinitionHolder/README.md):管理和操作BeanDefinition的关键类。<img src="https://img.shields.io/badge/Level-%E7%AE%80%E5%8D%95-0099ff"></img>
    - [BeanDefinitionRegistry](spring-beans/spring-bean-beanDefinitionRegistry/README.md):Bean定义注册管理关键接口,处理Bean元数据。<img src="https://img.shields.io/badge/Level-%E7%AE%80%E5%8D%95-0099ff"></img>

  + Bean定义读取与扫描
    - [XmlBeanDefinitionReader](spring-beans/spring-bean-xmlBeanDefinitionReader/README.md):加载解析XML配置,构建IOC容器,注册Bean定义。<img src="https://img.shields.io/badge/Level-%E4%B8%80%E8%88%AC-%23FF6347"></img>
    - [PropertiesBeanDefinitionReader](spring-beans/spring-bean-propertiesBeanDefinitionReader/README.md):属性文件加载,解析为Bean定义。<img src="https://img.shields.io/badge/Level-%E4%B8%80%E8%88%AC-%23FF6347"></img>
    - [GroovyBeanDefinitionReader](spring-beans/spring-bean-groovyBeanDefinitionReader/README.md):Groovy脚本解析为Bean定义。<img src="https://img.shields.io/badge/Level-%E4%B8%80%E8%88%AC-%23FF6347"></img>
    - [AnnotatedBeanDefinitionReader](spring-beans/spring-bean-annotatedBeanDefinitionReader/README.md):注解配置,自动扫描注册Spring组件,简化Bean定义配置。<img src="https://img.shields.io/badge/Level-%E4%B8%80%E8%88%AC-%23FF6347"></img>
    - [ClassPathBeanDefinitionScanner](spring-beans/spring-bean-classPathBeanDefinitionScanner/README.md):类路径扫描注册Spring Bean,支持自动装配。<img src="https://img.shields.io/badge/Level-%E4%B8%80%E8%88%AC-%23FF6347"></img>

  + Bean工厂
    - [BeanFactory](spring-factory/spring-factory-beanFactory/README.md):Spring的核心接口,提供对Bean的配置、创建、管理的基本功能。<img src="https://img.shields.io/badge/Level-%E4%B8%80%E8%88%AC-%23FF6347"></img>
    - [ListableBeanFactory](spring-factory/spring-factory-listableBeanFactory/README.md):支持按类型获取Bean的集合。<img src="https://img.shields.io/badge/Level-%E4%B8%80%E8%88%AC-%23FF6347"></img>
    - [HierarchicalBeanFactory](spring-factory/spring-factory-hierarchicalBeanFactory/README.md):支持父子容器关系,实现Bean定义的层次结构。<img src="https://img.shields.io/badge/Level-%E4%B8%80%E8%88%AC-%23FF6347"></img>
    - [ConfigurableBeanFactory](spring-factory/spring-factory-configurableBeanFactory/README.md):提供对BeanFactory配置的扩展,如属性编辑器、作用域等。<img src="https://img.shields.io/badge/Level-%E4%B8%80%E8%88%AC-%23FF6347"></img>
    - [AutowireCapableBeanFactory](spring-factory/spring-factory-autowireCapableBeanFactory/README.md):Bean创建、初始化、注入、销毁的核心功能接口。<img src="https://img.shields.io/badge/Level-%E4%B8%80%E8%88%AC-%23FF6347"></img>
    - [ConfigurableListableBeanFactory](spring-factory/spring-factory-configurableListableBeanFactory/README.md):支持配置和列表操作的可配置Bean工厂接口。<img src="https://img.shields.io/badge/Level-%E4%B8%80%E8%88%AC-%23FF6347"></img>

  + 容器上下文
    - [ClassPathXmlApplicationContext](spring-context/spring-context-classPathXmlApplicationContext/README.md):类路径(classpath)加载 XML 配置文件的上下文。<img src="https://img.shields.io/badge/Level-%E7%AE%80%E5%8D%95-0099ff"></img>
    - [AnnotationConfigApplicationContext](spring-context/spring-context-annotationConfigApplicationContext/README.md):注解配置类中加载配置信息的上下文。<img src="https://img.shields.io/badge/Level-%E7%AE%80%E5%8D%95-0099ff"></img>
    - GenericApplicationContext:支持多种配置方式,XML、注解、手动注册的上下文。<img src="https://img.shields.io/badge/%E5%8D%B3%E5%B0%86%E6%9B%B4%E6%96%B0-339933"></img>

  + Bean定义导入与组合
    - ImportBeanDefinitionRegistrar:运行时动态注册 Bean,实现灵活配置,扩展配置类功能。<img src="https://img.shields.io/badge/%E5%8D%B3%E5%B0%86%E6%9B%B4%E6%96%B0-339933"></img>
    - ImportSelector:运行时动态导入配置类,实现条件选择和灵活配置。<img src="https://img.shields.io/badge/%E5%8D%B3%E5%B0%86%E6%9B%B4%E6%96%B0-339933"></img>
    - DeferredImportSelector:运行时动态导入配置,支持条件选择和按组别延迟加载。<img src="https://img.shields.io/badge/%E5%8D%B3%E5%B0%86%E6%9B%B4%E6%96%B0-339933"></img>

  + Bean生命周期
    - [Bean的定义注册过程](spring-core/spring-core-registerBeanDefinition):加载与解析配置文件,注册解析Bean定义,类名、作用域、属性等。<img src="https://img.shields.io/badge/Level-%E4%B8%80%E8%88%AC-%23FF8C69"></img>
    - [Bean的初始化过程](spring-core/spring-core-getBean/README.md):实例化、属性注入、Aware回调、后置处理器、初始化方法调用。<img src="https://img.shields.io/badge/Level-%E5%9B%B0%E9%9A%BE-%23FF3030"></img>
    - [Bean的依赖解析过程](spring-core/spring-core-resolveDependency/README.md):声明依赖,查找依赖,注入依赖,处理循环依赖,延迟依赖解析。<img src="https://img.shields.io/badge/Level-%E5%9B%B0%E9%9A%BE-%23FF3030"></img>
    - [Bean的销毁过程](spring-core/spring-core-destroyBean/README.md):销毁方法调用,接口回调,后处理清理,通知触发,GC回收资源。<img src="https://img.shields.io/badge/Level-%E5%9B%B0%E9%9A%BE-%23FF3030"></img>

  + 属性解析和环境配置
    - [PropertySource](spring-env/spring-env-propertySource/README.md):管理各种配置源的抽象类,支持灵活地加载和访问应用配置。<img src="https://img.shields.io/badge/Level-%E7%AE%80%E5%8D%95-0099ff"></img>
    - [PropertySources](spring-env/spring-env-propertySources/README.md):用于统一管理和访问多个 PropertySource 实例,简化配置数据的处理。<img src="https://img.shields.io/badge/Level-%E7%AE%80%E5%8D%95-0099ff"></img>
    - [PropertyResolver](spring-env/spring-env-propertyResolver/README.md):通用属性解析,获取配置值,处理属性缺失,简便灵活。<img src="https://img.shields.io/badge/Level-%E7%AE%80%E5%8D%95-0099ff"></img>
    - [ConfigurablePropertyResolver](spring-env/spring-env-configurablePropertyResolver/README.md):属性解析配置,占位符设置,适应不同配置需求。<img src="https://img.shields.io/badge/Level-%E7%AE%80%E5%8D%95-0099ff"></img>
    - [Environment](spring-env/spring-env-environment/README.md):应用环境表示,提供属性访问,支持配置文件,实现动态配置。<img src="https://img.shields.io/badge/Level-%E7%AE%80%E5%8D%95-0099ff"></img>
    - [ConfigurableEnvironment](spring-env/spring-env-configurableEnvironment/README.md):动态配置应用环境,激活、默认配置,提升应用灵活性。<img src="https://img.shields.io/badge/Level-%E7%AE%80%E5%8D%95-0099ff"></img>

  + Bean初始化与扩展点
    - [InitializingBean](spring-interface/spring-interface-initializingBean/README.md):提供Bean初始化时执行自定义逻辑的接口。<img src="https://img.shields.io/badge/Level-%E4%B8%80%E8%88%AC-%23FF8C69"></img>
    - [DisposableBean](spring-interface/spring-interface-disposableBean/README.md):定义Bean销毁前执行清理操作的接口。<img src="https://img.shields.io/badge/Level-%E4%B8%80%E8%88%AC-%23FF8C69"></img>
    - [BeanDefinitionRegistryPostProcessor](spring-interface/spring-interface-beanDefinitionRegistryPostProcessor/README.md):在容器启动时,对BeanDefinition动态修改或添加。<img src="https://img.shields.io/badge/Level-%E4%B8%80%E8%88%AC-%23FF8C69"></img>
    - [BeanFactoryPostProcessor](spring-interface/spring-interface-beanFactoryPostProcessor/README.md):在Bean实例化前,对BeanFactory进行全局修改或配置。<img src="https://img.shields.io/badge/Level-%E4%B8%80%E8%88%AC-%23FF8C69"></img>
    - [BeanPostProcessor](spring-interface/spring-interface-beanPostProcessor/README.md):在Bean初始化前后,进行自定义处理,可影响所有Bean。<img src="https://img.shields.io/badge/Level-%E4%B8%80%E8%88%AC-%23FF8C69"></img>
    - [InstantiationAwareBeanPostProcessor](spring-interface/spring-interface-instantiationAwareBeanPostProcessor/README.md):提供更深层次的实例化和属性注入控制。<img src="https://img.shields.io/badge/Level-%E4%B8%80%E8%88%AC-%23FF8C69"></img>
    - [DestructionAwareBeanPostProcessor](spring-interface/spring-interface-destructionAwareBeanPostProcessor/README.md): 允许在Bean销毁前进行额外的清理操作。<img src="https://img.shields.io/badge/Level-%E4%B8%80%E8%88%AC-%23FF8C69"></img>
    - [MergedBeanDefinitionPostProcessor](spring-interface/spring-interface-mergedBeanDefinitionPostProcessor/README.md):在合并Bean定义时对BeanDefinition进行处理。<img src="https://img.shields.io/badge/Level-%E4%B8%80%E8%88%AC-%23FF8C69"></img>
    - [SmartInstantiationAwareBeanPostProcessor](spring-interface/spring-interface-smartInstantiationAwareBeanPostProcessor/README.md):提供更智能的实例化控制。<img src="https://img.shields.io/badge/Level-%E4%B8%80%E8%88%AC-%23FF8C69"></img>
    - [SmartInitializingSingleton](spring-interface/spring-interface-smartInitializingSingleton/README.md):在所有单例Bean初始化完成后,执行自定义逻辑。<img src="https://img.shields.io/badge/Level-%E4%B8%80%E8%88%AC-%23FF8C69"></img>

  + Aware接口系列
    - [BeanNameAware](spring-aware/spring-aware-beanNameAware/README.md):让Bean获取自身在容器中的名字。<img src="https://img.shields.io/badge/Level-%E4%B8%80%E8%88%AC-%23FF8C69"></img>
    - [BeanClassLoaderAware](spring-aware/spring-aware-beanClassLoaderAware/README.md):允许Bean获取其类加载器。<img src="https://img.shields.io/badge/Level-%E4%B8%80%E8%88%AC-%23FF8C69"></img>
    - [BeanFactoryAware](spring-aware/spring-aware-beanFactoryAware/README.md):提供Bean获取所属的BeanFactory。<img src="https://img.shields.io/badge/Level-%E4%B8%80%E8%88%AC-%23FF8C69"></img>
    - [EnvironmentAware](spring-aware/spring-aware-environmentAware/README.md):允许Bean获取应用程序环境配置。<img src="https://img.shields.io/badge/Level-%E4%B8%80%E8%88%AC-%23FF8C69"></img>
    - [EmbeddedValueResolverAware](spring-aware/spring-aware-embeddedValueResolverAware/README.md):允许Bean解析嵌入式值占位符。<img src="https://img.shields.io/badge/Level-%E4%B8%80%E8%88%AC-%23FF8C69"></img>
    - [ResourceLoaderAware](spring-aware/spring-aware-beanClassLoaderAware/README.md):允许Bean获取资源加载器。<img src="https://img.shields.io/badge/Level-%E4%B8%80%E8%88%AC-%23FF8C69"></img>
    - [ApplicationEventPublisherAware](spring-aware/spring-aware-applicationEventPublisherAware/README.md):允许Bean发布应用程序事件。<img src="https://img.shields.io/badge/Level-%E4%B8%80%E8%88%AC-%23FF8C69"></img>
    - [MessageSourceAware](spring-aware/spring-aware-messageSourceAware/README.md):允许Bean获取消息源。<img src="https://img.shields.io/badge/Level-%E4%B8%80%E8%88%AC-%23FF8C69"></img>
    - [ApplicationContextAware](spring-aware/spring-aware-applicationContextAware/README.md):允许Bean获取应用程序上下文。<img src="https://img.shields.io/badge/Level-%E4%B8%80%E8%88%AC-%23FF8C69"></img>
    - [ImportAware](spring-aware/spring-aware-importAware/README.md):允许被导入的配置类获取导入它的类的信息。<img src="https://img.shields.io/badge/Level-%E4%B8%80%E8%88%AC-%23FF8C69"></img>

  + 核心注解
    - [@Configuration](spring-annotation/spring-annotation-configuration/README.md):声明类为配置类,定义Bean和Bean之间的依赖关系。<img src="https://img.shields.io/badge/Level-%E5%9B%B0%E9%9A%BE-%23FF3030"></img>
    - [@ComponentScan](spring-annotation/spring-annotation-componentScan/README.md):启用组件扫描,自动发现并注册标记为组件的类。<img src="https://img.shields.io/badge/Level-%E5%9B%B0%E9%9A%BE-%23FF3030"></img>
    - [@Bean](spring-annotation/spring-annotation-bean/README.md):在配置类中声明方法,返回Bean实例。<img src="https://img.shields.io/badge/Level-%E5%9B%B0%E9%9A%BE-%23FF3030"></img>
    - [@Import](spring-annotation/spring-annotation-import/README.md):引入其他配置类,将其Bean定义合并到当前容器。<img src="https://img.shields.io/badge/Level-%E5%9B%B0%E9%9A%BE-%23FF3030"></img>
    - [@PropertySource](spring-annotation/spring-annotation-propertySource/README.md):指定属性文件,加载外部配置到环境中。<img src="https://img.shields.io/badge/Level-%E5%9B%B0%E9%9A%BE-%23FF3030"></img>
    - [@DependsOn](spring-annotation/spring-annotation-dependsOn/README.md):指定Bean的依赖顺序,确保特定Bean在其他Bean之前初始化。<img src="https://img.shields.io/badge/Level-%E5%9B%B0%E9%9A%BE-%23FF3030"></img>
    - [@Conditional](spring-annotation/spring-annotation-conditional/README.md):根据条件决定是否创建Bean。<img src="https://img.shields.io/badge/Level-%E5%9B%B0%E9%9A%BE-%23FF3030"></img>
    - [@Lazy](spring-annotation/spring-annotation-lazy/README.md):指定Bean的延迟初始化,只有在首次使用时才创建。<img src="https://img.shields.io/badge/Level-%E5%9B%B0%E9%9A%BE-%23FF3030"></img>
    - [@Value](spring-annotation/spring-annotation-value/README.md):注入简单值或表达式到Bean的字段或方法参数。<img src="https://img.shields.io/badge/Level-%E5%9B%B0%E9%9A%BE-%23FF3030"></img>
    - [@Autowired](spring-annotation/spring-annotation-autowired/README.md):自动装配Bean依赖。<img src="https://img.shields.io/badge/Level-%E5%9B%B0%E9%9A%BE-%23FF3030"></img>
    - @Primary:指定在多个候选Bean中优先选择的首选Bean。<img src="https://img.shields.io/badge/%E5%8D%B3%E5%B0%86%E6%9B%B4%E6%96%B0-339933"></img>
    - @Description:为Bean提供描述性信息。<img src="https://img.shields.io/badge/%E5%8D%B3%E5%B0%86%E6%9B%B4%E6%96%B0-339933"></img>
    - @Role:为Bean提供角色提示,用于区分相似类型的Bean。<img src="https://img.shields.io/badge/%E5%8D%B3%E5%B0%86%E6%9B%B4%E6%96%B0-339933"></img>
    - @Indexed: 标记Bean用于索引。<img src="https://img.shields.io/badge/%E5%8D%B3%E5%B0%86%E6%9B%B4%E6%96%B0-339933"></img>
    - @Order:指定Bean的加载顺序。<img src="https://img.shields.io/badge/%E5%8D%B3%E5%B0%86%E6%9B%B4%E6%96%B0-339933"></img>

  + JSR规范
    - [@Inject](spring-jsr/spring-jsr330-inject/README.md):JSR-330标准的依赖注入注解。<img src="https://img.shields.io/badge/Level-%E4%B8%80%E8%88%AC-%23FF8C69"></img>
    - [@Named](spring-jsr/spring-jsr330-named/README.md):JSR-330标准的命名注解。<img src="https://img.shields.io/badge/Level-%E4%B8%80%E8%88%AC-%23FF8C69"></img>
    - [@Resource](spring-jsr/spring-jsr250-resource/README.md):Java EE标准的资源注入注解。<img src="https://img.shields.io/badge/Level-%E4%B8%80%E8%88%AC-%23FF8C69"></img>
    - [@Qualifier](spring-jsr/spring-jsr330-qualifier/README.md):用于限定注入的Bean。<img src="https://img.shields.io/badge/Level-%E4%B8%80%E8%88%AC-%23FF8C69"></img>
    - [@Scope](spring-jsr/spring-jsr330-scope/README.md):指定Bean的作用域。<img src="https://img.shields.io/badge/Level-%E4%B8%80%E8%88%AC-%23FF8C69"></img>
    - [@Singleton](spring-jsr/spring-jsr330-singleton/README.md):指定Bean为单例。<img src="https://img.shields.io/badge/Level-%E4%B8%80%E8%88%AC-%23FF8C69"></img>
    - [@PostConstruct](spring-jsr/spring-jsr250-postConstruct/README.md):指定初始化方法。<img src="https://img.shields.io/badge/Level-%E4%B8%80%E8%88%AC-%23FF8C69"></img>
    - [@PreDestroy](spring-jsr/spring-jsr250-preDestroy/README.md):指定销毁方法。<img src="https://img.shields.io/badge/Level-%E4%B8%80%E8%88%AC-%23FF8C69"></img>
    - [Provider](spring-jsr/spring-jsr330-provider/README.md):Java标准库提供的通用Bean工厂接口。<img src="https://img.shields.io/badge/Level-%E4%B8%80%E8%88%AC-%23FF8C69"></img>

  + Spring AOP
    - [JDK动态代理](spring-aop/spring-aop-jdkProxy/README.md):接口实现,动态生成代理类,处理方法调用,统一横切关注点。<img src="https://img.shields.io/badge/Level-%E7%AE%80%E5%8D%95-0099ff"></img>
    - [Cglib动态代理](spring-aop/spring-aop-cglibProxy/README.md):基于字节码生成的库,无需接口,可拦截类方法并进行增强。<img src="https://img.shields.io/badge/Level-%E7%AE%80%E5%8D%95-0099ff"></img>
    - [ClassFilter](spring-aop/spring-aop-classFilter/README.md):确定类是否匹配拦截条件。<img src="https://img.shields.io/badge/Level-%E7%AE%80%E5%8D%95-0099ff"></img>
    - [MethodMatcher](spring-aop/spring-aop-methodMatcher/README.md):确定方法是否匹配拦截条件。<img src="https://img.shields.io/badge/Level-%E7%AE%80%E5%8D%95-0099ff"></img>
    - [Pointcut](spring-aop/spring-aop-pointcut/README.md):定义切入点,匹配被拦截的方法。<img src="https://img.shields.io/badge/Level-%E7%AE%80%E5%8D%95-0099ff"></img>
    - [Advice](spring-aop/spring-aop-advice/README.md):AOP中定义各种通知类型行为的核心接口。<img src="https://img.shields.io/badge/Level-%E7%AE%80%E5%8D%95-0099ff"></img>
      - [MethodInterceptor](spring-aop/spring-aop-advice-methodInterceptor/README.md):拦截方法执行,允许在前后添加额外逻辑。<img src="https://img.shields.io/badge/Level-%E7%AE%80%E5%8D%95-0099ff"></img>
      - [MethodBeforeAdvice](spring-aop/spring-aop-advice-methodBeforeAdvice/README.md):允许在方法调用之前插入自定义逻辑。<img src="https://img.shields.io/badge/Level-%E7%AE%80%E5%8D%95-0099ff"></img>
      - [AfterReturningAdvice](spring-aop/spring-aop-advice-afterReturningAdvice/README.md):允许在方法调用之后插入自定义逻辑。<<img src="https://img.shields.io/badge/Level-%E7%AE%80%E5%8D%95-0099ff"></img>
      - [ThrowsAdvice](spring-aop/spring-aop-advice-throwsAdvice/README.md):异常通知,捕获方法抛出的异常,执行额外逻辑。<img src="https://img.shields.io/badge/Level-%E7%AE%80%E5%8D%95-0099ff"></img>
      - [IntroductionInterceptor](spring-aop/spring-aop-advice-introductionInterceptor/README.md):动态地向目标对象引入新的功能或属性。<img src="https://img.shields.io/badge/Level-%E7%AE%80%E5%8D%95-0099ff"></img>
    - [Advisor](spring-aop/spring-aop-advisor/README.md):用于将通知和切点结合,实现切面编程的横切关注点。<img src="https://img.shields.io/badge/Level-%E7%AE%80%E5%8D%95-0099ff"></img>
    - [Advised](spring-aop/spring-aop-advised/README.md):配置AOP代理的通知、通知器、目标等。<img src="https://img.shields.io/badge/Level-%E7%AE%80%E5%8D%95-0099ff"></img>
    - [ProxyFactory](spring-aop/spring-aop-proxyFactory/README.md):一种便捷的方式来创建代理对象。<img src="https://img.shields.io/badge/Level-%E7%AE%80%E5%8D%95-0099ff"></img>
    - [AopProxyFactory](spring-aop/spring-aop-aopProxyFactory/README.md):创建AOP代理工厂,支持JDK和CGLIB。<img src="https://img.shields.io/badge/Level-%E4%B8%80%E8%88%AC-%23FF6347"></img>
    - [AopProxy](spring-aop/spring-aop-aopProxy/README.md):创建和管理AOP代理对象。<img src="https://img.shields.io/badge/Level-%E5%9B%B0%E9%9A%BE-%23FF3030"></img>
    - [AdvisorChainFactory](spring-aop/spring-aop-advisorChainFactory/README.md):创建Advisor链的工厂接口。<img src="https://img.shields.io/badge/Level-%E4%B8%80%E8%88%AC-%23FF6347"></img>
    - [AdvisorAdapterRegistry](spring-aop/spring-aop-advisorAdapterRegistry/README.md):适配各种Advice到AOP拦截器,注册和管理Advisor适配器。<img src="https://img.shields.io/badge/Level-%E4%B8%80%E8%88%AC-%23FF6347"></img>
    - [AdvisorAdapter](spring-aop/spring-aop-advisorAdapter/README.md):适配不同类型通知到拦截器链。<img src="https://img.shields.io/badge/Level-%E4%B8%80%E8%88%AC-%23FF6347"></img>
    - [ProxyMethodInvocation](spring-aop/spring-aop-proxyMethodInvocation/README.md):AOP方法调用代理,处理拦截器链和方法调用。<img src="https://img.shields.io/badge/Level-%E4%B8%80%E8%88%AC-%23FF6347"></img>
    - [@EnableAspectJAutoProxy](spring-aop/spring-aop-enableAspectJAutoProxy/README.md):启用AspectJ切面自动代理。<img src="https://img.shields.io/badge/Level-%E4%B8%80%E8%88%AC-%23FF6347"></img>
    - [AnnotationAwareAspectJAutoProxyCreator](spring-aop/spring-aop-annotationAwareAspectJAutoProxyCreator/README.md):创建AOP代理以应用AspectJ风格的切面。<img src="https://img.shields.io/badge/Level-%E5%9B%B0%E9%9A%BE-%23FF3030"></img>
    - [BeanFactoryAdvisorRetrievalHelper](spring-aop/spring-aop-beanFactoryAdvisorRetrievalHelper/README.md):帮助检索并管理Spring AOP 中的 Advisor Beans。<img src="https://img.shields.io/badge/Level-%E4%B8%80%E8%88%AC-%23FF6347"></img>
    - [BeanFactoryAspectJAdvisorsBuilder](spring-aop/spring-aop-beanFactoryAspectJAdvisorsBuilder/README.md):构建@AspectJ注解切面,生成Spring AOP Advisors。<img src="https://img.shields.io/badge/Level-%E4%B8%80%E8%88%AC-%23FF6347"></img>
    - [AspectInstanceFactory](spring-aop/spring-aop-aspectInstanceFactory/README.md):创建切面实例,支持多种实现方式。<img src="https://img.shields.io/badge/Level-%E4%B8%80%E8%88%AC-%23FF6347"></img>
    - [MetadataAwareAspectInstanceFactory](spring-aop/spring-aop-metadataAwareAspectInstanceFactory/README.md):管理切面实例和元数据,支持多种实例化策略。<img src="https://img.shields.io/badge/Level-%E4%B8%80%E8%88%AC-%23FF6347"></img>
    - [AspectJAdvisorFactory](spring-aop/spring-aop-aspectJAdvisorFactory/README.md):创建AspectJ通知器实例,管理切面通知的创建和配置。<img src="https://img.shields.io/badge/Level-%E5%9B%B0%E9%9A%BE-%23FF3030"></img>
    - [TargetSource](spring-aop/spring-aop-targetSource/README.md):管理AOP代理对象的获取与释放。<img src="https://img.shields.io/badge/Level-%E7%AE%80%E5%8D%95-0099ff"></img>
    - [TargetSourceCreator](spring-aop/spring-aop-targetSourceCreator/README.md):创建特殊的目标源,定制代理对象的创建和管理。<img src="https://img.shields.io/badge/Level-%E4%B8%80%E8%88%AC-%23FF6347"></img>
    - [AopContext](spring-aop/spring-aop-aopContext/README.md):获取Spring AOP代理对象的工具。<img src="https://img.shields.io/badge/Level-%E7%AE%80%E5%8D%95-0099ff"></img>
    - [ExposeInvocationInterceptor](spring-aop/spring-aop-exposeInvocationInterceptor/README.md):暴露Spring AOP方法调用上下文的拦截器。<img src="https://img.shields.io/badge/Level-%E7%AE%80%E5%8D%95-0099ff"></img>
    - [@EnableLoadTimeWeaving](spring-aop/spring-aop-enableLoadTimeWeaving/README.md):启用Spring加载时编织。<img src="https://img.shields.io/badge/Level-%E4%B8%80%E8%88%AC-%23FF6347"></img>
+ Spring 事务
  + [Connection](spring-transaction/spring-transaction-connection/README.md):管理数据库连接,执行SQL,处理事务。<img src="https://img.shields.io/badge/Level-%E7%AE%80%E5%8D%95-0099ff"></img>
  + [DataSource](spring-transaction/spring-transaction-dataSource/README.md):提供高效管理数据库连接的接口。<img src="https://img.shields.io/badge/Level-%E7%AE%80%E5%8D%95-0099ff"></img>
  + [DriverManager](spring-transaction/spring-transaction-driverManager/README.md):管理和建立数据库连接的核心类。<img src="https://img.shields.io/badge/Level-%E7%AE%80%E5%8D%95-0099ff"></img>
  + [JdbcTemplate](spring-transaction/spring-transaction-jdbcTemplate/README.md):简化了JDBC操作,提供了方便的数据库访问抽象。<img src="https://img.shields.io/badge/Level-%E7%AE%80%E5%8D%95-0099ff"></img>
  + [TransactionDefinition](spring-transaction/spring-transaction-transactionDefinition/README.md):定义事务的传播行为和隔离级别。<img src="https://img.shields.io/badge/Level-%E7%AE%80%E5%8D%95-0099ff"></img>
  + [TransactionAttributeSource](spring-transaction/spring-transaction-transactionAttributeSource/README.md):用于获取事务属性的策略接口。<img src="https://img.shields.io/badge/Level-%E7%AE%80%E5%8D%95-0099ff"></img>
  + [PlatformTransactionManager](spring-transaction/spring-transaction-platformTransactionManager/README.md):用于管理和协调事务的生命周期和执行。<img src="https://img.shields.io/badge/Level-%E5%9B%B0%E9%9A%BE-%23FF3030"></img>
  + [TransactionTemplate](spring-transaction/spring-transaction-transactionTemplate/README.md):简化事务管理,支持编程式事务控制与异常处理。<img src="https://img.shields.io/badge/Level-%E7%AE%80%E5%8D%95-0099ff"></img>
  + [SpringTransactionAnnotationParser](spring-transaction/spring-transaction-springTransactionAnnotationParser/README.md):解析 `@Transactional`注解并转换为事务配置。<img src="https://img.shields.io/badge/Level-%E7%AE%80%E5%8D%95-0099ff"></img>
  + [TransactionInterceptor](spring-transaction/spring-transaction-transactionInterceptor/README.md):事务拦截器,用于管理方法级别的事务处理。<img src="https://img.shields.io/badge/Level-%E4%B8%80%E8%88%AC-%23FF6347"></img>
  + [EnableTransactionManagement](spring-transaction/spring-transaction-enableTransactionManagement/README.md):启用Spring的注解驱动事务管理。<img src="https://img.shields.io/badge/Level-%E4%B8%80%E8%88%AC-%23FF6347"></img>

+ Spring MVC
+ Spring OpenFeign

## 💬与我联系

✉️ [Email](xuchengshengsuper@163.com) | 💬 [Issue](https://github.com/xuchengsheng/spring-reading/issues) | 🌐 [CSDN](https://blog.csdn.net/duzhuang2399?type=blog)  Me about everything!

## ⛵欢迎贡献!

如果你发现任何错误🔍或者有改进建议🛠️,欢迎提交 issue 或者 pull request。你的反馈📢对于我非常宝贵💎!

## 🔄持续更新中

为了给大家提供最新🌱、最有价值的内容💼,我会坚持每天更新这个仓库⏳。每一天,你都可以期待看到一些新的内容或者对已有内容的改进✨。如果你有任何建议或反馈📣,欢迎随时联系我📞。我非常珍视每一个反馈💌,因为这是我持续改进的动力🚀。

## ✨Star History

 <picture>
   <source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/svg?repos=xuchengsheng/spring-reading&type=Date&theme=dark" />
   <source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/svg?repos=xuchengsheng/spring-reading&type=Date" />
   <img alt="Star History Chart" src="https://api.star-history.com/svg?repos=xuchengsheng/spring-reading&type=Date" />
 </picture>

## 🎉Stargazers

[![Stargazers123 repo roster for @xuchengsheng/spring-reading](https://reporoster.com/stars/xuchengsheng/spring-reading)](https://github.com/xuchengsheng/spring-reading/stargazers)

## 🎉Forkers

[![Forkers repo roster for @xuchengsheng/spring-reading](https://reporoster.com/forks/xuchengsheng/spring-reading)](https://github.com/xuchengsheng/spring-reading/network/members)

## 🍱请我吃盒饭?

作者晚上还要写博客✍️,平时还需要工作💼,如果帮到了你可以请作者吃个盒饭🥡
<div>
<img alt="logo" src="image/WeChatPay.png" style="width: 260px;height: 280px">
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<img alt="logo" src="image/Alipay.png" style="width: 260px;height: 280px">
</div>

## 👥**关注公众号**

关注后,回复关键字 **“加群”**,即可加入我们的技术交流群,与更多开发者一起交流学习。

<div>
<img alt="logo" src="image/wechat-mp.png" style="height: 220px">
</div>


================================================
FILE: index.html
================================================
<table align="center">
    <tr align="center">
        <th>标题</th>
        <th>地址</th>
        <th>难度级别</th>
        <th>视频讲解</th>
    </tr>
    <tr align="center">
        <td><strong>【资源加载与访问】</strong></td>
        <td colspan="3"></td>
    </tr>
    <tr align="center">
        <td>资源加载</td>
        <td><a href="spring-resources/spring-resource/README.md">Resource</a></td>
        <td><img src="https://img.shields.io/badge/Level-%E7%AE%80%E5%8D%95-Green"/></td>
        <td>❌</td>
    </tr>
    <tr align="center">
        <td>资源加载器</td>
        <td><a href="spring-resources/spring-resource-resourceLoader/README.md">ResourceLoader</a></td>
        <td><img src="https://img.shields.io/badge/Level-%E7%AE%80%E5%8D%95-Green"/></td>
        <td>❌</td>
    </tr>
    <tr align="center">
        <td>XML资源加载器</td>
        <td><a href="spring-resources/spring-resource-documentLoader/README.md">DocumentLoader</a></td>
        <td><img src="https://img.shields.io/badge/Level-%E7%AE%80%E5%8D%95-Green"/></td>
        <td>❌</td>
    </tr>
    <tr align="center">
        <td><strong>【元数据与过滤】</strong></td>
        <td colspan="3"></td>
    </tr>
    <tr align="center">
        <td>类元数据读取</td>
        <td><a href="spring-metadata/spring-metadata-metadataReader/README.md">MetadataReader</a></td>
        <td><img src="https://img.shields.io/badge/Level-%E7%AE%80%E5%8D%95-Green"/></td>
        <td>❌</td>
    </tr>
    <tr align="center">
        <td>注解元数据</td>
        <td><a href="spring-metadata/spring-metadata-annotationMetadata/README.md">AnnotationMetadata</a></td>
        <td><img src="https://img.shields.io/badge/Level-%E7%AE%80%E5%8D%95-Green"/></td>
        <td>❌</td>
    </tr>
    <tr align="center">
        <td>类过滤器</td>
        <td><a href="spring-metadata/spring-metadata-typeFilter/README.md">TypeFilter</a></td>
        <td><img src="https://img.shields.io/badge/Level-%E7%AE%80%E5%8D%95-Green"/></td>
        <td>❌</td>
    </tr>
    <tr align="center">
        <td>条件过滤器</td>
        <td><a href="spring-metadata/spring-metadata-condition/README.md">Condition</a></td>
        <td><img src="https://img.shields.io/badge/Level-%E7%AE%80%E5%8D%95-Green"/></td>
        <td>❌</td>
    </tr>
    <tr align="center">
        <td><strong>【Bean定义与注册】</strong></td>
        <td colspan="3"></td>
    </tr>
    <tr align="center">
        <td>Bean定义</td>
        <td><a href="spring-beans/spring-bean-beanDefinition/README.md">BeanDefinition</a></td>
        <td><img src="https://img.shields.io/badge/Level-%E7%AE%80%E5%8D%95-Green"/></td>
        <td>❌</td>
    </tr>
    <tr align="center">
        <td>Bean定义持有者</td>
        <td><a href="spring-beans/spring-bean-beanDefinitionHolder/README.md">BeanDefinitionHolder</a></td>
        <td><img src="https://img.shields.io/badge/Level-%E7%AE%80%E5%8D%95-Green"/></td>
        <td>❌</td>
    </tr>
    <tr align="center">
        <td>Bean定义注册器</td>
        <td><a href="spring-beans/spring-bean-beanDefinitionRegistry/README.md">BeanDefinitionRegistry</a></td>
        <td><img src="https://img.shields.io/badge/Level-%E7%AE%80%E5%8D%95-Green"/></td>
        <td>❌</td>
    </tr>
    <tr align="center">
        <td><strong>【Bean定义读取与扫描】</strong></td>
        <td colspan="3"></td>
    </tr>
    <tr align="center">
        <td>XML Bean定义读取器</td>
        <td><a href="spring-beans/spring-bean-xmlBeanDefinitionReader/README.md">XmlBeanDefinitionReader</a></td>
        <td><img src="https://img.shields.io/badge/Level-%E7%AE%80%E5%8D%95-Green"/></td>
        <td>❌</td>
    </tr>
    <tr align="center">
        <td>属性文件Bean定义读取器</td>
        <td><a href="spring-beans/spring-bean-propertiesBeanDefinitionReader/README.md">PropertiesBeanDefinitionReader</a></td>
        <td><img src="https://img.shields.io/badge/Level-%E7%AE%80%E5%8D%95-Green"/></td>
        <td>❌</td>
    </tr>
    <tr align="center">
        <td>Groovy脚本Bean定义读取器</td>
        <td><a href="spring-beans/spring-bean-groovyBeanDefinitionReader/README.md">GroovyBeanDefinitionReader</a></td>
        <td><img src="https://img.shields.io/badge/Level-%E7%AE%80%E5%8D%95-Green"/></td>
        <td>❌</td>
    </tr>
    <tr align="center">
        <td>注解Bean定义读取器</td>
        <td><a href="spring-beans/spring-bean-annotatedBeanDefinitionReader/README.md">AnnotatedBeanDefinitionReader</a></td>
        <td><img src="https://img.shields.io/badge/Level-%E4%B8%80%E8%88%AC-blue"/></td>
        <td>❌</td>
    </tr>
    <tr align="center">
        <td>类路径Bean定义扫描器</td>
        <td><a href="spring-beans/spring-bean-classPathBeanDefinitionScanner/README.md">ClassPathBeanDefinitionScanner</a></td>
        <td><img src="https://img.shields.io/badge/Level-%E4%B8%80%E8%88%AC-blue"/></td>
        <td>❌</td>
    </tr>
    <tr align="center">
        <td><strong>【Bean生命周期过程】</strong></td>
        <td colspan="3"></td>
    </tr>
    <tr align="center">
        <td>Bean的定义解析</td>
        <td><a href="#">Bean的定义解析</a></td>
        <td><img src="https://img.shields.io/badge/Level-%E4%B8%80%E8%88%AC-blue"/></td>
        <td>❌</td>
    </tr>
    <tr align="center">
        <td>Bean的初始化过程</td>
        <td><a href="spring-core/spring-core-getBean/README.md">Bean的初始化过程</a></td>
        <td><img src="https://img.shields.io/badge/Level-%E5%9B%B0%E9%9A%BE-orange"/></td>
        <td>❌</td>
    </tr>
    <tr align="center">
        <td>Bean的依赖解析过程</td>
        <td><a href="spring-core/spring-core-resolveDependency/README.md">Bean的依赖解析过程</a></td>
        <td><img src="https://img.shields.io/badge/Level-%E5%9B%B0%E9%9A%BE-orange"/></td>
        <td>❌</td>
    </tr>
    <tr align="center">
        <td>Bean的销毁过程</td>
        <td><a href="#">Bean的销毁过程</a></td>
        <td><img src="https://img.shields.io/badge/Level-%E4%B8%80%E8%88%AC-blue"/></td>
        <td>❌</td>
    </tr>
    <tr align="center">
        <td><strong>【后置处理器与初始化】</strong></td>
        <td colspan="3"></td>
    </tr>
    <tr align="center">
        <td>属性设置后的初始化操作</td>
        <td><a href="spring-interface/spring-interface-initializingBean/README.md">InitializingBean</a></td>
        <td><img src="https://img.shields.io/badge/Level-%E4%B8%80%E8%88%AC-blue"/></td>
        <td>❌</td>
    </tr>
    <tr align="center">
        <td>资源清理与销毁</td>
        <td><a href="spring-interface/spring-interface-disposableBean/README.md">DisposableBean</a></td>
        <td><img src="https://img.shields.io/badge/Level-%E4%B8%80%E8%88%AC-blue"/></td>
        <td>❌</td>
    </tr>
    <tr align="center">
        <td>动态修改Bean定义</td>
        <td><a href="spring-interface/spring-interface-beanDefinitionRegistryPostProcessor/README.md">BeanDefinitionRegistryPostProcessor</a></td>
        <td><img src="https://img.shields.io/badge/Level-%E4%B8%80%E8%88%AC-blue"/></td>
        <td>❌</td>
    </tr>
    <tr align="center">
        <td>动态调整Bean配置</td>
        <td><a href="spring-interface/spring-interface-beanFactoryPostProcessor/README.md">BeanFactoryPostProcessor</a></td>
        <td><img src="https://img.shields.io/badge/Level-%E4%B8%80%E8%88%AC-blue"/></td>
        <td>❌</td>
    </tr>
    <tr align="center">
        <td>调整Bean属性</td>
        <td><a href="spring-interface/spring-interface-beanPostProcessor/README.md">BeanPostProcessor</a></td>
        <td><img src="https://img.shields.io/badge/Level-%E4%B8%80%E8%88%AC-blue"/></td>
        <td>❌</td>
    </tr>
    <tr align="center">
        <td>Bean实例拦截</td>
        <td><a href="spring-interface/spring-interface-instantiationAwareBeanPostProcessor/README.md">InstantiationAwareBeanPostProcessor</a></td>
        <td><img src="https://img.shields.io/badge/Level-%E4%B8%80%E8%88%AC-blue"/></td>
        <td>❌</td>
    </tr>
    <tr align="center">
        <td>Bean销毁生命周期</td>
        <td><a href="spring-interface/spring-interface-destructionAwareBeanPostProcessor/README.md">DestructionAwareBeanPostProcessor</a></td>
        <td><img src="https://img.shields.io/badge/Level-%E4%B8%80%E8%88%AC-blue"/></td>
        <td>❌</td>
    </tr>
    <tr align="center">
        <td>Bean定义的动态处理</td>
        <td><a href="spring-interface/spring-interface-mergedBeanDefinitionPostProcessor/README.md">MergedBeanDefinitionPostProcessor</a></td>
        <td><img src="https://img.shields.io/badge/Level-%E4%B8%80%E8%88%AC-blue"/></td>
        <td>❌</td>
    </tr>
    <tr align="center">
        <td>调整Bean实例化策略</td>
        <td><a href="spring-interface/spring-interface-smartInstantiationAwareBeanPostProcessor/README.md">SmartInstantiationAwareBeanPostProcessor</a></td>
        <td><img src="https://img.shields.io/badge/Level-%E4%B8%80%E8%88%AC-blue"/></td>
        <td>❌</td>
    </tr>
    <tr align="center">
        <td>All Beans完全初始化后</td>
        <td><a href="spring-interface/spring-interface-smartInitializingSingleton/README.md">SmartInitializingSingleton</a></td>
        <td><img src="https://img.shields.io/badge/Level-%E4%B8%80%E8%88%AC-blue"/></td>
        <td>❌</td>
    </tr>
    <tr align="center">
        <td><strong>【Aware接口】</strong></td>
        <td colspan="3"></td>
    </tr>
    <tr align="center">
        <td>获取Bean名称</td>
        <td><a href="spring-aware/spring-aware-beanNameAware/README.md">BeanNameAware</a></td>
        <td><img src="https://img.shields.io/badge/Level-%E4%B8%80%E8%88%AC-blue"/></td>
        <td>❌</td>
    </tr>
    <tr align="center">
        <td>获取类加载器</td>
        <td><a href="spring-aware/spring-aware-beanClassLoaderAware/README.md">BeanClassLoaderAware</a></td>
        <td><img src="https://img.shields.io/badge/Level-%E4%B8%80%E8%88%AC-blue"/></td>
        <td>❌</td>
    </tr>
    <tr align="center">
        <td>与Bean工厂互动</td>
        <td><a href="spring-aware/spring-aware-beanFactoryAware/README.md">BeanFactoryAware</a></td>
        <td><img src="https://img.shields.io/badge/Level-%E4%B8%80%E8%88%AC-blue"/></td>
        <td>❌</td>
    </tr>
    <tr align="center">
        <td>感知运行环境</td>
        <td><a href="spring-aware/spring-aware-environmentAware/README.md">EnvironmentAware</a></td>
        <td><img src="https://img.shields.io/badge/Level-%E4%B8%80%E8%88%AC-blue"/></td>
        <td>❌</td>
    </tr>
    <tr align="center">
        <td>嵌入值解析</td>
        <td><a href="spring-aware/spring-aware-embeddedValueResolverAware/README.md">EmbeddedValueResolverAware</a></td>
        <td><img src="https://img.shields.io/badge/Level-%E4%B8%80%E8%88%AC-blue"/></td>
        <td>❌</td>
    </tr>
    <tr align="center">
        <td>资源加载策略</td>
        <td><a href="spring-aware/spring-aware-resourceLoaderAware/README.md">ResourceLoaderAware</a></td>
        <td><img src="https://img.shields.io/badge/Level-%E4%B8%80%E8%88%AC-blue"/></td>
        <td>❌</td>
    </tr>
    <tr align="center">
        <td>发布应用事件</td>
        <td><a href="spring-aware/spring-aware-applicationEventPublisherAware/README.md">ApplicationEventPublisherAware</a></td>
        <td><img src="https://img.shields.io/badge/Level-%E4%B8%80%E8%88%AC-blue"/></td>
        <td>❌</td>
    </tr>
    <tr align="center">
        <td>访问消息源</td>
        <td><a href="spring-aware/spring-aware-messageSourceAware/README.md">MessageSourceAware</a></td>
        <td><img src="https://img.shields.io/badge/Level-%E4%B8%80%E8%88%AC-blue"/></td>
        <td>❌</td>
    </tr>
    <tr align="center">
        <td>感知应用启动过程</td>
        <td><a href="spring-aware/spring-aware-applicationStartupAware/README.md">ApplicationStartupAware</a></td>
        <td><img src="https://img.shields.io/badge/Level-%E4%B8%80%E8%88%AC-blue"/></td>
        <td>❌</td>
    </tr>
    <tr align="center">
        <td>访问应用上下文</td>
        <td><a href="spring-aware/spring-aware-applicationContextAware/README.md">ApplicationContextAware</a></td>
        <td><img src="https://img.shields.io/badge/Level-%E4%B8%80%E8%88%AC-blue"/></td>
        <td>❌</td>
    </tr>
    <tr align="center">
        <td>了解关联导入信息</td>
        <td><a href="spring-aware/spring-aware-importAware/README.md">ImportAware</a></td>
        <td><img src="https://img.shields.io/badge/Level-%E4%B8%80%E8%88%AC-blue"/></td>
        <td>❌</td>
    </tr>
    <tr align="center">
        <td><strong>【核心注解】</strong></td>
        <td colspan="3"></td>
    </tr>
    <tr align="center">
        <td>Java配置</td>
        <td><a href="spring-annotation/spring-annotation-configuration/README.md">@Configuration</a></td>
        <td><img src="https://img.shields.io/badge/Level-%E5%9B%B0%E9%9A%BE-orange"/></td>
        <td>❌</td>
    </tr>
    <tr align="center">
        <td>组件扫描</td>
        <td><a href="spring-annotation/spring-annotation-componentScan/README.md">@ComponentScan</a></td>
        <td><img src="https://img.shields.io/badge/Level-%E5%9B%B0%E9%9A%BE-orange"/></td>
        <td>❌</td>
    </tr>
    <tr align="center">
        <td>Bean定义</td>
        <td><a href="spring-annotation/spring-annotation-bean/README.md">@Bean</a></td>
        <td><img src="https://img.shields.io/badge/Level-%E5%9B%B0%E9%9A%BE-orange"/></td>
        <td>❌</td>
    </tr>
    <tr align="center">
        <td>导入配置</td>
        <td><a href="spring-annotation/spring-annotation-import/README.md">@Import</a></td>
        <td><img src="https://img.shields.io/badge/Level-%E5%9B%B0%E9%9A%BE-orange"/></td>
        <td>❌</td>
    </tr>
    <tr align="center">
        <td>属性绑定</td>
        <td><a href="spring-annotation/spring-annotation-propertySource/README.md">@PropertySource</a></td>
        <td><img src="https://img.shields.io/badge/Level-%E5%9B%B0%E9%9A%BE-orange"/></td>
        <td>❌</td>
    </tr>
    <tr align="center">
        <td>初始化顺序</td>
        <td><a href="spring-annotation/spring-annotation-dependsOn/README.md">@DependsOn</a></td>
        <td><img src="https://img.shields.io/badge/Level-%E5%9B%B0%E9%9A%BE-orange"/></td>
        <td>❌</td>
    </tr>
    <tr align="center">
        <td>条件注册</td>
        <td><a href="spring-annotation/spring-annotation-conditional/README.md">@Conditional</a></td>
        <td><img src="https://img.shields.io/badge/Level-%E5%9B%B0%E9%9A%BE-orange"/></td>
        <td>❌</td>
    </tr>
    <tr align="center">
        <td>延迟加载</td>
        <td><a href="spring-annotation/spring-annotation-lazy/README.md">@Lazy</a></td>
        <td><img src="https://img.shields.io/badge/Level-%E5%9B%B0%E9%9A%BE-orange"/></td>
        <td>❌</td>
    </tr>
    <tr align="center">
        <td>属性注入</td>
        <td><a href="spring-annotation/spring-annotation-value/README.md">@Value</a></td>
        <td><img src="https://img.shields.io/badge/Level-%E5%9B%B0%E9%9A%BE-orange"/></td>
        <td>❌</td>
    </tr>
    <tr align="center">
        <td>依赖注入</td>
        <td><a href="spring-annotation/spring-annotation-autowired/README.md">@Autowired</a></td>
        <td><img src="https://img.shields.io/badge/Level-%E5%9B%B0%E9%9A%BE-orange"/></td>
        <td>❌</td>
    </tr>
    <tr align="center">
        <td>注入依赖</td>
        <td><a href="spring-jsr/spring-jsr330-inject/README.md">@Inject</a></td>
        <td><img src="https://img.shields.io/badge/Level-%E5%9B%B0%E9%9A%BE-orange"/></td>
        <td>❌</td>
    </tr>
    <tr align="center">
        <td>具名组件</td>
        <td><a href="spring-jsr/spring-jsr330-named/README.md">@Named</a></td>
        <td><img src="https://img.shields.io/badge/Level-%E5%9B%B0%E9%9A%BE-orange"/></td>
        <td>❌</td>
    </tr>
    <tr align="center">
        <td>初始化后操作</td>
        <td><a href="spring-jsr/spring-jsr250-postConstruct/README.md">@PostConstruct</a></td>
        <td><img src="https://img.shields.io/badge/Level-%E5%9B%B0%E9%9A%BE-orange"/></td>
        <td>❌</td>
    </tr>
    <tr align="center">
        <td>销毁前操作</td>
        <td><a href="spring-jsr/spring-jsr250-preDestroy/README.md">@PreDestroy</a></td>
        <td><img src="https://img.shields.io/badge/Level-%E5%9B%B0%E9%9A%BE-orange"/></td>
        <td>❌</td>
    </tr>
    <tr align="center">
        <td>资源绑定</td>
        <td><a href="spring-jsr/spring-jsr250-resource/README.md">@Resource</a></td>
        <td><img src="https://img.shields.io/badge/Level-%E5%9B%B0%E9%9A%BE-orange"/></td>
        <td>❌</td>
    </tr>
    <tr align="center">
        <td>提供者机制</td>
        <td><a href="spring-jsr/spring-jsr330-provider/README.md">Provider</a></td>
        <td><img src="https://img.shields.io/badge/Level-%E5%9B%B0%E9%9A%BE-orange"/></td>
        <td>❌</td>
    </tr>
    <tr align="center">
        <td>限定符</td>
        <td><a href="spring-jsr/spring-jsr330-qualifier/README.md">@Qualifier</a></td>
        <td><img src="https://img.shields.io/badge/Level-%E5%9B%B0%E9%9A%BE-orange"/></td>
        <td>❌</td>
    </tr>
    <tr align="center">
        <td>作用域定义</td>
        <td><a href="spring-jsr/spring-jsr330-scope/README.md">@Scope</a></td>
        <td><img src="https://img.shields.io/badge/Level-%E5%9B%B0%E9%9A%BE-orange"/></td>
        <td>❌</td>
    </tr>
    <tr align="center">
        <td>单例模式</td>
        <td><a href="spring-jsr/spring-jsr330-singleton/README.md">@Singleton</a></td>
        <td><img src="https://img.shields.io/badge/Level-%E5%9B%B0%E9%9A%BE-orange"/></td>
        <td>❌</td>
    </tr>
    <tr align="center">
        <td>定义主要候选项</td>
        <td>@Primary</td>
        <td><img src="https://img.shields.io/badge/Level-%E5%9B%B0%E9%9A%BE-orange"/></td>
        <td>❌</td>
    </tr>
    <tr align="center">
        <td>添加描述信息</td>
        <td>@Description</td>
        <td><img src="https://img.shields.io/badge/Level-%E5%9B%B0%E9%9A%BE-orange"/></td>
        <td>❌</td>
    </tr>
    <tr align="center">
        <td>指定注解角色</td>
        <td>@Role</td>
        <td><img src="https://img.shields.io/badge/Level-%E5%9B%B0%E9%9A%BE-orange"/></td>
        <td>❌</td>
    </tr>
    <tr align="center">
        <td>标记为可索引</td>
        <td>@Indexed</td>
        <td><img src="https://img.shields.io/badge/Level-%E5%9B%B0%E9%9A%BE-orange"/></td>
        <td>❌</td>
    </tr>
    <tr align="center">
        <td>指定顺序</td>
        <td>@Order</td>
        <td><img src="https://img.shields.io/badge/Level-%E5%9B%B0%E9%9A%BE-orange"/></td>
        <td>❌</td>
    </tr>
</table>

================================================
FILE: pom.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">

    <modelVersion>4.0.0</modelVersion>
    <packaging>pom</packaging>
    <groupId>com.xcs.spring</groupId>
    <artifactId>spring-reading</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>spring-reading</name>
    <description>spring-reading</description>

    <properties>
        <maven.compiler.source>11</maven.compiler.source>
        <maven.compiler.target>11</maven.compiler.target>
        <java.version>11</java.version>
        <spring.version>5.2.15.RELEASE</spring.version>
        <mysql.version>8.0.30</mysql.version>
        <spring.boot.version>2.3.12.RELEASE</spring.boot.version>
    </properties>

    <modules>
        <module>spring-annotation</module>
        <module>spring-aware</module>
        <module>spring-interface</module>
        <module>spring-jsr</module>
        <module>spring-core</module>
        <module>spring-aop</module>
        <module>spring-mvc</module>
        <module>spring-resources</module>
        <module>spring-metadata</module>
        <module>spring-beans</module>
        <module>spring-context</module>
        <module>spring-factory</module>
        <module>spring-env</module>
        <module>spring-dataops</module>
        <module>spring-spel</module>
        <module>spring-transaction</module>
    </modules>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <version>${spring.boot.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
            <version>${spring.boot.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
            <version>${spring.boot.version}</version>
        </dependency>
    </dependencies>

</project>


================================================
FILE: spring-annotation/pom.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>spring-reading</artifactId>
        <groupId>com.xcs.spring</groupId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>

    <modelVersion>4.0.0</modelVersion>
    <artifactId>spring-annotation</artifactId>
    <packaging>pom</packaging>

    <modules>
        <module>spring-annotation-configuration</module>
        <module>spring-annotation-bean</module>
        <module>spring-annotation-import</module>
        <module>spring-annotation-propertySource</module>
        <module>spring-annotation-componentScan</module>
        <module>spring-annotation-dependsOn</module>
        <module>spring-annotation-lazy</module>
        <module>spring-annotation-conditional</module>
        <module>spring-annotation-value</module>
        <module>spring-annotation-autowired</module>
        <module>spring-annotation-profile</module>
    </modules>

</project>

================================================
FILE: spring-annotation/spring-annotation-autowired/README.md
================================================
## @Autowired

- [@Autowired](#autowired)
  - [一、基本信息](#一基本信息)
  - [二、注解描述](#二注解描述)
  - [三、接口源码](#三接口源码)
  - [四、主要功能](#四主要功能)
  - [五、最佳实践](#五最佳实践)
  - [六、时序图](#六时序图)
  - [七、源码分析](#七源码分析)
    - [前置条件](#前置条件)
    - [收集阶段](#收集阶段)
    - [注入阶段](#注入阶段)
  - [八、注意事项](#八注意事项)
  - [九、总结](#九总结)
    - [最佳实践总结](#最佳实践总结)
    - [源码分析总结](#源码分析总结)


### 一、基本信息

✒️ **作者** - Lex 📝 **博客** - [我的CSDN](https://blog.csdn.net/duzhuang2399/article/details/133833938) 📚 **文章目录** - [所有文章](https://github.com/xuchengsheng/spring-reading) 🔗 **源码地址** - [@Autowired源码](https://github.com/xuchengsheng/spring-reading/tree/master/spring-annotation/spring-annotation-autowired)

### 二、注解描述

`@Autowired` 注解,用于实现依赖注入(Dependency Injection, DI)。当我们在 Spring 中定义了一个 Bean 并想要使用另一个 Bean 时,可以使用 `@Autowired` 注解来自动注入所需的 Bean,而我们无需手动查找和配置它。

### 三、接口源码

`@Autowired`注解是 Spring 框架自 2.5 版本开始引入的一个核心注解,该注解用于告知 Spring 框架的依赖注入工具自动注入所需的依赖。

```java
/**
 * 通过Spring的依赖注入机制标记构造函数、字段、setter方法或配置方法。
 * 这是JSR-330 Inject 注解的一种替代,增加了必需与可选的语义。
 *
 * 自动注入的构造函数:
 * 任何给定的bean类只有一个构造函数可以声明此注解,且其required属性设置为 true,
 * 表示当作为Spring bean使用时要自动注入的构造函数。如果required属性设置为true,
 * 则只能有一个构造函数被标记为Autowired。如果多个非必需的构造函数声明了这个注解,
 * 它们都会被视为自动注入的候选者。Spring会选择可以满足最多依赖的构造函数进行注入。如果没有一个候选者满足条件,
 * 则会使用默认的构造函数。如果一个类声明了多个构造函数,但没有一个使用Autowired,
 * 则会使用默认的构造函数。如果一个类从一开始就只声明了一个构造函数,它总是会被使用,即使没有被标记。被标记的构造函数不需要是public的。
 *
 * 自动注入的字段:
 * 字段会在bean构造完成后注入,任何配置方法调用之前。配置字段不需要是public的。
 *
 * 自动注入的方法:
 * 配置方法可以有任意名称和任意数量的参数;其中每一个参数都会通过Spring容器中的一个匹配的bean进行自动注入。
 * Bean属性的setter方法在实质上只是这种通用配置方法的一个特例。这些配置方法不需要是public的。
 *
 * 自动注入的参数:
 * 尽管从Spring 5.0开始Autowired可以在方法或构造函数的单独参数上声明,
 * 但框架的大部分都会忽略这样的声明。唯一支持自动注入参数的Spring核心部分是
 * spring-test模块中的JUnit Jupiter支持。
 *
 * 多参数与'required'语义:
 * 对于多参数的构造函数或方法,required属性适用于所有参数。
 *
 * 自动装配数组、集合和映射:
 * 对于数组、Collection或Map类型的依赖,容器会自动注入所有匹配声明的值类型的bean。
 * 对于这种目的,map的键必须声明为类型String,它会解析为相应的bean名称。
 *
 * 在BeanPostProcessor或BeanFactoryPostProcessor中不支持:
 * 请注意,实际的注入是通过BeanPostProcessor执行的,这意味着我们不能使用Autowired在
 * BeanPostProcessor或BeanFactoryPostProcessor类型中进行注入。
 *
 * @author Juergen Hoeller
 * @author Mark Fisher
 * @author Sam Brannen
 * @since 2.5
 * @see AutowiredAnnotationBeanPostProcessor
 * @see Qualifier
 * @see Value
 */
@Target({ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Autowired {

    /**
     * 声明注解的依赖是否是必需的。
     * 默认值为true。
     */
    boolean required() default true;
}
```

### 四、主要功能

1. **自动注入依赖**
   + 不需要明确指定 bean 之间的关系,Spring 会自动找到并注入所需的依赖。
2. **字段注入**
   + 可以直接标记在类的字段上,使得该字段在 Bean 初始化时被自动注入。
3. **构造函数注入**
   + 当标记在构造函数上时,该构造函数会被用于创建 bean 实例并注入所需的依赖。
4. **方法注入**
   + 当标记在 setter 方法或其他方法上时,这些方法会在 Bean 初始化时被调用以注入依赖。
5. **指定必需性**
   + 通过 `required` 属性,可以指定某个依赖是否是必需的。如果标记为必需但没有找到相应的依赖,Spring 会抛出异常。

### 五、最佳实践

首先来看看启动类入口,上下文环境使用`AnnotationConfigApplicationContext`(此类是使用Java注解来配置Spring容器的方式),构造参数我们给定了一个`MyConfiguration`组件类。然后从Spring上下文中获取一个`MyController`类型的bean并调用了`showService`方法,

```java
public class AutowiredApplication {

    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MyConfiguration.class);
        MyController controller = context.getBean(MyController.class);
        controller.showService();
    }
}
```

在`MyConfiguration`类中,使用了`@ComponentScan("com.xcs.spring")`注解告诉 Spring 在指定的包(在这里是 "`com.xcs.spring`")及其子包中搜索带有 `@Component`、`@Service`、`@Repository` 和 `@Controller` 等注解的类,并将它们自动注册为 beans。这样,spring就不必为每个组件明确写一个 bean 定义。Spring 会自动识别并注册它们。

```java
@Configuration
@ComponentScan("com.xcs.spring")
public class MyConfiguration {

}
```

 Spring 容器在初始化 `MyController` 时自动注入一个 `MyService` 类型的 bean 到 `myService` 字段。

```java
@Controller
public class MyController {

    @Autowired
    private MyService myService;

    public void showService(){
        System.out.println("myService = " + myService);
    }
}
```

`MyService` 是一个简单的服务类,但我们没有定义任何方法或功能。

```java
@Service
public class MyService {
    
}
```

运行结果发现,我们使用 `@Autowired` 注解的功能,在我们的 Spring 上下文中工作正常,并且它成功地自动注入了所需的依赖关系。

```java
myService = com.xcs.spring.service.MyService@4a883b15
```

### 六、时序图

~~~mermaid
sequenceDiagram
Title: @Autowired注解时序图
AbstractAutowireCapableBeanFactory->>AbstractAutowireCapableBeanFactory:applyMergedBeanDefinitionPostProcessors(mbd,beanType,beanName)<br>应用Bean定义的后置处理器
AbstractAutowireCapableBeanFactory->>AutowiredAnnotationBeanPostProcessor:postProcessMergedBeanDefinition(beanDefinition,beanType,beanName)<br>处理已合并的Bean定义
AutowiredAnnotationBeanPostProcessor->>AutowiredAnnotationBeanPostProcessor:findAutowiringMetadata(beanName,clazz,pvs)<br>查找自动注入的元数据
AutowiredAnnotationBeanPostProcessor->>AutowiredAnnotationBeanPostProcessor:buildAutowiringMetadata(clazz)<br>构建自动注入的元数据
AutowiredAnnotationBeanPostProcessor->>ReflectionUtils:doWithLocalFields(clazz,fc)<br>处理类的本地字段
ReflectionUtils->>AutowiredAnnotationBeanPostProcessor:解析有@Autowired注解的字段
AutowiredAnnotationBeanPostProcessor->>ReflectionUtils:doWithLocalMethods(clazz,fc)<br>处理类的本地方法
ReflectionUtils->>AutowiredAnnotationBeanPostProcessor:解析有@Autowired注解的方法
AutowiredAnnotationBeanPostProcessor->>AutowiredAnnotationBeanPostProcessor:injectionMetadataCache.put(cacheKey, metadata)<br>将元数据存入缓存
AbstractAutowireCapableBeanFactory->>AbstractAutowireCapableBeanFactory:populateBean(beanName,mbd,bw)<br>填充Bean的属性值
AbstractAutowireCapableBeanFactory->>AutowiredAnnotationBeanPostProcessor:postProcessProperties(pvs,bean,beanName)<br>后处理Bean的属性
AutowiredAnnotationBeanPostProcessor->>AutowiredAnnotationBeanPostProcessor:findAutowiringMetadata(beanName,clazz,pvs)<br>再次查找自动注入的元数据
Note right of AutowiredAnnotationBeanPostProcessor:<br>从缓存中获取注入的元数据
AutowiredAnnotationBeanPostProcessor->>InjectionMetadata:inject(bean, beanName, pvs)<br>执行实际的属性注入
InjectionMetadata->>AutowiredFieldElement:inject(target, beanName, pvs)<br>注入特定的字段元素
AutowiredFieldElement->>AutowiredFieldElement:resolveFieldValue(field,bean,beanName)<br>解析字段的值
AutowiredFieldElement->>DefaultListableBeanFactory:resolveDependency(desc, beanName, autowiredBeanNames, typeConverter)<br>解析字段的依赖
DefaultListableBeanFactory->>DefaultListableBeanFactory:doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter)<br>解析指定的依赖关系
DefaultListableBeanFactory->>DefaultListableBeanFactory:findAutowireCandidates(beanName, type, descriptor)<br>查找符合自动装配条件的候选 Bean
DefaultListableBeanFactory->>DefaultListableBeanFactory:addCandidateEntry(result, candidate, descriptor, requiredType)<br>向结果集中添加候选 Bean
DefaultListableBeanFactory->>AbstractBeanFactory:getType(name)<br>获取指定 Bean 的类型
AbstractBeanFactory->>DefaultListableBeanFactory:返回被依赖Bean的类<br>返回依赖 Bean 的实际类
DefaultListableBeanFactory->>DependencyDescriptor:resolveCandidate(beanName, requiredType, beanFactory)<br>解析候选的依赖 Bean
DependencyDescriptor->>AbstractBeanFactory:getBean(name)<br>获取指定的 Bean 实例
AbstractBeanFactory->>DependencyDescriptor:<br>返回具体的依赖 Bean 实例
DependencyDescriptor->>DefaultListableBeanFactory:<br>返回依赖的 Bean 实例给工厂
DefaultListableBeanFactory->>AutowiredFieldElement:<br>返回依赖的 Bean 给字段注入器
AutowiredFieldElement->>Field:field.set(bean, value)<br>实际设置 Bean 的字段值
~~~

### 七、源码分析

#### 前置条件

在Spring中,`AutowiredAnnotationBeanPostProcessor`是处理`@Autowired`等注解的关键类,它实现了下述两个接口。因此,为了深入理解`@Autowired`的工作方式,研究这个类是非常有用的。简而言之,为了完全理解`@Autowired`的工作机制,了解下述接口确实是必要的。这两个接口提供了对bean生命周期中关键阶段的干预,从而允许进行属性注入和其他相关的操作。

1. `MergedBeanDefinitionPostProcessor`接口
   - 此接口提供的`postProcessMergedBeanDefinition`方法允许后处理器修改合并后的bean定义。合并后的bean定义是一个已经考虑了所有父bean定义属性的bean定义。对于`@Autowired`注解的处理,这一步通常涉及到收集需要被解析的`@Autowired`注解信息并准备对其进行后续处理。
   - 🔗 [MergedBeanDefinitionPostProcessor接口传送门](https://github.com/xuchengsheng/spring-reading/tree/master/spring-interface/spring-interface-mergedBeanDefinitionPostProcessor)
2. `InstantiationAwareBeanPostProcessor`接口
   - 此接口提供了几个回调方法,允许后处理器在bean实例化之前和实例化之后介入bean的创建过程。特别是,`postProcessProperties`方法允许后处理器对bean的属性进行操作。对于`@Autowired`注解,这通常需要在属性设置或依赖注入阶段对 bean 进行处理,并将解析得到的值注入到bean中。
   - 🔗 [InstantiationAwareBeanPostProcessor接口传送门](https://github.com/xuchengsheng/spring-reading/tree/master/spring-interface/spring-interface-instantiationAwareBeanPostProcessor)

#### 收集阶段

在`org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor#postProcessMergedBeanDefinition`方法中,主要确保给定的bean定义与其预期的自动装配元数据一致。

```java
@Override
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
    // 对于给定的bean名称和类型,它首先尝试查找相关的InjectionMetadata,这可能包含了该bean的字段和方法的注入信息
    InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null);
    
    // 使用找到的InjectionMetadata来验证bean定义中的配置成员是否与预期的注入元数据匹配。
    metadata.checkConfigMembers(beanDefinition);
}
```

在`org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor#findAutowiringMetadata`方法中,确保了始终为给定的bean名称和类获取最新和相关的`InjectionMetadata`,并利用缓存机制优化性能。

```java
private InjectionMetadata findAutowiringMetadata(String beanName, Class<?> clazz, @Nullable PropertyValues pvs) {
    // 如果beanName为空,则使用类名作为缓存键。
    String cacheKey = (StringUtils.hasLength(beanName) ? beanName : clazz.getName());
    // 首先尝试从并发缓存中获取InjectionMetadata。
    InjectionMetadata metadata = this.injectionMetadataCache.get(cacheKey);
    // 检查获取到的元数据是否需要刷新。
    if (InjectionMetadata.needsRefresh(metadata, clazz)) {
        // 使用双重检查锁定确保线程安全。
        synchronized (this.injectionMetadataCache) {
            metadata = this.injectionMetadataCache.get(cacheKey);
            if (InjectionMetadata.needsRefresh(metadata, clazz)) {
                // 如果有旧的元数据,清除它。
                if (metadata != null) {
                    metadata.clear(pvs);
                }
                // 为给定的类构建新的InjectionMetadata。
                metadata = buildAutowiringMetadata(clazz);
                // 将新构建的元数据更新到缓存中。
                this.injectionMetadataCache.put(cacheKey, metadata);
            }
        }
    }
    // 返回找到的或新构建的元数据。
    return metadata;
}
```

在`org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor#buildAutowiringMetadata`方法中,查找类及其所有父类中的字段和方法,以找出所有带有自动装配注解的字段和方法,并为它们创建一个统一的`InjectionMetadata`对象。

```java
private InjectionMetadata buildAutowiringMetadata(final Class<?> clazz) {
    // 检查类是否含有自动装配注解,若无则直接返回空的InjectionMetadata。
    if (!AnnotationUtils.isCandidateClass(clazz, this.autowiredAnnotationTypes)) {
        return InjectionMetadata.EMPTY;
    }

    // 初始化存放注入元素的列表。
    List<InjectionMetadata.InjectedElement> elements = new ArrayList<>();
    Class<?> targetClass = clazz;

    do {
        // 当前类中要注入的元素列表。
        final List<InjectionMetadata.InjectedElement> currElements = new ArrayList<>();

        // 处理类中的所有字段。
        ReflectionUtils.doWithLocalFields(targetClass, field -> {
            // 查找字段上的自动装配注解。
            MergedAnnotation<?> ann = findAutowiredAnnotation(field);
            if (ann != null) {
                
                // ... [代码部分省略以简化]
                
                boolean required = determineRequiredStatus(ann);
                // 创建一个新的AutowiredFieldElement并加入到列表。
                currElements.add(new AutowiredFieldElement(field, required));
            }
        });

        // 处理类中的所有方法。
        ReflectionUtils.doWithLocalMethods(targetClass, method -> {
            Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
            if (!BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) {
                return;
            }
            // 查找方法上的自动装配注解。
            MergedAnnotation<?> ann = findAutowiredAnnotation(bridgedMethod);
            if (ann != null && method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {
                
                // ... [代码部分省略以简化]
                
                boolean required = determineRequiredStatus(ann);
                PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
                // 创建一个新的AutowiredMethodElement并加入到列表。
                currElements.add(new AutowiredMethodElement(method, required, pd));
            }
        });

        // 将当前类的注入元素加入到总的注入元素列表的开头。
        elements.addAll(0, currElements);
        // 处理父类。
        targetClass = targetClass.getSuperclass();
    }
    // 循环直至Object类。
    while (targetClass != null && targetClass != Object.class);

    // 返回为元素列表创建的新的InjectionMetadata。
    return InjectionMetadata.forElements(elements, clazz);
}
```

在`org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor#autowiredAnnotationTypes`字段中,主要的用途是告诉`AutowiredAnnotationBeanPostProcessor`哪些注解它应该处理。当Spring容器解析bean定义并创建bean实例时,如果这个bean的字段、方法或构造函数上的注解被包含在这个`autowiredAnnotationTypes`集合中,那么`AutowiredAnnotationBeanPostProcessor`就会对它进行处理。

```java
public AutowiredAnnotationBeanPostProcessor() {
   this.autowiredAnnotationTypes.add(Autowired.class);
   // ... [代码部分省略以简化]
}
```

#### 注入阶段

在`org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor#postProcessProperties`方法中,用于处理bean属性的后处理,特别是通过`@Autowired`等注解进行的属性注入。

```java
@Override
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
    // 获取与bean名称和类相关的InjectionMetadata。
    // 这包括该bean需要进行注入的所有字段和方法。
    InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
    
    try {
        // 使用获取到的InjectionMetadata,实际进行属性的注入。
        metadata.inject(bean, beanName, pvs);
    }
    // 如果在注入过程中出现BeanCreationException,直接抛出。
    catch (BeanCreationException ex) {
        throw ex;
    }
    // 捕获其他异常,并以BeanCreationException的形式抛出,提供详细的错误信息。
    catch (Throwable ex) {
        throw new BeanCreationException(beanName, "Injection of autowired dependencies failed", ex);
    }
    // 返回原始的PropertyValues,因为这个方法主要关注依赖注入而不是修改属性。
    return pvs;
}
```

在`org.springframework.beans.factory.annotation.InjectionMetadata#inject`方法中,主要目的是将所有需要注入的元素(例如带有`@Autowired`等注解的字段或方法)注入到目标bean中。

```java
public void inject(Object target, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
    // 获取已经检查的元素。通常,在初始化阶段,所有的元素都会被检查一次。
    Collection<InjectedElement> checkedElements = this.checkedElements;

    // 如果已经有检查过的元素,则使用它们,否则使用所有注入的元素。
    Collection<InjectedElement> elementsToIterate =
        (checkedElements != null ? checkedElements : this.injectedElements);

    // 如果有需要注入的元素...
    if (!elementsToIterate.isEmpty()) {
        // 遍历每个元素并注入到目标bean中。
        for (InjectedElement element : elementsToIterate) {
            // 对每个元素(字段或方法)执行注入操作。
            element.inject(target, beanName, pvs);
        }
    }
}
```

在`org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.AutowiredFieldElement#inject`方法中,首先检查字段的值是否已经被缓存。如果已缓存,则从缓存中获取,否则重新解析。然后,它确保字段是可访问的(特别是对于私有字段),并将解析的值设置到目标bean的相应字段中。

```java
@Override
protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
    // 步骤1. 获取代表带有@Autowired注解的字段的Field对象。
    Field field = (Field) this.member;

    Object value;
    // 步骤2. 如果字段的值已经被缓存(即先前已解析过),则尝试从缓存中获取。
    if (this.cached) {
        try {
            // 从缓存中获取已解析的字段值。
            value = resolvedCachedArgument(beanName, this.cachedFieldValue);
        }
        catch (NoSuchBeanDefinitionException ex) {
            // 如果缓存中的bean已被意外删除 -> 重新解析。
            value = resolveFieldValue(field, bean, beanName);
        }
    }
    else {
        // 步骤3. 如果字段值未被缓存,直接解析。
        value = resolveFieldValue(field, bean, beanName);
    }

    // 步骤4. 如果解析到的值不为null...
    if (value != null) {
        // 步骤4.1. 使字段可访问,这是必要的,特别是当字段是private时。
        ReflectionUtils.makeAccessible(field);
        // 步骤4.2. 实际将解析的值注入到目标bean的字段中。
        field.set(bean, value);
    }
}
```

首先来到`org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.AutowiredFieldElement#inject`方法中的步骤3。在`org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.AutowiredFieldElement#resolveFieldValue`方法中,通过`beanFactory.resolveDependency`方法从Spring的bean工厂中解析字段的值。

```java
@Nullable
private Object resolveFieldValue(Field field, Object bean, @Nullable String beanName) {
    // ... [代码部分省略以简化]
    Object value;
    try {
        // 通过`beanFactory.resolveDependency`方法从Spring的bean工厂中解析字段的值
        value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
    }
    catch (BeansException ex) {
        throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(field), ex);
    }
    // ... [代码部分省略以简化]
    return value;
}
```

在`org.springframework.beans.factory.support.DefaultListableBeanFactory#resolveDependency`方法中,首先尝试获取一个延迟解析代理。如果无法获得,它会进一步尝试解析依赖。`doResolveDependency` 是实际进行解析工作的方法。

```java
public Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName,
                                @Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {
	// ... [代码部分省略以简化]
    
    Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(
        descriptor, requestingBeanName);
    if (result == null) {
        result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);
    }
    return result;
}
```

在`org.springframework.beans.factory.support.DefaultListableBeanFactory#doResolveDependency`方法中,尝试解析一个特定的依赖,首先查找所有可能的匹配的 bean,然后选择一个最佳匹配的 bean。如果存在多个匹配的 bean 或没有找到匹配的 bean,它会进行相应的处理。

```java
public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName,
			@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {

    // ... [代码部分省略以简化]

    try {
        // 如果存在快捷解决依赖的方法,使用它
        Object shortcut = descriptor.resolveShortcut(this);
        if (shortcut != null) {
            return shortcut;
        }

        // 获取依赖的类型
        Class<?> type = descriptor.getDependencyType();
        
        // ... [代码部分省略以简化]

        // 步骤1. 根据依赖描述符查找匹配的bean
        Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
        
        // 如果没有找到匹配的bean
        if (matchingBeans.isEmpty()) {
            if (isRequired(descriptor)) {
                // 如果依赖是必需的,抛出异常
                raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
            }
            return null;
        }

        String autowiredBeanName;
        Object instanceCandidate;

        // 当找到多个匹配的bean
        if (matchingBeans.size() > 1) {
            // 确定最佳的自动装配候选者
            autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);
            if (autowiredBeanName == null) {
                if (isRequired(descriptor) || !indicatesMultipleBeans(type)) {
                    // 如果不能确定唯一的bean,尝试解析不唯一的依赖
                    return descriptor.resolveNotUnique(descriptor.getResolvableType(), matchingBeans);
                }
                else {
                    return null;
                }
            }
            instanceCandidate = matchingBeans.get(autowiredBeanName);
        }
        else {
            // 只找到一个匹配的bean
            Map.Entry<String, Object> entry = matchingBeans.entrySet().iterator().next();
            autowiredBeanName = entry.getKey();
            instanceCandidate = entry.getValue();
        }

        // 添加自动装配的bean名到集合
        if (autowiredBeanNames != null) {
            autowiredBeanNames.add(autowiredBeanName);
        }

        // 步骤2. 如果候选者是一个类,实例化它
        if (instanceCandidate instanceof Class) {
            instanceCandidate = descriptor.resolveCandidate(autowiredBeanName, type, this);
        }
        
        Object result = instanceCandidate;
        
        // ... [代码部分省略以简化]
        
        return result;
    }
    // ... [代码部分省略以简化]
}
```

我们来到在`org.springframework.beans.factory.support.DefaultListableBeanFactory#doResolveDependency`方法中的步骤1。在`org.springframework.beans.factory.support.DefaultListableBeanFactory#findAutowireCandidates`方法中,首先基于给定的类型获取所有可能的bean名。接着,对于每一个可能的候选bean,它检查该bean是否是一个合适的自动注入候选,如果是,它将这个bean添加到结果集中。最后,方法返回找到的所有合适的候选bean。

```java
protected Map<String, Object> findAutowireCandidates(
			@Nullable String beanName, Class<?> requiredType, DependencyDescriptor descriptor) {

    // 根据所需的类型,包括所有父工厂中的bean,获取所有可能的bean名
    String[] candidateNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
        this, requiredType, true, descriptor.isEager());

    // ... [代码部分省略以简化]

    // 遍历所有候选bean名
    for (String candidate : candidateNames) {
        // 如果候选bean不是正在查找的bean本身并且它是一个合适的自动注入候选
        if (!isSelfReference(beanName, candidate) && isAutowireCandidate(candidate, descriptor)) {
            // 添加这个候选bean到结果中
            addCandidateEntry(result, candidate, descriptor, requiredType);
        }
    }

    // ... [代码部分省略以简化]

    // 返回找到的所有候选bean
    return result; 
}
```

在`org.springframework.beans.factory.support.DefaultListableBeanFactory#addCandidateEntry`方法中,主要获取候选bean的类型,并将其添加到候选bean的集合中。

```java
private void addCandidateEntry(Map<String, Object> candidates, String candidateName,
			DependencyDescriptor descriptor, Class<?> requiredType) {
	// ... [代码部分省略以简化]
    candidates.put(candidateName, getType(candidateName));
}
```

在`org.springframework.beans.factory.support.AbstractBeanFactory#getType(name)`方法中,通过bean的名字来获取对应bean的类型。

```java
public Class<?> getType(String name) throws NoSuchBeanDefinitionException {
    return getType(name, true);
}
```

我们来到在`org.springframework.beans.factory.support.DefaultListableBeanFactory#doResolveDependency`方法中的步骤2。在`org.springframework.beans.factory.config.DependencyDescriptor#resolveCandidate`方法中,最后发现`@Autowired` 的整个流程最终还是从Spring容器中获取一个bean实例并注入到相应的字段或构造函数参数中。

```java
public Object resolveCandidate(String beanName, Class<?> requiredType, BeanFactory beanFactory)
			throws BeansException {

    return beanFactory.getBean(beanName);
}
```

最后我们来到`org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.AutowiredFieldElement#inject`方法中的步骤4.2。在 `AutowiredFieldElement#inject` 方法内部,通过`resolveFieldValue(field, bean, beanName)`方法,来确定了正确的bean值并满足某个字段的 `@Autowired` 注解,将使用反射来实际设置这个值。具体地说,它会使用 `Field` 类的 `set` 方法来为目标对象的这个字段设置相应的值。这就是 `@Autowired` 在字段上使用时如何使得Spring能够自动为这个字段注入值的背后原理。

```java
// 步骤4. 如果解析到的值不为null...
if (value != null) {
    // 步骤4.1. 使字段可访问,这是必要的,特别是当字段是private时。
    ReflectionUtils.makeAccessible(field);
    // 步骤4.2. 实际将解析的值注入到目标bean的字段中。
    field.set(bean, value);
}
```

### 八、注意事项

1. **默认情况下,依赖是必需的**
   - 如果Spring找不到匹配的bean来注入,它会抛出一个异常。我们可以通过将 `required` 属性设置为 `false` 来使其变为非必需:`@Autowired(required=false)`。
2. **类型匹配**
   - 默认情况下,Spring使用类型匹配来解析依赖。如果有多个匹配的bean,它会抛出一个异常。
3. **使用 `@Qualifier`**
   - 如果有多个相同类型的bean,我们可以使用 `@Qualifier` 注解来指定bean的名称,以解决歧义。
4. **循环依赖**
   - `@Autowired` 可能导致循环依赖的问题。例如,A依赖于B,而B依赖于A。Spring有一定的机制来处理单例作用域的bean的循环依赖,但对于原型作用域的bean,循环依赖会导致异常。
5. **注入位置**
   - 我们可以在字段、构造函数、或setter方法上使用 `@Autowired`。但是,推荐的做法是在构造函数上使用它,这样可以确保所有的依赖在对象创建时都已经注入。
6. **影响范围**
   - 使用 `@Autowired` 时,请注意不要在大范围的bean(例如单例)中注入小范围的bean(例如原型),除非我们清楚地知道自己在做什么。
7. **考虑使用构造函数注入**
   - 使用构造函数注入可以确保bean在构造时已完全初始化,从而使bean处于不变的状态。这也有助于在单元测试中模拟依赖关系。
8. **私有字段注入**
   - 尽管可以将 `@Autowired` 应用于私有字段,但这意味着Spring通过反射绕过了正常的Java访问控制来注入字段,这可能不是最佳实践。
9. **不支持静态字段**
   + `@Autowired` 不能用于静态字段。这是因为静态字段属于类而不是实例,而Spring是通过实例进行依赖注入的。
10. **不支持静态方法**
    + `@Autowired` 也不能用于静态setter方法或其他静态方法

### 九、总结

#### 最佳实践总结

1. **上下文初始化**
   - 当我们创建 `AnnotationConfigApplicationContext` 并提供 `MyConfiguration` 类作为参数时,Spring 开始初始化上下文。这意味着它会加载所有的bean定义并准备创建实例。
2. **组件扫描**
   - 在 `MyConfiguration` 类中,我们使用了 `@ComponentScan` 注解指定了扫描的包路径。这使得Spring扫描指定包和其子包中的所有类,并查找标记为 `@Component`、`@Service`、`@Repository` 和 `@Controller` 等注解的类。找到后,Spring 会自动将这些类注册为bean。
3. **依赖解析**
   - 在 `MyController` 类中,我们在 `myService` 字段上使用了 `@Autowired` 注解。这告诉Spring,当创建 `MyController` bean时,需要找到一个 `MyService` 类型的bean,并自动注入到该字段中。
4. **实例化并注入**
   - 当我们从上下文中请求 `MyController` 类型的bean时,Spring会先创建 `MyController` 的一个实例。但在此之前,它会查看所有带有 `@Autowired` 注解的字段,然后为这些字段找到匹配的bean并注入。
   - 在我们的例子中,Spring找到了 `MyService` 类型的bean并将其注入到了 `myService` 字段中。
5. **执行业务逻辑**
   - 在 `showService` 方法被调用时,它简单地打印了 `myService` 字段。由于这个字段已经被成功地自动注入,所以我们看到了预期的输出,证明 `@Autowired` 功能正常。
6. **结果**
   - 最终输出显示了 `myService` 已经被成功地注入到 `MyController` 中,并显示了其实例的内存地址。

#### 源码分析总结

1. **核心后处理器**

   - `AutowiredAnnotationBeanPostProcessor`是处理`@Autowired`等注解的主要后处理器。它实现了两个关键的接口,`MergedBeanDefinitionPostProcessor`和`InstantiationAwareBeanPostProcessor`,这两个接口允许在bean的生命周期中的关键阶段进行干预,为属性注入提供了机制。

2. **收集阶段**

   + 检索Autowired的元数据

     - Spring首先使用`postProcessMergedBeanDefinition`方法确保给定的bean定义与其预期的自动装配元数据一致。

     - 在该方法中, Spring会尝试查找与给定bean名称和类型相关的`InjectionMetadata`。这可能包括了该bean的字段和方法的注入信息。

   + 寻找匹配的Autowiring元数据
     - 在`findAutowiringMetadata`中,Spring确保始终为给定的bean名称和类获取最新和相关的`InjectionMetadata`。Spring也利用了缓存机制,以提高性能。

   + 构建Autowiring元数据

     - 在`buildAutowiringMetadata`方法中,Spring会查找类及其所有父类中的字段和方法,以找出所有带有自动装配注解的字段和方法。

     - 然后,为这些字段和方法创建一个统一的`InjectionMetadata`对象。

   + 检查注解类型
     - 在`AutowiredAnnotationBeanPostProcessor`的构造方法中,主要的目的是告诉这个后处理器它应该处理哪些注解。例如, `@Autowired`就是这些注解之一。

3. **注入阶段**

   + 处理bean属性的后处理

     - 在`postProcessProperties`中,Spring用于处理bean属性的后处理,特别是通过`@Autowired`进行的属性注入。

     - 这涉及到实际将解析得到的值注入到bean中。

   + 注入元数据的实际注入操作

     - 在`InjectionMetadata#inject`方法中,这里会对bean进行属性的实际注入。

     - Spring会遍历每一个需要注入的元素,并执行实际的注入操作。

   + 字段的实际注入

     - 在`AutowiredFieldElement#inject`中,Spring首先会检查字段的值是否已经被缓存。如果已缓存,则从缓存中获取,否则重新解析。

     - 然后,它确保字段是可访问的,并将解析的值设置到目标bean的相应字段中。

   + 解析依赖

     - 在`doResolveDependency`方法中,Spring开始尝试解析一个特定的依赖。

     - 首先,基于给定的类型,Spring会查找所有匹配的bean。

     - 如果找到多个匹配的bean,它会尝试确定哪一个是最佳的自动装配候选。

   + 获取bean的类型

     - 在`addCandidateEntry`方法中,Spring主要获取候选bean的类型,并将其添加到候选bean的集合中。

     - 使用`getType`方法,Spring可以通过bean的名字来获取对应bean的类型。

   + 从Spring容器中获取bean实例
     - 在`resolveCandidate`中,即从Spring容器中获取一个bean实例并注入到相应的字段或构造函数参数中。
   + 反射注入
     + 通过`field.set(bean, value)`来完成实际字段注入的步骤,将解析出的bean实例(value)注入到目标bean的对应字段上。这是整个`@Autowired`流程的最终步骤

================================================
FILE: spring-annotation/spring-annotation-autowired/pom.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>spring-annotation</artifactId>
        <groupId>com.xcs.spring</groupId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>spring-annotation-autowired</artifactId>

    <properties>
        <maven.compiler.source>11</maven.compiler.source>
        <maven.compiler.target>11</maven.compiler.target>
    </properties>

</project>

================================================
FILE: spring-annotation/spring-annotation-autowired/src/main/java/com/xcs/spring/AutowiredApplication.java
================================================
package com.xcs.spring;

import com.xcs.spring.config.MyConfiguration;
import com.xcs.spring.controller.MyController;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

/**
 * @author xcs
 * @date 2023年08月07日 16时21分
 **/
public class AutowiredApplication {

    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MyConfiguration.class);
        MyController controller = context.getBean(MyController.class);
        controller.showService();
    }
}


================================================
FILE: spring-annotation/spring-annotation-autowired/src/main/java/com/xcs/spring/config/MyConfiguration.java
================================================
package com.xcs.spring.config;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@ComponentScan("com.xcs.spring")
public class MyConfiguration {

}


================================================
FILE: spring-annotation/spring-annotation-autowired/src/main/java/com/xcs/spring/controller/MyController.java
================================================
package com.xcs.spring.controller;

import com.xcs.spring.service.MyService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;

@Controller
public class MyController {

    @Autowired
    private MyService myService;

    public void showService(){
        System.out.println("myService = " + myService);
    }
}


================================================
FILE: spring-annotation/spring-annotation-autowired/src/main/java/com/xcs/spring/service/MyService.java
================================================
package com.xcs.spring.service;

import org.springframework.stereotype.Service;

@Service
public class MyService {
}


================================================
FILE: spring-annotation/spring-annotation-bean/README.md
================================================
## @Bean

- [@Bean](#bean)
  - [一、基本信息](#一基本信息)
  - [二、注解描述](#二注解描述)
  - [三、注解源码](#三注解源码)
  - [四、主要功能](#四主要功能)
  - [五、最佳实践](#五最佳实践)
  - [六、时序图](#六时序图)
    - [@Bean注册时序图](#bean注册时序图)
    - [@Bean初始化方法时序图](#bean初始化方法时序图)
    - [@Bean销毁方法时序图](#bean销毁方法时序图)
  - [七、源码分析](#七源码分析)
    - [@Bean注册源码分析](#bean注册源码分析)
    - [@Bean初始化源码分析](#bean初始化源码分析)
    - [@Bean销毁源码分析](#bean销毁源码分析)
  - [八、注意事项](#八注意事项)
  - [九、总结](#九总结)
    - [最佳实践总结](#最佳实践总结)
    - [源码分析总结](#源码分析总结)


### 一、基本信息

✒️ **作者** - Lex 📝 **博客** - [我的CSDN](https://blog.csdn.net/duzhuang2399/article/details/132498762) 📚 **文章目录** - [所有文章](https://github.com/xuchengsheng/spring-reading) 🔗 **源码地址** - [@Bean源码](https://github.com/xuchengsheng/spring-reading/tree/master/spring-annotation/spring-annotation-bean)

### 二、注解描述

`@Bean` 是 Spring 框架的核心注解,用于标记一个方法,表明这个方法返回值应被注册为 Spring 容器中的一个对象(Bean)。与传统的 XML 配置方式相比,它提供了一种更加简洁和直观的方式来定义 Bean。通常,`@Bean` 与 `@Configuration` 注解一起使用,后者标记一个类为 Spring 的配置类。方法名默认作为 Bean 的 ID,但也可以通过 `@Bean` 的 `name` 属性自定义。这种声明式的 Bean 定义方式在 Java 代码中提供了强大的灵活性,允许我们利用 Java 的完整特性来配置和初始化对象。此外,结合其他 Spring 特性,如 `@Autowired`,可以轻松实现依赖注入,进一步简化了应用的配置和组件管理。总之,通过 `@Bean` 注解,Spring 为现代化的应用开发提供了强大的支持,使得代码更为整洁和易于维护。

### 三、注解源码

`@Bean`注解是 Spring 框架自 3.0 版本开始引入的一个核心注解,这个注解表明一个方法会返回一个对象,该对象应该被注册为 Spring 应用上下文中的一个 bean。

```java
/**
 * 指示一个方法会产生一个由Spring容器管理的Bean。
 * @author Rod Johnson
 * @author Costin Leau
 * @author Chris Beams
 * @author Juergen Hoeller
 * @author Sam Brannen
 * @since 3.0
 * @see Configuration
 * @see Scope
 * @see DependsOn
 * @see Lazy
 * @see Primary
 * @see org.springframework.stereotype.Component
 * @see org.springframework.beans.factory.annotation.Autowired
 * @see org.springframework.beans.factory.annotation.Value
 */
@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Bean {

    /**
     * {@link #name}的别名。
     * 当不需要其他属性时可以使用,例如:{@code @Bean("customBeanName")}。
     * @see #name
     */
    @AliasFor("name")
    String[] value() default {};

    /**
     * 这个bean的名称,或者如果有多个名称,则为主要的bean名称加上别名。
     * 如果未指定,bean的名称是注解方法的名称。
     * @see #value
     */
    @AliasFor("value")
    String[] name() default {};

    /**
     * 是否通过基于习惯的按名称或类型进行自动装配?
     * 注意,这种自动装配模式是基于按照习惯通过bean属性的setter方法进行的外部驱动的自动装配。
     * @deprecated ...
     */
    @Deprecated
    Autowire autowire() default Autowire.NO;

    /**
     * 这个bean是否可以作为其他bean的自动注入候选者?
     */
    boolean autowireCandidate() default true;

    /**
     * 在初始化时调用bean实例上的方法的可选名称。
     * 通常,可以在带有@Bean注解的方法的主体中直接以编程方式调用该方法。
     */
    String initMethod() default "";

    /**
     * 在关闭应用程序上下文时调用bean实例上的方法的可选名称。
     * 例如,一个JDBC DataSource的close()方法。
     */
    String destroyMethod() default AbstractBeanDefinition.INFER_METHOD;

}
```

### 四、主要功能

1. **Bean 的创建与注册**:
   + `@Bean` 注解用于标记一个方法,该方法返回的对象会被 Spring 容器管理。这意味着当应用上下文启动时,该方法会被调用,并且它的返回值会被添加到容器中作为一个 bean。

2. **自定义 Bean 名称**
   + 虽然默认的 bean 名称是标注 `@Bean` 的方法的名称,但可以通过 `@Bean` 的 `name` 属性为 bean 指定一个或多个名称。

3. **生命周期管理**
   + 通过 `initMethod` 和 `destroyMethod` 属性,可以为 bean 指定初始化和销毁的回调方法。当 bean 被创建或销毁时,这些方法会被调用。

4. **替代 XML 配置**
   + 在早期的 Spring 版本中,bean 通常是在 XML 文件中定义的。使用 `@Bean` 注解可以完全用 Java 配置来替代 XML,从而使配置更为集中和类型安全。

5. **灵活的依赖注入**
   + 在 `@Bean` 方法内部,可以直接调用其他 `@Bean` 方法,实现依赖的注入。这种方式保证了类型安全,并使得代码与配置紧密结合。

6. **与其他注解结合**
   + `@Bean` 注解经常与其他 Spring 注解一起使用,如 `@Scope`(定义 bean 的范围,如单例或原型),`@Lazy`(延迟 bean 的初始化),`@Primary`(当存在多个相同类型的 bean 时,标记一个为首选)等,为 bean 提供更详细的配置。

7. **控制自动装配行为**
   + 通过 `autowireCandidate` 属性,可以控制该 bean 是否应被视为自动装配的候选对象,当其他 bean 需要进行类型匹配的自动装配时。

### 五、最佳实践

首先来看看启动类入口,上下文环境使用`AnnotationConfigApplicationContext`(此类是使用Java注解来配置Spring容器的方式),构造参数我们给定了一个`MyConfiguration`组件类。然后从Spring上下文中获取一个`MyBean`类型的bean,最后调用`context.close()`方法关闭容器。

```java
public class BeanApplication {

    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MyConfiguration.class);
        System.out.println(context.getBean(MyBean.class));
        context.close();
    }
}
```

在 `MyConfiguration` 配置类中,通过 `@Bean` 注解定义了一个名为 `myBean` 的 bean。这个 bean 是 `MyBean` 类的实例。当 Spring 容器初始化这个 bean 时,它会首先调用 `MyBean` 的 `init` 方法(由 `initMethod` 属性指定)。当这个 bean 在容器关闭时被销毁,它会调用 `MyBean` 的 `destroy` 方法(由 `destroyMethod` 属性指定)。

```java
@Configuration
public class MyConfiguration {

    @Bean(initMethod = "init",destroyMethod = "destroy")
    public MyBean myBean(){
        return new MyBean();
    }
}
```

当 Spring 容器创建 `MyBean` 的实例时,`init` 方法会被自动调用,因此 "MyBean.init" 会被输出到控制台。同样地,当 Spring 容器准备销毁这个 bean 或关闭时,`destroy` 方法会被调用,于是 "MyBean.destroy" 会被输出到控制台。

```java
public class MyBean {

    public void init(){
        System.out.println("MyBean.init");
    }

    public void destroy(){
        System.out.println("MyBean.destroy");
    }
}
```

运行结果发现,证明了在创建 bean 时 `init` 方法的调用以及在销毁 bean 时 `destroy` 方法的调用,从而展示了通过 `@Bean` 注解指定的生命周期方法在实际应用中的执行顺序。

```java
MyBean.init
com.xcs.spring.bean.MyBean@2fb3536e
MyBean.destroy
```

### 六、时序图

#### @Bean注册时序图

~~~mermaid
sequenceDiagram
Title: @Bean注册时序图
BeanApplication->>AnnotationConfigApplicationContext: AnnotationConfigApplicationContext(componentClasses)<br>创建应用上下文
AnnotationConfigApplicationContext->>AbstractApplicationContext: refresh()<br>刷新应用上下文
AbstractApplicationContext->>AbstractApplicationContext: invokeBeanFactoryPostProcessors(beanFactory)<br>调用BeanFactory后置处理器
AbstractApplicationContext->>PostProcessorRegistrationDelegate: invokeBeanFactoryPostProcessors(beanFactory,beanFactoryPostProcessors)<br>执行BeanFactory的后置处理器
PostProcessorRegistrationDelegate->>PostProcessorRegistrationDelegate: invokeBeanDefinitionRegistryPostProcessors(postProcessors,registry,applicationStartup)<br>执行BeanDefinition的注册后处理器
PostProcessorRegistrationDelegate->>ConfigurationClassPostProcessor: postProcessBeanDefinitionRegistry(registry)<br>处理@Configuration注解的类的Bean定义
ConfigurationClassPostProcessor->>ConfigurationClassPostProcessor: processConfigBeanDefinitions(registry)<br>处理配置类的Bean定义
ConfigurationClassPostProcessor->>ConfigurationClassParser: ConfigurationClassParser(...)<br>创建配置类解析器
ConfigurationClassParser-->>ConfigurationClassPostProcessor: 返回parser解析器<br>
ConfigurationClassPostProcessor->>ConfigurationClassParser: parser.parse(candidates)<br>解析候选的@Configuration类
ConfigurationClassParser->>ConfigurationClassParser: parse(metadata, String beanName)<br>解析具体的@Configuration类
ConfigurationClassParser->>ConfigurationClassParser: processConfigurationClass(configClass,filter)<br>处理@Configuration类
ConfigurationClassParser->>+ConfigurationClassParser: doProcessConfigurationClass(configClass,sourceClass,filter)<br>实际处理@Configuration类
ConfigurationClassParser->>+ConfigurationClassParser: retrieveBeanMethodMetadata(sourceClass)<br>获取@Bean方法的元数据
ConfigurationClassParser-->>-ConfigurationClassParser: 返回Set<MethodMetadata><br>
ConfigurationClassParser-->>-ConfigurationClassParser: 返回SourceClass<br>
ConfigurationClassPostProcessor->>ConfigurationClassBeanDefinitionReader: loadBeanDefinitions(configurationModel)<br>加载Bean定义
ConfigurationClassBeanDefinitionReader->>ConfigurationClassBeanDefinitionReader: loadBeanDefinitionsForConfigurationClass(configClass,trackedConditionEvaluator)<br>为@Configuration类加载Bean定义
ConfigurationClassBeanDefinitionReader->>ConfigurationClassBeanDefinitionReader: loadBeanDefinitionsForBeanMethod(beanMethod)<br>为@Bean方法加载Bean定义
ConfigurationClassBeanDefinitionReader->>DefaultListableBeanFactory: registerBeanDefinition(beanName, beanDefToRegister)<br>在BeanFactory中注册Bean定义
~~~

#### @Bean初始化方法时序图

~~~mermaid
sequenceDiagram
Title: @Bean初始化方法时序图
BeanApplication->>AnnotationConfigApplicationContext: AnnotationConfigApplicationContext(componentClasses)<br>创建应用上下文
AnnotationConfigApplicationContext->>AbstractApplicationContext: refresh()<br>刷新应用上下文
AbstractApplicationContext->>AbstractApplicationContext: finishBeanFactoryInitialization(beanFactory)<br>完成BeanFactory的初始化
AbstractApplicationContext->>DefaultListableBeanFactory: preInstantiateSingletons()<br>预先实例化单例Bean
DefaultListableBeanFactory->>AbstractBeanFactory: getBean(name)<br>获取Bean
AbstractBeanFactory->>AbstractBeanFactory: doGetBean(name,requiredType,args,typeCheckOnly)<br>执行真实的获取Bean的操作
AbstractBeanFactory->>DefaultSingletonBeanRegistry: getSingleton(beanName,singletonFactory)<br>从单例注册表中获取Bean
DefaultSingletonBeanRegistry->>AbstractBeanFactory: singletonFactory.getObject()<br>从singleton工厂中获取Bean对象
AbstractBeanFactory->>AbstractAutowireCapableBeanFactory: createBean(beanName,mbd,args)<br>创建Bean
AbstractAutowireCapableBeanFactory->>AbstractAutowireCapableBeanFactory: doCreateBean(beanName,mbd,args)<br>执行Bean的创建过程
AbstractAutowireCapableBeanFactory->>AbstractAutowireCapableBeanFactory: initializeBean(beanName,bean,mbd)<br>初始化Bean
AbstractAutowireCapableBeanFactory->>AbstractAutowireCapableBeanFactory: invokeInitMethods(beanName,bean,mbd)<br>调用Bean的初始化方法
AbstractAutowireCapableBeanFactory->>AbstractAutowireCapableBeanFactory: invokeCustomInitMethod(beanName,bean,mbd)<br>执行自定义的初始化方法
AbstractAutowireCapableBeanFactory->>Method: invoke(obj,args)<br>反射调用Bean的方法
Method->>MyBean: init()<br>执行Bean的init方法
AbstractBeanFactory-->>DefaultListableBeanFactory: 返回最终创建的Bean

~~~

#### @Bean销毁方法时序图

~~~mermaid
sequenceDiagram
Title: @Bean销毁方法时序图
BeanApplication->>AnnotationConfigApplicationContext: AnnotationConfigApplicationContext(componentClasses)<br>创建应用上下文
AnnotationConfigApplicationContext-->>BeanApplication: 应用上下文初始化完成并返回应用
BeanApplication->>AbstractApplicationContext: close()<br>请求关闭应用上下文
AbstractApplicationContext->>AbstractApplicationContext: doClose()<br>执行关闭操作
AbstractApplicationContext->>AbstractApplicationContext: destroyBeans()<br>销毁容器中的所有Beans
AbstractApplicationContext->>DefaultListableBeanFactory: destroySingletons()<br>销毁所有单例Beans
DefaultListableBeanFactory->>DefaultSingletonBeanRegistry: super.destroySingletons()<br>调用父类方法,销毁所有单例Beans
DefaultSingletonBeanRegistry->>DefaultSingletonBeanRegistry: destroySingleton(beanName)<br>销毁指定名称的单例Bean
DefaultSingletonBeanRegistry->>DefaultSingletonBeanRegistry: destroyBean(beanName,bean)<br>执行Bean的销毁逻辑
DefaultSingletonBeanRegistry->>DisposableBeanAdapter: destroy()<br>调用Bean的销毁方法
DisposableBeanAdapter->>DisposableBeanAdapter: invokeCustomDestroyMethod(destroyMethod)<br>调用自定义的销毁方法
DisposableBeanAdapter->>Method: invoke(this.bean, args)<br>反射调用Bean的销毁方法
Method->>MyBean: destroy()<br>执行Bean的destroy方法
~~~

### 七、源码分析

#### @Bean注册源码分析

首先来看看启动类入口,上下文环境使用`AnnotationConfigApplicationContext`(此类是使用Java注解来配置Spring容器的方式),构造参数我们给定了一个`MyConfiguration`组件类。然后从Spring上下文中获取一个`MyBean`类型的bean,最后调用`context.close()`方法关闭容器。

```java
public class BeanApplication {

    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MyConfiguration.class);
        System.out.println(context.getBean(MyBean.class));
        context.close();
    }
}
```

在`org.springframework.context.annotation.AnnotationConfigApplicationContext#AnnotationConfigApplicationContext`构造函数中,执行了三个步骤,我们重点关注`refresh()`方法。

```java
public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
    this();
    register(componentClasses);
    refresh();
}
```

在`org.springframework.context.support.AbstractApplicationContext#refresh`方法中我们重点关注一下`finishBeanFactoryInitialization(beanFactory)`这方法会对实例化所有剩余非懒加载的单列Bean对象,其他方法不是本次源码阅读的重点暂时忽略。

```java
@Override
public void refresh() throws BeansException, IllegalStateException {
     // ... [代码部分省略以简化]
     // 调用在上下文中注册为bean的工厂处理器
     invokeBeanFactoryPostProcessors(beanFactory);
     // ... [代码部分省略以简化]
}
```

在`org.springframework.context.support.AbstractApplicationContext#invokeBeanFactoryPostProcessors`方法中,又委托了`PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors()`进行调用。

```java
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
    PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
    // ... [代码部分省略以简化]
}
```

在`org.springframework.context.support.PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors`方法中,首先调用了 `BeanDefinitionRegistryPostProcessor`(这是 `BeanFactoryPostProcessor` 的子接口)。它专门用来在所有其他 bean 定义加载之前修改默认的 bean 定义。

```java
public static void invokeBeanFactoryPostProcessors(
        ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
    // ... [代码部分省略以简化]
    invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
	// ... [代码部分省略以简化]
}
```

在`org.springframework.context.support.PostProcessorRegistrationDelegate#invokeBeanDefinitionRegistryPostProcessors`方法中,循环调用了实现`BeanDefinitionRegistryPostProcessor`接口中的`postProcessBeanDefinitionRegistry(registry)`方法

```java
private static void invokeBeanDefinitionRegistryPostProcessors(
			Collection<? extends BeanDefinitionRegistryPostProcessor> postProcessors, BeanDefinitionRegistry registry, ApplicationStartup applicationStartup) {

    for (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) {
        StartupStep postProcessBeanDefRegistry = applicationStartup.start("spring.context.beandef-registry.post-process")
            .tag("postProcessor", postProcessor::toString);
        postProcessor.postProcessBeanDefinitionRegistry(registry);
        postProcessBeanDefRegistry.end();
    }
}
```

在`org.springframework.context.annotation.ConfigurationClassPostProcessor#postProcessBeanDefinitionRegistry`方法中,调用了`processConfigBeanDefinitions`方法,该方法的主要目的是处理和注册配置类中定义的beans。

```java
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
    // ... [代码部分省略以简化]
    processConfigBeanDefinitions(registry);
}
```

在`org.springframework.context.annotation.ConfigurationClassPostProcessor#processConfigBeanDefinitions`方法中,这个方法主要处理了配置类的解析和验证,并确保了所有在配置类中定义的beans都被正确地注册到Spring的bean定义注册表中。

```java
public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
    // ... [代码部分省略以简化]

    // 步骤1:创建一个用于解析配置类的解析器
    ConfigurationClassParser parser = new ConfigurationClassParser(
            this.metadataReaderFactory, this.problemReporter, this.environment,
            this.resourceLoader, this.componentScanBeanNameGenerator, registry);

    // 步骤2:初始化候选配置类集合以及已解析配置类集合
    Set<BeanDefinitionHolder> candidates = new LinkedHashSet<>(configCandidates);
    Set<ConfigurationClass> alreadyParsed = new HashSet<>(configCandidates.size());

    // 步骤3:循环处理所有候选配置类,直至没有候选类为止
    do {
        // 步骤3.1 解析配置类
        parser.parse(candidates);
        // 步骤3.2 验证配置类
        parser.validate();

        // 获取解析后的配置类,并从中移除已经处理过的
        Set<ConfigurationClass> configClasses = new LinkedHashSet<>(parser.getConfigurationClasses());
        configClasses.removeAll(alreadyParsed);

        // 步骤4:如果reader为空,则创建一个新的Bean定义读取器
        if (this.reader == null) {
            this.reader = new ConfigurationClassBeanDefinitionReader(
                    registry, this.sourceExtractor, this.resourceLoader, this.environment,
                    this.importBeanNameGenerator, parser.getImportRegistry());
        }

        // 步骤5:使用读取器为解析的配置类加载Bean定义
        this.reader.loadBeanDefinitions(configClasses);

        // ... [代码部分省略以简化]
        
    } while (!candidates.isEmpty());

    // ... [代码部分省略以简化]
}
```

我们来到`org.springframework.context.annotation.ConfigurationClassPostProcessor#processConfigBeanDefinitions`方法中的步骤3.1。在`org.springframework.context.annotation.ConfigurationClassParser#parse`方法中,主要是遍历所有的配置类候选者,并对每一个带有注解的Bean定义进行解析。这通常涉及到查找该配置类中的@Bean方法、组件扫描指令等,并将这些信息注册到Spring容器中。

```java
public void parse(Set<BeanDefinitionHolder> configCandidates) {
    // ... [代码部分省略以简化]
    parse(((AnnotatedBeanDefinition) bd).getMetadata(), holder.getBeanName());
    // ... [代码部分省略以简化]
}
```

在`org.springframework.context.annotation.ConfigurationClassParser#parse(metadata, beanName)`方法中,将注解元数据和Bean名称转化为一个配置类,然后对其进行处理。处理配置类是Spring配置驱动的核心,它涉及到许多关键操作,如解析@Bean方法、处理@ComponentScan注解、处理@Import注解等。

```java
protected final void parse(AnnotationMetadata metadata, String beanName) throws IOException {
    processConfigurationClass(new ConfigurationClass(metadata, beanName), DEFAULT_EXCLUSION_FILTER);
}
```

在`org.springframework.context.annotation.ConfigurationClassParser#processConfigurationClass`方法中,处理一个给定的配置类。它首先递归地处理配置类及其父类,以确保所有相关的配置都被正确地读取并解析。在递归处理完所有相关配置后,它将配置类添加到已解析的配置类的映射中。

```java
protected void processConfigurationClass(ConfigurationClass configClass, Predicate<String> filter) throws IOException {
    // ... [代码部分省略以简化]

    // 步骤1:递归地处理配置类及其超类层次结构
    SourceClass sourceClass = asSourceClass(configClass, filter);
    do {
        sourceClass = doProcessConfigurationClass(configClass, sourceClass, filter);
    } while (sourceClass != null);

    // 步骤2:将处理后的配置类放入映射中
    this.configurationClasses.put(configClass, configClass);
}
```

在`org.springframework.context.annotation.ConfigurationClassParser#doProcessConfigurationClass`方法中,进一步处理配置类。特别是,它处理配置类中所有带有@Bean注解的方法。这些方法定义了如何在Spring应用程序上下文中初始化bean。这里简化的注释重点放在@Bean方法上,但原方法可能还包含其他重要的处理逻辑。

```java
@Nullable
protected final SourceClass doProcessConfigurationClass(
    ConfigurationClass configClass, SourceClass sourceClass, Predicate<String> filter)
    throws IOException {

    // ... [代码部分省略以简化]
    
    // 处理配置类中的每一个@Bean注解的方法
    // 这里的目标是识别和注册配置类中定义的所有@Bean方法。这些方法定义了如何初始化应用程序中的bean。
    Set<MethodMetadata> beanMethods = retrieveBeanMethodMetadata(sourceClass);
    for (MethodMetadata methodMetadata : beanMethods) {
        configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));
    }

    // ... [代码部分省略以简化]
    return null;
}
```

在`org.springframework.context.annotation.ConfigurationClassParser#retrieveBeanMethodMetadata`方法中,终于看到对`@Bean`注解的解析过程了,首先是尝试使用ASM获取确定的方法顺序,这一步是因为Java反射API返回的方法顺序是不确定的,但在某些场景下,方法的声明顺序可能是重要的。为了获得一个确定的顺序,我们尝试使用ASM(一个Java字节码处理框架)来读取类文件。其次是比较反射和ASM的结果,如果通过ASM获取到的方法数大于或等于通过反射获取的方法数,那么我们会进一步比较这两个集合。如果这两个集合的方法名相匹配,我们会更倾向于使用ASM的结果,因为它提供了确定的方法顺序。最后,方法返回一个`Set<MethodMetadata>`,表示找到的所有标注了@Bean的方法。

**为什么要关心方法的顺序?** 在某些情况下,我们可能期望@Bean方法按照它们在类中的声明顺序执行。虽然这种依赖通常应该避免,但Spring还是尽可能地根据我们声明的这种顺序,特别是在涉及生命周期回调和依赖注入时。

```java
private Set<MethodMetadata> retrieveBeanMethodMetadata(SourceClass sourceClass) {
    // 从源类中获取其注解元数据
    AnnotationMetadata original = sourceClass.getMetadata();
    
    // 从注解元数据中获取所有带有@Bean注解的方法
    Set<MethodMetadata> beanMethods = original.getAnnotatedMethods(Bean.class.getName());

    // 如果发现多个@Bean方法,并且注解元数据是StandardAnnotationMetadata的实例,
    // 则尝试使用ASM库读取类文件,以获取确定的方法声明顺序。
    if (beanMethods.size() > 1 && original instanceof StandardAnnotationMetadata) {
        try {
            // 使用ASM读取类文件的元数据
            AnnotationMetadata asm =
                this.metadataReaderFactory.getMetadataReader(original.getClassName()).getAnnotationMetadata();
            Set<MethodMetadata> asmMethods = asm.getAnnotatedMethods(Bean.class.getName());

            // 检查ASM读取的方法集是否包含所有通过标准反射检测到的方法
            if (asmMethods.size() >= beanMethods.size()) {
                Set<MethodMetadata> selectedMethods = new LinkedHashSet<>(asmMethods.size());
                for (MethodMetadata asmMethod : asmMethods) {
                    for (MethodMetadata beanMethod : beanMethods) {
                        if (beanMethod.getMethodName().equals(asmMethod.getMethodName())) {
                            selectedMethods.add(beanMethod);
                            break;
                        }
                    }
                }
                if (selectedMethods.size() == beanMethods.size()) {
                    // 所有通过反射检测到的方法都在ASM方法集中,因此使用ASM方法集
                    beanMethods = selectedMethods;
                }
            }
        }
        catch (IOException ex) {
            // 如果使用ASM读取类文件时发生错误,记录错误信息,并继续使用反射元数据
            logger.debug("Failed to read class file via ASM for determining @Bean method order", ex);
        }
    }

    // 返回检索到的@Bean方法集
    return beanMethods;
}
```

上面是步骤3.1对`@Bean`方法进行扫描,并将扫描结果存储在`ConfigurationClass`类中的`beanMethods`字段中。

我们来到`org.springframework.context.annotation.ConfigurationClassPostProcessor#processConfigBeanDefinitions`方法中的步骤4。在`org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader#loadBeanDefinitions`方法中,首先设置了一个跟踪条件评估的工具,然后遍历每一个配置类,为每一个配置类加载bean定义。这是Spring Java配置方式的核心过程,确保`@Bean`方法被正确地解析并在容器中注册为bean。

```java
public void loadBeanDefinitions(Set<ConfigurationClass> configurationModel) {
    TrackedConditionEvaluator trackedConditionEvaluator = new TrackedConditionEvaluator();
    for (ConfigurationClass configClass : configurationModel) {
        loadBeanDefinitionsForConfigurationClass(configClass, trackedConditionEvaluator);
    }
}
```

在`org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader#loadBeanDefinitionsForConfigurationClass`方法中,对于每一个`BeanMethod`,调用了`loadBeanDefinitionsForBeanMethod`方法。这个方法会针对单个@Bean方法进行解析,并将其转换为一个Spring IoC容器可以管理的Bean定义。

```java
private void loadBeanDefinitionsForConfigurationClass(
			ConfigurationClass configClass, TrackedConditionEvaluator trackedConditionEvaluator) {

    // ... [代码部分省略以简化]
    for (BeanMethod beanMethod : configClass.getBeanMethods()) {
        loadBeanDefinitionsForBeanMethod(beanMethod);
    }
	// ... [代码部分省略以简化]
}
```

在`org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader#loadBeanDefinitionsForBeanMethod`方法中,如果@Bean方法是静态的,那么它直接使用方法所在类作为bean的类。否则,它使用配置类的bean名称作为工厂bean名,并设置工厂方法名为当前@Bean方法的名字,然后尝试获取更详细的方法元数据,特别是如果元数据是`StandardMethodMetadata`类型的,它可以直接获取原始方法对象,然后还要处理`autowire`, `autowireCandidate`, `initMethod`, 和`destroyMethod`等属性,这些属性提供了有关如何处理bean生命周期和依赖注入的信息。然后如果@Bean方法有`@Scope`注解,它会处理这个注解的属性,如作用域名和代理模式,然后需要为这个bean创建一个代理,最后,使用`registerBeanDefinition`方法将Bean定义注册到IoC容器中。

```java
private void loadBeanDefinitionsForBeanMethod(BeanMethod beanMethod) {
    // ... [代码部分省略以简化]

    // 创建一个新的Bean定义基于@Bean方法的元数据
    ConfigurationClassBeanDefinition beanDef = new ConfigurationClassBeanDefinition(configClass, metadata, beanName);

    // 设置Bean定义的来源信息
    beanDef.setSource(this.sourceExtractor.extractSource(metadata, configClass.getResource()));

    // 检查@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);
    }

    // 如果元数据是StandardMethodMetadata类型的,设置已解析的工厂方法
    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);

    // 处理Bean定义的通用注解属性
    AnnotationConfigUtils.processCommonDefinitionAnnotations(beanDef, metadata);

    // 获取并设置autowire属性
    Autowire autowire = bean.getEnum("autowire");
    if (autowire.isAutowire()) {
        beanDef.setAutowireMode(autowire.value());
    }

    // 获取并设置autowireCandidate属性
    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);

    // 根据@Scope注解处理Bean的作用域及其代理模式
    ScopedProxyMode proxyMode = ScopedProxyMode.NO;
    AnnotationAttributes attributes = AnnotationConfigUtils.attributesFor(metadata, Scope.class);
    if (attributes != null) {
        beanDef.setScope(attributes.getString("value"));
        proxyMode = attributes.getEnum("proxyMode");
        if (proxyMode == ScopedProxyMode.DEFAULT) {
            proxyMode = ScopedProxyMode.NO;
        }
    }

    // 如果需要,创建一个代理的Bean定义
    BeanDefinition beanDefToRegister = beanDef;
    if (proxyMode != ScopedProxyMode.NO) {
        BeanDefinitionHolder proxyDef = ScopedProxyCreator.createScopedProxy(
            new BeanDefinitionHolder(beanDef, beanName), this.registry,
            proxyMode == ScopedProxyMode.TARGET_CLASS);
        beanDefToRegister = new ConfigurationClassBeanDefinition(
            (RootBeanDefinition) proxyDef.getBeanDefinition(), configClass, metadata, beanName);
    }

    // 最终将@Bean方法对应的Bean定义注册到容器
    this.registry.registerBeanDefinition(beanName, beanDefToRegister);
}
```

#### @Bean初始化源码分析

首先来看看启动类入口,上下文环境使用`AnnotationConfigApplicationContext`(此类是使用Java注解来配置Spring容器的方式),构造参数我们给定了一个`MyConfiguration`组件类。然后从Spring上下文中获取一个`MyBean`类型的bean,最后调用`context.close()`方法关闭容器。

```java
public class BeanApplication {

    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MyConfiguration.class);
        System.out.println(context.getBean(MyBean.class));
        context.close();
    }
}
```

在`org.springframework.context.annotation.AnnotationConfigApplicationContext#AnnotationConfigApplicationContext`构造函数中,执行了三个步骤,我们重点关注`refresh()`方法

```java
public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
    this();
    register(componentClasses);
    refresh();
}
```

在`org.springframework.context.support.AbstractApplicationContext#refresh`方法中我们重点关注一下`finishBeanFactoryInitialization(beanFactory)`这方法会对实例化所有剩余非懒加载的单列Bean对象,其他方法不是本次源码阅读的重点暂时忽略。

```java
@Override
public void refresh() throws BeansException, IllegalStateException {
    // ... [代码部分省略以简化]
    // Instantiate all remaining (non-lazy-init) singletons.
    finishBeanFactoryInitialization(beanFactory);
    // ... [代码部分省略以简化]
}
```

在`org.springframework.context.support.AbstractApplicationContext#finishBeanFactoryInitialization`方法中,会继续调用`DefaultListableBeanFactory`类中的`preInstantiateSingletons`方法来完成所有剩余非懒加载的单列Bean对象。

```java
/**
 * 完成此工厂的bean初始化,实例化所有剩余的非延迟初始化单例bean。
 * 
 * @param beanFactory 要初始化的bean工厂
 */
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
    // ... [代码部分省略以简化]
    // 完成所有剩余非懒加载的单列Bean对象。
    beanFactory.preInstantiateSingletons();
}
```

在`org.springframework.beans.factory.support.DefaultListableBeanFactory#preInstantiateSingletons`方法中,主要的核心目的是预先实例化所有非懒加载的单例bean。在Spring的上下文初始化完成后,该方法会被触发,以确保所有单例bean都被正确地创建并初始化。其中`getBean(beanName)`是此方法的核心操作。对于容器中定义的每一个单例bean,它都会调用`getBean`方法,这将触发bean的实例化、初始化及其依赖的注入。如果bean之前没有被创建过,那么这个调用会导致其被实例化和初始化。

```java
public void preInstantiateSingletons() throws BeansException {
    // ... [代码部分省略以简化]
    // 循环遍历所有bean的名称
    for (String beanName : beanNames) {
        getBean(beanName);
    }
    // ... [代码部分省略以简化]
}
```

在`org.springframework.beans.factory.support.AbstractBeanFactory#getBean()`方法中,又调用了`doGetBean`方法来实际执行创建Bean的过程,传递给它bean的名称和一些其他默认的参数值。此处,`doGetBean`负责大部分工作,如查找bean定义、创建bean(如果尚未创建)、处理依赖关系等。

```java
@Override
public Object getBean(String name) throws BeansException {
    return doGetBean(name, null, null, false);
}
```

在`org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean`方法中,首先检查所请求的bean是否是一个单例并且已经创建。如果尚未创建,它将创建一个新的实例。在这个过程中,它处理可能的异常情况,如循环引用,并确保返回的bean是正确的类型。这是Spring容器bean生命周期管理的核心部分。

```java
protected <T> T doGetBean(
        String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
        throws BeansException {
    // ... [代码部分省略以简化]

    // 开始创建bean实例
    if (mbd.isSingleton()) {
        // 如果bean是单例的,我们会尝试从单例缓存中获取它
        // 如果不存在,则使用lambda创建一个新的实例
        sharedInstance = getSingleton(beanName, () -> {
            try {
                // 尝试创建bean实例
                return createBean(beanName, mbd, args);
            }
            catch (BeansException ex) {
                // ... [代码部分省略以简化]
            }
        });
        // 对于某些bean(例如FactoryBeans),可能需要进一步处理以获取真正的bean实例
        beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
    }
    // ... [代码部分省略以简化]

    // 确保返回的bean实例与请求的类型匹配
    return adaptBeanInstance(name, beanInstance, requiredType);
}
```

在`org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#getSingleton()`方法中,主要负责从单例缓存中获取一个已存在的bean实例,或者使用提供的`ObjectFactory`创建一个新的实例。这是确保bean在Spring容器中作为单例存在的关键部分。

```java
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
    // 断言bean名称不能为空
    Assert.notNull(beanName, "Bean name must not be null");

    // 同步访问单例对象缓存,确保线程安全
    synchronized (this.singletonObjects) {
        // 从缓存中获取单例对象
        Object singletonObject = this.singletonObjects.get(beanName);

        // 如果缓存中没有找到
        if (singletonObject == null) {
            // ... [代码部分省略以简化]

            try {
                // 使用工厂创建新的单例实例
                singletonObject = singletonFactory.getObject();
                newSingleton = true;
            }
            catch (IllegalStateException ex) {
                // ... [代码部分省略以简化]
            }
            catch (BeanCreationException ex) {
                // ... [代码部分省略以简化]
            }
            finally {
                // ... [代码部分省略以简化]
            }

            // ... [代码部分省略以简化]
        }

        // 返回单例对象
        return singletonObject;
    }
}
```

在`org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBean()`方法中,主要的逻辑是调用 `doCreateBean`,这是真正进行 bean 实例化、属性填充和初始化的地方。这个方法会返回新创建的 bean 实例。

```java
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
    throws BeanCreationException {
    
    // ... [代码部分省略以简化]
    
    try {
        // 正常的bean实例化、属性注入和初始化。
        // 这里是真正进行bean创建的部分。
        Object beanInstance = doCreateBean(beanName, mbdToUse, args);
        // 记录bean成功创建的日志
        if (logger.isTraceEnabled()) {
            logger.trace("Finished creating instance of bean '" + beanName + "'");
        }
        return beanInstance;
    }
    catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
        // ... [代码部分省略以简化]
    }
    catch (Throwable ex) {
        // ... [代码部分省略以简化]
    }
}
```

在`org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean`方法中,`initializeBean`方法是bean初始化,确保bean是完全配置和准备好的。

```java
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
        throws BeanCreationException {

    // 声明一个对象,后续可能用于存放初始化后的bean或它的代理对象
    Object exposedObject = bean;

    // ... [代码部分省略以简化]
    
    try {
        // ... [代码部分省略以简化]
        
        // bean初始化
        exposedObject = initializeBean(beanName, exposedObject, mbd);
    } 
    catch (Throwable ex) {
        // ... [代码部分省略以简化]
    }

    // 返回创建和初始化后的bean
    return exposedObject;
}
```

在`org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#initializeBean`方法中,如果bean实现了`InitializingBean`接口,则它的`afterPropertiesSet`方法会在此处被调用。此外,如果bean配置中定义了自定义的初始化方法,spring会在这里被调用。

```java
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {

    // ... [代码部分省略以简化]
    
    try {
        invokeInitMethods(beanName, wrappedBean, mbd);
    }
    catch (Throwable ex) {
        // ... [代码部分省略以简化]
    }
    
    // ... [代码部分省略以简化]

    return wrappedBean;
}
```

在`org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#invokeInitMethods`方法中,`afterPropertiesSet`是`InitializingBean`接口中定义的一个特殊的初始化方法。如果bean实现了这个接口,这个方法会在bean的属性被注入之后自动被调用。在这里,为了避免重复调用,Spring会检查bean是否是`InitializingBean`的实例,以及其初始化方法名是否为`afterPropertiesSet`。

```java
protected void invokeInitMethods(String beanName, Object bean, @Nullable RootBeanDefinition mbd)
			throws Throwable {
    // ... [代码部分省略以简化]
    
    // 检查Bean定义是否存在,且bean实例不是一个NullBean(Spring中用于标记占位bean的特殊类型)
    if (mbd != null && bean.getClass() != NullBean.class) {
        // 获取初始化方法名
        String initMethodName = mbd.getInitMethodName();
        // 检查是否有初始化方法需要被调用
        if (StringUtils.hasLength(initMethodName) &&
            // bean不是一个InitializingBean,或者初始化方法名不是"afterPropertiesSet"
            !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
            // 初始化方法没有被外部管理(例如,通过AspectJ的切面)
            !mbd.isExternallyManagedInitMethod(initMethodName)) {
            // 调用自定义的初始化方法
            invokeCustomInitMethod(beanName, bean, mbd);
        }
    }
}
```

在`org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#invokeCustomInitMethod`方法中,使用Java反射API来动态地调用Bean的初始化方法。

```java
protected void invokeCustomInitMethod(String beanName, Object bean, RootBeanDefinition mbd)
			throws Throwable {
	// ... [代码部分省略以简化]

	// 使用反射来调用Bean的初始化方法
    try {
        // 确保要调用的方法是可访问的
        ReflectionUtils.makeAccessible(methodToInvoke);
        // 调用Bean的自定义初始化方法
        methodToInvoke.invoke(bean);
    }
    catch (InvocationTargetException ex) {
        // 如果初始化方法抛出了异常,这里会捕获到,并继续抛出该异常的目标异常
        throw ex.getTargetException();
    }
    // ... [代码部分省略以简化]
}
```

#### @Bean销毁源码分析

首先来看看启动类入口,上下文环境使用`AnnotationConfigApplicationContext`(此类是使用Java注解来配置Spring容器的方式),构造参数我们给定了一个`MyConfiguration`组件类。然后从Spring上下文中获取一个`MyBean`类型的bean,最后调用`context.close()`方法关闭容器。

```java
public class BeanApplication {

    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MyConfiguration.class);
        System.out.println(context.getBean(MyBean.class));
        context.close();
    }
}
```

在`org.springframework.context.support.AbstractApplicationContext#close`方法中,首先是启动了一个同步块,它同步在 `startupShutdownMonitor` 对象上。这确保了在给定时刻只有一个线程可以执行这个块内的代码,防止多线程导致的资源竞争或数据不一致,然后是调用了 `doClose` 方法,最后是为 JVM 注册了一个关闭钩子。

```java
@Override
public void close() {
    synchronized (this.startupShutdownMonitor) {
        doClose();
        // If we registered a JVM shutdown hook, we don't need it anymore now:
        // We've already explicitly closed the context.
        if (this.shutdownHook != null) {
            try {
                Runtime.getRuntime().removeShutdownHook(this.shutdownHook);
            }
            catch (IllegalStateException ex) {
                // ignore - VM is already shutting down
            }
        }
    }
}
```

在`org.springframework.context.support.AbstractApplicationContext#doClose`方法中,又调用了 `destroyBeans` 方法。

```java
protected void doClose() {
    // ... [代码部分省略以简化]
    // Destroy all cached singletons in the context's BeanFactory.
    destroyBeans();
    // ... [代码部分省略以简化]
}
```

在`org.springframework.context.support.AbstractApplicationContext#destroyBeans`方法中,首先是调用了`getBeanFactory()`返回 Spring 的 `BeanFactory` ,然后在获得的 `BeanFactory` 上,调用了 `destroySingletons` 方法,这个方法的目的是销毁所有在 `BeanFactory` 中缓存的单例 beans。

```java
protected void destroyBeans() {
    getBeanFactory().destroySingletons();
}
```

在`org.springframework.beans.factory.support.DefaultListableBeanFactory#destroySingletons`方法中,首先是调用了父类的 `destroySingletons` 方法,为了确保继承自父类的销毁逻辑得到了执行。

```java
@Override
public void destroySingletons() {
    super.destroySingletons();
    updateManualSingletonNames(Set::clear, set -> !set.isEmpty());
    clearByTypeCache();
}
```

在`org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#destroySingletons`方法中,首先是在`disposableBeans` 字段上,从其键集合中获取所有的 bean 名称,并将它们转换为一个字符串数组。`disposableBeans` 可能包含了实现了 `DisposableBean` 接口的 beans,这些 beans 需要在容器销毁时特殊处理,最后倒序循环,从最后一个开始,销毁所有在 `disposableBeans` 列表中的 beans。这样做是为了确保依赖关系正确地处理,beans先被创建的应该后被销毁。

```java
public void destroySingletons() {
    // ... [代码部分省略以简化]
    String[] disposableBeanNames;
    synchronized (this.disposableBeans) {
        disposableBeanNames = StringUtils.toStringArray(this.disposableBeans.keySet());
    }
    for (int i = disposableBeanNames.length - 1; i >= 0; i--) {
        destroySingleton(disposableBeanNames[i]);
    }
    // ... [代码部分省略以简化]
}
```

在`org.springframework.beans.factory.support.DefaultListableBeanFactory#destroySingleton`方法中,首先是调用了父类的 `destroySingleton` 方法,为了确保继承自父类的销毁逻辑得到了执行。

```java
@Override
public void destroySingleton(String beanName) {
    super.destroySingleton(beanName);
    removeManualSingletonName(beanName);
    clearByTypeCache();
}
```

在`org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#destroySingleton`方法中,首先是使用 `synchronized` 关键字在 `disposableBeans` 对象上进行同步,以确保在多线程环境中安全地访问和修改它,从 `disposableBeans` 集合中移除指定名称的 bean,并将其转换为 `DisposableBean` 类型,最后调用`destroyBean`方法执行实际的销毁操作。

```java
public void destroySingleton(String beanName) {
    // Remove a registered singleton of the given name, if any.
    removeSingleton(beanName);

    // Destroy the corresponding DisposableBean instance.
    DisposableBean disposableBean;
    synchronized (this.disposableBeans) {
        disposableBean = (DisposableBean) this.disposableBeans.remove(beanName);
    }
    destroyBean(beanName, disposableBean);
}
```

在`org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#destroyBean`方法中,直接调用 `bean` 的 `destroy` 方法。因为 `bean` 是一个 `DisposableBean` 类型的实例,所以它一定有一个 `destroy` 方法,该方法提供了 bean 的自定义销毁逻辑。

```java
protected void destroyBean(String beanName, @Nullable DisposableBean bean) {
    // ... [代码部分省略以简化]
    // Actually destroy the bean now...
    if (bean != null) {
        try {
            bean.destroy();
        }
        catch (Throwable ex) {
            // ... [代码部分省略以简化]
        }
    }
    // ... [代码部分省略以简化]
}
```

在`org.springframework.beans.factory.support.DisposableBeanAdapter#destroy`方法中,此方法首先检查是否已经为bean指定了一个销毁方法(`destroyMethod`)。如果有,则直接调用`invokeCustomDestroyMethod`方法。如果没有提供具体的方法,但提供了方法的名称(`destroyMethodName`),那么它会尝试根据这个名称找到对应的方法。一旦找到了方法,就会调用`invokeCustomDestroyMethod`方法。

```java
@Override
public void destroy() {
    // ... [代码部分省略以简化]

    // 如果提供了销毁方法(destroyMethod),则直接调用它
    if (this.destroyMethod != null) {
        invokeCustomDestroyMethod(this.destroyMethod);
    }
    // 否则,如果提供了销毁方法的名称(destroyMethodName),则尝试找到对应的方法并调用它
    else if (this.destroyMethodName != null) {
        // 根据方法名确定要调用的销毁方法
        Method methodToInvoke = determineDestroyMethod(this.destroyMethodName);
        if (methodToInvoke != null) {
            // 如果找到了方法,则调用它,但确保使用的是方法的接口版本(如果可能的话)
            invokeCustomDestroyMethod(ClassUtils.getInterfaceMethodIfPossible(methodToInvoke));
        }
    }
}
```

在`org.springframework.beans.factory.support.DisposableBeanAdapter#invokeCustomDestroyMethod`方法中,用于执行自定义的销毁方法。自定义销毁方法是由我们在Spring配置中为bean定义的,用于在bean的生命周期结束时释放资源、清理等。

```java
private void invokeCustomDestroyMethod(final Method destroyMethod) {
    // ... [代码部分省略以简化]
    try {
        if (System.getSecurityManager() != null) {
            // ... [代码部分省略以简化]
        }
        else {
            ReflectionUtils.makeAccessible(destroyMethod);
            destroyMethod.invoke(this.bean, args);
        }
    }
    catch (InvocationTargetException ex) {
        // ... [代码部分省略以简化]
    }
    catch (Throwable ex) {
        // ... [代码部分省略以简化]
    }
}
```

### 八、注意事项

1. **方法名称即Bean名称**
   + 默认情况下,使用`@Bean`注解的方法名称将用作Bean的名称。如果需要自定义bean的名称,可以在`@Bean`注解中指定名称,如`@Bean("customBeanName")`。

2. **返回类型**
   + 确保`@Bean`方法的返回类型与实际创建的bean对象匹配。

3. **调用其他`@Bean`方法**
   + 在一个配置类中,可以调用一个`@Bean`方法来注入另一个`@Bean`方法的结果。这是因为`@Bean`方法在调用时是通过Spring代理进行的,这确保了单例beans的单一实例性。

4. **作用域**
   + 使用`@Scope`注解与`@Bean`一起可以定义Bean的作用域,例如单例(默认)、原型、请求、会话等。

5. **生命周期回调**
   + `@Bean`注解允许指定`initMethod`和`destroyMethod`,这些方法分别在bean初始化和销毁时被调用。

6. **避免重复定义**
   + 确保不在XML和Java配置中同时定义同一个bean。如果必须这样做,确保bean的名称和定义相同,否则会出现不可预测的行为。

7. **慎用`@Lazy`**
   + `@Lazy`注解使得bean在首次请求时才被初始化。如果一个bean需要在应用启动时就初始化,那么不应该标记为延迟初始化。

8. **参数化`@Bean`方法**
   + `@Bean`方法可以接受参数,这些参数会从Spring容器中自动解析。这在创建一个bean依赖于另一个bean时特别有用。

9. **考虑线程安全性**
   + 特别是对于原型作用域的bean,确保bean是线程安全的,或者不会在多个线程之间共享。

10. **使用条件注解**
    + 配合`@Conditional`或其他相关注解,可以在满足某些条件时才创建bean。

11. **`@Bean`与`@Component`的区别**
    + 虽然两者都用于定义bean,但`@Bean`通常用于方法,特别是在Java配置类中,而`@Component`(及其特化:`@Service`、`@Repository`、`@Controller`等)用于类。

12. **注意潜在的循环依赖**
    + 如果两个`@Bean`方法相互调用,可能会出现循环依赖。Spring可以解决单例作用域的bean之间的循环依赖,但不推荐这样做。

13. **配置类应被Spring管理**
    + 确保包含`@Bean`方法的类由Spring管理,并标记为`@Configuration`。这确保`@Bean`方法由Spring的代理调用,从而支持上述提到的特性,如单例保证和循环引用。

### 九、总结

#### 最佳实践总结

1. **应用启动**
   + 使用`AnnotationConfigApplicationContext`可以基于Java注解来启动和配置Spring的上下文。在上述示例中,我们传递了一个Java配置类 `MyConfiguration` 作为参数来初始化这个上下文。

2. **配置类的使用**
   + 使用 `@Configuration` 注解标记配置类,表明这个类包含Spring的bean定义。在配置类中,可以使用 `@Bean` 注解来定义bean。这个注解的方法的名称默认会作为bean的名称,返回的实例则为Spring容器管理的bean实例。

3. **Bean的生命周期**
   + 通过 `@Bean` 注解的 `initMethod` 和 `destroyMethod` 属性,可以为bean定义初始化和销毁时要调用的方法。这为bean提供了一种自定义的初始化和清理机制。当bean被Spring容器实例化时,指定的初始化方法会被调用;当bean被销毁或容器关闭时,指定的销毁方法会被调用。

#### 源码分析总结

1. **@Bean 注册源码分析总结**

   + **启动及配置加载**
     + 使用 `AnnotationConfigApplicationContext` 初始化Spring上下文,并传入 `MyConfiguration` 配置类。该上下文构造函数将执行 `register()` 和 `refresh()` 方法。

   + **Bean定义的解析**
     + `refresh()` 方法触发上下文的刷新,其中涉及到对bean定义的处理。调用 `invokeBeanFactoryPostProcessors()` 方法来处理bean工厂后置处理器。

   + **处理配置类**
     + `BeanDefinitionRegistryPostProcessor` 是特殊的 `BeanFactoryPostProcessor`,它会在所有其他bean定义被加载之前运行。这个流程主要通过 `ConfigurationClassPostProcessor` 实现,该类负责处理标有 `@Configuration` 的类。

   + **解析 `@Bean` 方法**
     + 对每个 `@Configuration` 类执行解析,将其中的 `@Bean` 方法解析为bean定义。这涉及读取方法元数据,并将其转化为一个Spring可以理解和管理的 `BeanDefinition` 对象。

   + **处理bean作用域与代理**
     + 如果在 `@Bean` 方法上有 `@Scope` 注解,会根据其属性处理bean的作用域。根据需要,可能会为bean创建一个代理,这是通过 `ScopedProxyCreator` 来完成的。

   + **bean定义的注册**
     + 最终,解析出的bean定义会被注册到Spring的bean定义注册表中,这样在上下文启动后,这些定义的bean就可以被实例化和使用了。

2. **@Bean初始化源码分析总结**

   + **启动**
     + 当使用`AnnotationConfigApplicationContext`并提供`MyConfiguration`类作为参数时,Spring容器开始初始化。

   + **刷新上下文**
     +  通过调用`refresh()`方法,Spring上下文被刷新。这是在上下文中创建和初始化所有bean的关键阶段。

   + **初始化Bean工厂**
     +  方法`finishBeanFactoryInitialization`会确保所有非懒加载的单例bean都被初始化。它调用`DefaultListableBeanFactory`中的`preInstantiateSingletons`方法,该方法循环遍历容器中定义的每一个单例bean并使用`getBean`方法进行初始化。

   + **获取Bean**:
     + 在获取bean时,首先会检查是否已存在此单例bean。如果不存在,则会创建它。核心方法是`doGetBean`,它管理整个bean的生命周期,从查找bean定义到初始化bean。

   + **单例处理**
     + `getSingleton`方法管理单例bean的缓存。它首先尝试从缓存中获取bean,如果未找到,则使用提供的`ObjectFactory`创建一个新的实例。

   + **创建Bean**
     +  如果需要,`createBean`方法将负责实例化bean。最终,真正的bean创建工作是在`doCreateBean`方法中完成的。

   + **初始化Bean**
     +  一旦bean被实例化,就需要进行初始化。如果bean实现了`InitializingBean`接口,那么它的`afterPropertiesSet`方法会被调用。此外,如果bean配置中定义了自定义的初始化方法,该方法也会在此时被调用。

   + **反射调用**
     + 最终,如果定义了自定义的初始化方法,Spring会使用Java的反射API来调用它。

3. **@Bean销毁源码分析总结**

   + **启动和关闭**
     + 通过`AnnotationConfigApplicationContext`,Spring容器初始化后,`context.close()`方法会被调用以关闭容器。

   + **关闭上下文**
     + `close()`方法首先同步`startupShutdownMonitor`,确保在特定时刻只有一个线程能关闭上下文,接着调用`doClose`方法执行实际关闭操作。

   + **销毁Beans**
     + 在`doClose`方法中,`destroyBeans`方法被调用以销毁所有缓存中的单例bean。

   + **销毁单例Beans**
     + `destroyBeans`方法会调用BeanFactory的`destroySingletons`方法来销毁所有缓存的单例beans。

   + **遍历并销毁**
     + 在`destroySingletons`中,所有缓存的单例bean都会被遍历。对于每一个bean,`destroySingleton`方法会被调用来执行销毁操作。

   + **实际的销毁操作**
     + 在`destroySingleton`中,会从`disposableBeans`列表中移除对应的bean,并执行实际的销毁操作。

   + **自定义销毁逻辑**
     + 如果bean实现了`DisposableBean`接口或者定义了自定义的销毁方法,Spring容器会确保在销毁bean时调用这些方法。销毁方法可以是定义在bean配置中的任何方法,不需要特定的方法签名。

   + **反射调用销毁方法**
     + 最后,Spring使用Java反射API来动态地调用bean的自定义销毁方法。

================================================
FILE: spring-annotation/spring-annotation-bean/pom.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>spring-annotation</artifactId>
        <groupId>com.xcs.spring</groupId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>

    <modelVersion>4.0.0</modelVersion>
    <artifactId>spring-annotation-bean</artifactId>

</project>

================================================
FILE: spring-annotation/spring-annotation-bean/src/main/java/com/xcs/spring/BeanApplication.java
================================================
package com.xcs.spring;

import com.xcs.spring.bean.MyBean;
import com.xcs.spring.config.MyConfiguration;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

/**
 * @author xcs
 * @date 2023年08月07日 16时21分
 **/
public class BeanApplication {

    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MyConfiguration.class);
        System.out.println(context.getBean(MyBean.class));
        context.close();
    }
}


================================================
FILE: spring-annotation/spring-annotation-bean/src/main/java/com/xcs/spring/bean/MyBean.java
================================================
package com.xcs.spring.bean;

/**
 * @author xcs
 * @date 2023年08月25日 10时22分
 **/
public class MyBean {

    public void init(){
        System.out.println("MyBean.init");
    }

    public void destroy(){
        System.out.println("MyBean.destroy");
    }
}


================================================
FILE: spring-annotation/spring-annotation-bean/src/main/java/com/xcs/spring/config/MyConfiguration.java
================================================
package com.xcs.spring.config;

import com.xcs.spring.bean.MyBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @author xcs
 * @date 2023年08月07日 16时25分
 **/
@Configuration
public class MyConfiguration {

    @Bean(initMethod = "init",destroyMethod = "destroy")
    public MyBean myBean(){
        return new MyBean();
    }
}

================================================
FILE: spring-annotation/spring-annotation-componentScan/README.md
================================================
## @ComponentScan

- [@ComponentScan](#componentscan)
  - [一、基本信息](#一基本信息)
  - [二、注解描述](#二注解描述)
  - [三、注解源码](#三注解源码)
  - [四、主要功能](#四主要功能)
  - [五、最佳实践](#五最佳实践)
  - [六、时序图](#六时序图)
  - [七、源码分析](#七源码分析)
  - [八、注意事项](#八注意事项)
  - [九、总结](#九总结)
    - [最佳实践总结](#最佳实践总结)
    - [源码分析总结](#源码分析总结)


### 一、基本信息

✒️ **作者** - Lex 📝 **博客** - [我的CSDN](https://blog.csdn.net/duzhuang2399/article/details/132346179) 📚 **文章目录** - [所有文章](https://github.com/xuchengsheng/spring-reading) 🔗 **源码地址** - [@ComponentScan源码](https://github.com/xuchengsheng/spring-reading/blob/master/spring-annotation/spring-annotation-componentScan/README.md)

### 二、注解描述

`@ComponentScan` 注解,用于自动扫描特定包(和其子包)中的组件,并自动注册为 Spring 容器中的 bean。当我们使用 Spring Boot,它默认会扫描主应用程序所在的包以及子包。但是,如果我们需要更细粒度的控制,或者我们在使用传统的 Spring 而非 Spring Boot,那么我们可能会明确地使用 `@ComponentScan`。

### 三、注解源码

`@ComponentScan`注解是 Spring 框架自 3.1 版本开始引入的一个核心注解,用于指导如何扫描组件。与 `@Configuration` 配合使用,其功能与 Spring XML 的 `<context:component-scan>` 类似。除了允许指定要扫描的包,它还提供了多种属性,如命名生成器、范围解析器、代理设置等,以精细地控制组件的扫描和注册过程。若不指定扫描包,它默认从注解声明的位置开始。与此同时,`@Filter` 注解定义了类型过滤器,特别用于 `@ComponentScan` 中的组件包含和排除设置。它允许基于特定类型、类或模式来筛选组件。

```java
/**
 * 配置 @Configuration 类使用的组件扫描指令。
 * 提供与 Spring XML 的 <context:component-scan> 元素相似的支持。
 *
 * 可以指定 #basePackageClasses 或 #basePackages (或其别名
 * #value }) 来定义要扫描的特定包。如果没有定义特定的包,
 * 则从声明此注解的类的包开始扫描。
 *
 * 注意,<context:component-scan> 元素有一个
 * annotation-config 属性; 但是,此注解没有。这是因为
 * 在几乎所有使用 @ComponentScan 的情况下,默认的注解配置
 * 处理(例如处理 @Autowired 及其朋友们)都是预期的。此外,
 * 使用 AnnotationConfigApplicationContext 时,总是会注册注解配置处理器,
 * 这意味着在 @ComponentScan 级别尝试禁用它们都会被忽略。
 *
 * 有关使用示例,请参见 Configuration @Configuration 的 Javadoc。
 *
 * @author Chris Beams
 * @author Juergen Hoeller
 * @author Sam Brannen
 * @since 3.1
 * @see Configuration
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Repeatable(ComponentScans.class)
public @interface ComponentScan {
    
    /**
	 * #basePackages 的别名。
	 * 如果不需要其他属性,则允许更简洁的注解声明,例如,@ComponentScan("org.my.pkg")
	 * 而不是 @ComponentScan(basePackages = "org.my.pkg")。
	 */
	@AliasFor("basePackages")
	String[] value() default {};

	/**
	 * 扫描带注解的组件的基础包。
	 * #value 是此属性的别名(且与此属性互斥)。
	 * 使用 #basePackageClasses 作为基于类型安全的替代方法
	 * 来指定要扫描注解的组件的包。将扫描每个指定类的包。
	 */
	@AliasFor("value")
	String[] basePackages() default {};

	/**
	 * 指定要扫描的包的类型安全替代方法。每个指定类的包都会被扫描。
	 * 考虑在每个包中创建一个特殊的无操作标记类或接口,
	 * 除了被此属性引用之外,没有其他用途。
	 */
	Class<?>[] basePackageClasses() default {};
    
    /**
	 * 在Spring容器内为检测到的组件命名的 BeanNameGenerator 类。
	 * BeanNameGenerator 接口的默认值表明处理此 @ComponentScan 注解的扫描器
	 * 应使用它的继承的bean命名生成器,例如默认的
	 * AnnotationBeanNameGenerator 或在启动时提供给应用上下文的任何自定义实例。
	 */
	Class<? extends BeanNameGenerator> nameGenerator() default BeanNameGenerator.class;

	/**
	 * 用于解析检测到的组件范围的 ScopeMetadataResolver。
	 */
	Class<? extends ScopeMetadataResolver> scopeResolver() default AnnotationScopeMetadataResolver.class;

	/**
	 * 指示是否应为检测到的组件生成代理,这在以代理风格使用范围时可能是必要的。
	 * 默认值是延迟到执行实际扫描的组件扫描器的默认行为。
	 * 注意,设置此属性会覆盖为 #scopeResolver 设置的任何值。
	 */
	ScopedProxyMode scopedProxy() default ScopedProxyMode.DEFAULT;

	/**
	 * 控制适用于组件检测的类文件。
	 * 考虑使用 #includeFilters 和 #excludeFilters
	 * 来采用更灵活的方法。
	 */
	String resourcePattern() default ClassPathScanningCandidateComponentProvider.DEFAULT_RESOURCE_PATTERN;

	/**
	 * 指示是否应启用使用 @Component @Repository, @Service, 或 @Controller 注解的类的自动检测。
	 */
	boolean useDefaultFilters() default true;

	/**
	 * 指定哪些类型有资格进行组件扫描。
	 * 进一步从 #basePackages 中的所有内容缩小到匹配给定过滤器或过滤器的基包中的所有内容。
	 * 注意,这些过滤器将附加到默认过滤器(如果指定)。即使它与默认过滤器不匹配(例如,没有使用 @Component 注解),
	 * 任何匹配给定过滤器的基包下的类型都将被包括。
	 */
	Filter[] includeFilters() default {};

	/**
	 * 指定哪些类型不适合进行组件扫描。
	 */
	Filter[] excludeFilters() default {};

	/**
	 * 指定是否应注册扫描的beans以进行延迟初始化。
	 * 默认值是 false;如果需要,切换为 true。
	 */
	boolean lazyInit() default false;

	/**
	 * 声明用作 ComponentScan#includeFilters include filter 或 
	 * ComponentScan#excludeFilters exclude filter 的类型过滤器。
	 */
	@Retention(RetentionPolicy.RUNTIME)
	@Target({})
	@interface Filter {

		/**
		 * 要使用的过滤器类型。
		 * 默认为 FilterType#ANNOTATION。
		 * @see #classes
		 * @see #pattern
		 */
		FilterType type() default FilterType.ANNOTATION;

		/**
		 * #classes 的别名。
		 */
		@AliasFor("classes")
		Class<?>[] value() default {};

		/**
		 * 用作过滤器的类或类。
		 * 根据 #type 属性的配置值,以下表格解释了如何解释这些类
		 * ...
		 * 这部分包含了一个表格和其它详细说明,由于格式限制,需要额外的处理来适应中文文档
		 * ...
		 */
		@AliasFor("value")
		Class<?>[] classes() default {};

		/**
		 * 用作过滤器的模式(或模式),作为指定类 #value 的替代。
		 * 如果 #type 设置为 FilterType#ASPECTJ ASPECTJ,这是一个 AspectJ 类型模式表达式。
		 * 如果 #type 设置为 FilterType#REGEX REGEX,这是一个正则模式,用于匹配完全限定的类名。
		 */
		String[] pattern() default {};

	}
}

```

`ScopedProxyMode` 是一个枚举,定义了不同的作用域代理选项,用于决定如何为特定的作用域 bean 创建代理。作用域代理是 Spring 中一个高级特性,允许在不同的上下文中共享 bean 实例,如请求或会话。此枚举的主要用途是为这些作用域 bean 提供不同的代理机制。

```java
/**
 * 枚举各种作用域代理选项。
 *
 * 为了更完整地讨论什么是作用域代理,请查看 Spring 参考文档中标题为 '作为依赖的作用域 beans' 的部分。
 *
 * @author Mark Fisher
 * @since 2.5
 * @see ScopeMetadata
 */
public enum ScopedProxyMode {

	/**
	 * 默认通常等于 #NO,除非在组件扫描指令级别配置了不同的默认值。
	 */
	DEFAULT,

	/**
	 * 不创建一个作用域代理。
	 * <p>当与非单例作用域实例一起使用时,这种代理模式通常不太有用,如果要作为依赖项使用,
	 * 它应该优先使用 #INTERFACES 或 #TARGET_CLASS 代理模式。
	 */
	NO,

	/**
	 * 创建一个JDK动态代理,实现目标对象的类所暴露的所有接口。
	 */
	INTERFACES,

	/**
	 * 创建一个基于类的代理(使用CGLIB)。
	 */
	TARGET_CLASS

}
```

`FilterType` 是一个枚举,定义了与 `@ComponentScan` 注解结合使用时的不同类型过滤器选项。这些过滤器用于决定在组件扫描过程中哪些组件应被包括或排除。

```java
/**
 * 与 ComponentScan @ComponentScan 结合使用的类型过滤器的枚举。
 * 该枚举定义了在组件扫描过程中可以用于过滤组件的不同类型。
 *
 * @author Mark Fisher
 * @author Juergen Hoeller
 * @author Chris Beams
 * @since 2.5
 * @see ComponentScan
 * @see ComponentScan#includeFilters()
 * @see ComponentScan#excludeFilters()
 * @see org.springframework.core.type.filter.TypeFilter
 */
public enum FilterType {

	/**
	 * 过滤带有指定注解的候选项。
	 * @see org.springframework.core.type.filter.AnnotationTypeFilter
	 */
	ANNOTATION,

	/**
	 * 过滤可以赋值给指定类型的候选项。
	 * @see org.springframework.core.type.filter.AssignableTypeFilter
	 */
	ASSIGNABLE_TYPE,

	/**
	 * 过滤与指定的AspectJ类型模式表达式匹配的候选项。
	 * @see org.springframework.core.type.filter.AspectJTypeFilter
	 */
	ASPECTJ,

	/**
	 * 过滤与指定的正则表达式模式匹配的候选项。
	 * @see org.springframework.core.type.filter.RegexPatternTypeFilter
	 */
	REGEX,

	/**
	 * 使用给定的自定义 org.springframework.core.type.filter.TypeFilter 实现来过滤候选项。
	 */
	CUSTOM

}
```

### 四、主要功能

1. **指定扫描的包**
   + 通过 `basePackages` 和 `basePackageClasses` 属性,用户可以明确告诉 Spring 在哪些包中查找带有 `@Component`、`@Service`、`@Repository` 和 `@Controller` 等注解的类。

2. **自动扫描**
   + 如果用户没有明确指定要扫描的包,则默认从声明 `@ComponentScan` 的类所在的包开始进行扫描。

3. **过滤扫描的组件**
   + 通过 `includeFilters` 和 `excludeFilters` 属性,用户可以更精细地控制哪些组件应被扫描或排除。

4. **其他配置**
   + 此注解还提供了其他属性,如 `nameGenerator`(为检测到的组件命名)、`scopeResolver`(解析组件的范围)、`scopedProxy`(是否为组件生成代理)等,以提供更高级的配置。

### 五、最佳实践

首先来看看启动类入口,上下文环境使用`AnnotationConfigApplicationContext`(此类是使用Java注解来配置Spring容器的方式),构造参数我们给定了一个`MyConfiguration`组件类。在初始化上下文后,该程序会遍历并打印所有在 Spring 容器中定义的 beans 的名字。

```java
public class ComponentScanApplication {

    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MyConfiguration.class);
        for (String beanDefinitionName : context.getBeanDefinitionNames()) {
            System.out.println("beanName = " + beanDefinitionName);
        }
    }
}
```

在`MyConfiguration`类中,Spring 扫描 `com.xcs.spring` 包及其子包,包括所有 `SpecialComponent` 类型的组件,但排除所有 `AdminService` 类型的组件。

```java
@Configuration
@ComponentScan(
        basePackages = "com.xcs.spring",
        includeFilters = @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = SpecialComponent.class),
        excludeFilters = @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = AdminService.class)
)
public class MyConfiguration {

}
```

 `UserRepository` 的类,位于 `com.xcs.spring.repository` 包中,并用 `@Repository` 注解标记。

```java
package com.xcs.spring.repository;

@Repository
public class UserRepository {

}
```

`AdminService` 和 `UserService`,它们都位于 `com.xcs.spring.service` 包中并分别用 `@Service` 注解标记。

```java
package com.xcs.spring.service;

@Service
public class AdminService {

}

@Service
public class UserService {

}
```

`SpecialComponent` 的类,它位于 `com.xcs.spring.special` 包中,没有使用spring中的任何注解标记。

```java
package com.xcs.spring.special;

public class SpecialComponent {
    
}
```

运行结果发现,`UserRepository` 将被自动检测并注册为一个 Spring bean,因为它位于我们指定的 `com.xcs.spring` 包路径下。`UserService` 将被自动检测并注册为一个 Spring bean,因为它位于我们指定的 `com.xcs.spring` 包路径下。但是,由于 `@ComponentScan` 配置中使用了 `excludeFilters` 明确排除了 `AdminService`,所以即使 `AdminService` 位于 `com.xcs.spring` 包路径下,它也不会被注册为一个 Spring bean。虽然`SpecialComponent` 类是一个没有任何 Spring 注解的普通 Java 类。但通过使用 `@ComponentScan` 的 `includeFilters` 和 `FilterType.ASSIGNABLE_TYPE`,我们可以强制 Spring 上下文扫描并注册它为一个 bean,即使它没有标记为 `@Component` 或其他 Spring 注解。

```java
beanName = org.springframework.context.annotation.internalConfigurationAnnotationProcessor
beanName = org.springframework.context.annotation.internalAutowiredAnnotationProcessor
beanName = org.springframework.context.event.internalEventListenerProcessor
beanName = org.springframework.context.event.internalEventListenerFactory
beanName = myConfiguration
beanName = userRepository
beanName = userService
beanName = specialComponent
```

### 六、时序图

~~~mermaid
sequenceDiagram
Title: @ComponentScan注解时序图
ComponentScanApplication->>AnnotationConfigApplicationContext:AnnotationConfigApplicationContext(componentClasses)
AnnotationConfigApplicationContext->>AbstractApplicationContext:refresh()
AbstractApplicationContext->>AbstractApplicationContext:invokeBeanFactoryPostProcessors(beanFactory)
AbstractApplicationContext->>PostProcessorRegistrationDelegate:invokeBeanFactoryPostProcessors(beanFactory,beanFactoryPostProcessors)
PostProcessorRegistrationDelegate->>PostProcessorRegistrationDelegate:invokeBeanDefinitionRegistryPostProcessors(postProcessors,registry,applicationStartup) 
PostProcessorRegistrationDelegate->>ConfigurationClassPostProcessor:postProcessBeanDefinitionRegistry(registry)
ConfigurationClassPostProcessor->>ConfigurationClassPostProcessor:processConfigBeanDefinitions(registry)
ConfigurationClassPostProcessor->>ConfigurationClassParser:ConfigurationClassParser(...)
ConfigurationClassParser-->>ConfigurationClassPostProcessor:返回解析解析器
ConfigurationClassPostProcessor->>ConfigurationClassParser:parser.parse(candidates)
ConfigurationClassParser->>ConfigurationClassParser:parse(metadata, String beanName)
ConfigurationClassParser->>ConfigurationClassParser:processConfigurationClass(configClass,filter)
ConfigurationClassParser->>ConfigurationClassParser:doProcessConfigurationClass(configClass,sourceClass,filter)
ConfigurationClassParser->>ComponentScanAnnotationParser:parse(componentScan,declaringClass)
ComponentScanAnnotationParser->>ClassPathBeanDefinitionScanner:ClassPathBeanDefinitionScanner(registry,useDefaultFilters,environment,resourceLoader) 
ClassPathBeanDefinitionScanner->>ClassPathBeanDefinitionScanner:registerDefaultFilters()
ClassPathBeanDefinitionScanner-->>ComponentScanAnnotationParser:返回扫描器
ComponentScanAnnotationParser->>ClassPathBeanDefinitionScanner:doScan(basePackages)
ClassPathBeanDefinitionScanner->>ClassPathScanningCandidateComponentProvider:findCandidateComponents(basePackage)
ClassPathScanningCandidateComponentProvider->>ClassPathScanningCandidateComponentProvider:scanCandidateComponents(basePackage)
ClassPathScanningCandidateComponentProvider-->>ClassPathBeanDefinitionScanner:返回BeanDefinition
ClassPathBeanDefinitionScanner->>ClassPathBeanDefinitionScanner:registerBeanDefinition(definitionHolder,registry)
ClassPathBeanDefinitionScanner->>BeanDefinitionReaderUtils:registerBeanDefinition(definitionHolder, registry)
BeanDefinitionReaderUtils->>DefaultListableBeanFactory:registerBeanDefinition(beanName,beanDefinition)
ClassPathBeanDefinitionScanner-->>ComponentScanAnnotationParser:返回BeanDefinition
~~~

### 七、源码分析

首先来看看启动类入口,上下文环境使用`AnnotationConfigApplicationContext`(此类是使用Java注解来配置Spring容器的方式),构造参数我们给定了一个`MyConfiguration`组件类。在初始化上下文后,该程序会遍历并打印所有在 Spring 容器中定义的 beans 的名字。

```java
public class ComponentScanApplication {

    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MyConfiguration.class);
        for (String beanDefinitionName : context.getBeanDefinitionNames()) {
            System.out.println("beanName = " + beanDefinitionName);
        }
    }
}
```

在`org.springframework.context.annotation.AnnotationConfigApplicationContext#AnnotationConfigApplicationContext`构造函数中,执行了三个步骤,我们重点关注`refresh()`方法。

```java
public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
    this();
    register(componentClasses);
    refresh();
}
```

在`org.springframework.context.support.AbstractApplicationContext#refresh`方法中我们重点关注一下`finishBeanFactoryInitialization(beanFactory)`这方法会对实例化所有剩余非懒加载的单列Bean对象,其他方法不是本次源码阅读的重点暂时忽略。

```java
@Override
public void refresh() throws BeansException, IllegalStateException {
     // ... [代码部分省略以简化]
     // 调用在上下文中注册为bean的工厂处理器
     invokeBeanFactoryPostProcessors(beanFactory);
     // ... [代码部分省略以简化]
}
```

在`org.springframework.context.support.AbstractApplicationContext#invokeBeanFactoryPostProcessors`方法中,又委托了`PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors()`进行调用。

```java
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
    PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
    // ... [代码部分省略以简化]
}
```

在`org.springframework.context.support.PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors`方法中,首先调用了 `BeanDefinitionRegistryPostProcessor`(这是 `BeanFactoryPostProcessor` 的子接口)。它专门用来在所有其他 bean 定义加载之前修改默认的 bean 定义。

```java
public static void invokeBeanFactoryPostProcessors(
        ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
    // ... [代码部分省略以简化]
    invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
	// ... [代码部分省略以简化]
}
```

在`org.springframework.context.support.PostProcessorRegistrationDelegate#invokeBeanDefinitionRegistryPostProcessors`方法中,循环调用了实现`BeanDefinitionRegistryPostProcessor`接口中的`postProcessBeanDefinitionRegistry(registry)`方法

```java
private static void invokeBeanDefinitionRegistryPostProcessors(
			Collection<? extends BeanDefinitionRegistryPostProcessor> postProcessors, BeanDefinitionRegistry registry, ApplicationStartup applicationStartup) {

    for (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) {
        StartupStep postProcessBeanDefRegistry = applicationStartup.start("spring.context.beandef-registry.post-process")
            .tag("postProcessor", postProcessor::toString);
        postProcessor.postProcessBeanDefinitionRegistry(registry);
        postProcessBeanDefRegistry.end();
    }
}
```

在`org.springframework.context.annotation.ConfigurationClassPostProcessor#postProcessBeanDefinitionRegistry`方法中,调用了`processConfigBeanDefinitions`方法,该方法的主要目的是处理和注册配置类中定义的beans。

```java
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
    // ... [代码部分省略以简化]
    processConfigBeanDefinitions(registry);
}
```

在`org.springframework.context.annotation.ConfigurationClassPostProcessor#processConfigBeanDefinitions`方法中,这个方法主要处理了配置类的解析和验证,并确保了所有在配置类中定义的beans都被正确地注册到Spring的bean定义注册表中。

```java
public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
    // ... [代码部分省略以简化]

    // 步骤1:创建一个用于解析配置类的解析器
    ConfigurationClassParser parser = new ConfigurationClassParser(
            this.metadataReaderFactory, this.problemReporter, this.environment,
            this.resourceLoader, this.componentScanBeanNameGenerator, registry);

    // 步骤2:初始化候选配置类集合以及已解析配置类集合
    Set<BeanDefinitionHolder> candidates = new LinkedHashSet<>(configCandidates);
    Set<ConfigurationClass> alreadyParsed = new HashSet<>(configCandidates.size());

    // 步骤3:循环处理所有候选配置类,直至没有候选类为止
    do {
        // 步骤3.1 解析配置类
        parser.parse(candidates);
        // 步骤3.2 验证配置类
        parser.validate();

        // 获取解析后的配置类,并从中移除已经处理过的
        Set<ConfigurationClass> configClasses = new LinkedHashSet<>(parser.getConfigurationClasses());
        configClasses.removeAll(alreadyParsed);

        // 步骤4:如果reader为空,则创建一个新的Bean定义读取器
        if (this.reader == null) {
            this.reader = new ConfigurationClassBeanDefinitionReader(
                    registry, this.sourceExtractor, this.resourceLoader, this.environment,
                    this.importBeanNameGenerator, parser.getImportRegistry());
        }

        // 步骤5:使用读取器为解析的配置类加载Bean定义
        this.reader.loadBeanDefinitions(configClasses);

        // ... [代码部分省略以简化]
        
    } while (!candidates.isEmpty());

    // ... [代码部分省略以简化]
}
```

在`org.springframework.context.annotation.ConfigurationClassParser#parse`方法中,主要是遍历所有的配置类候选者,并对每一个带有注解的Bean定义进行解析。这通常涉及到查找该配置类中的@Bean方法、组件扫描指令等,并将这些信息注册到Spring容器中。

```java
public void parse(Set<BeanDefinitionHolder> configCandidates) {
    // ... [代码部分省略以简化]
    parse(((AnnotatedBeanDefinition) bd).getMetadata(), holder.getBeanName());
    // ... [代码部分省略以简化]
}
```

在`org.springframework.context.annotation.ConfigurationClassParser#parse(metadata, beanName)`方法中,将注解元数据和Bean名称转化为一个配置类,然后对其进行处理。处理配置类是Spring配置驱动的核心,它涉及到许多关键操作,如处理`@ComponentScan`注解等等。

```java
protected final void parse(AnnotationMetadata metadata, String beanName) throws IOException {
    processConfigurationClass(new ConfigurationClass(metadata, beanName), DEFAULT_EXCLUSION_FILTER);
}
```

在`org.springframework.context.annotation.ConfigurationClassParser#processConfigurationClass`方法中,处理一个给定的配置类。它首先递归地处理配置类及其父类,以确保所有相关的配置都被正确地读取并解析。在递归处理完所有相关配置后,它将配置类添加到已解析的配置类的映射中。

```java
protected void processConfigurationClass(ConfigurationClass configClass, Predicate<String> filter) throws IOException {
    // ... [代码部分省略以简化]

    // 步骤1:递归地处理配置类及其超类层次结构
    SourceClass sourceClass = asSourceClass(configClass, filter);
    do {
        sourceClass = doProcessConfigurationClass(configClass, sourceClass, filter);
    } while (sourceClass != null);

    // 步骤2:将处理后的配置类放入映射中
    this.configurationClasses.put(configClass, configClass);
}
```

在`org.springframework.context.annotation.ConfigurationClassParser#doProcessConfigurationClass`方法中,这个方法的目标是处理和解析标有 `@Configuration` 的类,执行组件扫描,并确保所有相关的配置类都被递归地解析。

```java
@Nullable
protected final SourceClass doProcessConfigurationClass(
    ConfigurationClass configClass, SourceClass sourceClass, Predicate<String> filter)
    throws IOException {
    
    // ... [代码部分省略以简化]

    // 处理任何 @ComponentScan 注解
    // 获取当前类(sourceClass)的所有 @ComponentScan 和 @ComponentScans 注解的属性
    Set<AnnotationAttributes> componentScans = AnnotationConfigUtils.attributesForRepeatable(
        sourceClass.getMetadata(), ComponentScans.class, ComponentScan.class);

    // 如果存在 @ComponentScan 或 @ComponentScans 注解,并且该类没有被条件评估排除
    if (!componentScans.isEmpty() &&
        !this.conditionEvaluator.shouldSkip(sourceClass.getMetadata(), ConfigurationPhase.REGISTER_BEAN)) {
        // 遍历每一个 @ComponentScan 注解
        for (AnnotationAttributes componentScan : componentScans) {
            // 对标有 @ComponentScan 的配置类进行立即扫描
            Set<BeanDefinitionHolder> scannedBeanDefinitions =
                this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName());

            // 检查扫描到的定义中是否有任何进一步的配置类,如果需要,则递归解析
            for (BeanDefinitionHolder holder : scannedBeanDefinitions) {
                BeanDefinition bdCand = holder.getBeanDefinition().getOriginatingBeanDefinition();
                if (bdCand == null) {
                    bdCand = holder.getBeanDefinition();
                }
                // 检查 BeanDefinition 是否是一个配置类的候选者
                if (ConfigurationClassUtils.checkConfigurationClassCandidate(bdCand, this.metadataReaderFactory)) {
                    // 如果是,递归解析它
                    parse(bdCand.getBeanClassName(), holder.getBeanName());
                }
            }
        }
    }
    
    // ... [代码部分省略以简化]

    // 没有父类 -> 处理完成
    return null;
}
```

在`org.springframework.context.annotation.ComponentScanAnnotationParser#parse`方法中,主要目的是为 `@ComponentScan` 配置的类提供了详细的处理,并指导了如何根据给定的属性配置和执行组件扫描。

```java
public Set<BeanDefinitionHolder> parse(AnnotationAttributes componentScan, final String declaringClass) {
    // 步骤1. 创建一个新的扫描器
    ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(this.registry,
             componentScan.getBoolean("useDefaultFilters"), this.environment, this.resourceLoader);

    // 步骤2. 根据nameGenerator属性设置Bean名称生成器
    Class<? extends BeanNameGenerator> generatorClass = componentScan.getClass("nameGenerator");
    boolean useInheritedGenerator = (BeanNameGenerator.class == generatorClass);
    scanner.setBeanNameGenerator(useInheritedGenerator ? this.beanNameGenerator :
                                 BeanUtils.instantiateClass(generatorClass));

    // 步骤3. 设置作用域代理模式或者作用域元数据解析器
    ScopedProxyMode scopedProxyMode = componentScan.getEnum("scopedProxy");
    if (scopedProxyMode != ScopedProxyMode.DEFAULT) {
        scanner.setScopedProxyMode(scopedProxyMode);
    }
    else {
        Class<? extends ScopeMetadataResolver> resolverClass = componentScan.getClass("scopeResolver");
        scanner.setScopeMetadataResolver(BeanUtils.instantiateClass(resolverClass));
    }

    // 步骤4. 设置资源模式
    scanner.setResourcePattern(componentScan.getString("resourcePattern"));

    // 步骤5. 根据includeFilters和excludeFilters属性添加类型过滤器
    for (AnnotationAttributes filter : componentScan.getAnnotationArray("includeFilters")) {
        for (TypeFilter typeFilter : typeFiltersFor(filter)) {
            scanner.addIncludeFilter(typeFilter);
        }
    }
    for (AnnotationAttributes filter : componentScan.getAnnotationArray("excludeFilters")) {
        for (TypeFilter typeFilter : typeFiltersFor(filter)) {
            scanner.addExcludeFilter(typeFilter);
        }
    }

    // 步骤6. 设置bean是否为懒加载
    boolean lazyInit = componentScan.getBoolean("lazyInit");
    if (lazyInit) {
        scanner.getBeanDefinitionDefaults().setLazyInit(true);
    }

    // 步骤7. 确定扫描器的基础包
    Set<String> basePackages = new LinkedHashSet<>();
    String[] basePackagesArray = componentScan.getStringArray("basePackages");
    for (String pkg : basePackagesArray) {
        String[] tokenized = StringUtils.tokenizeToStringArray(this.environment.resolvePlaceholders(pkg),
                                                               ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS);
        Collections.addAll(basePackages, tokenized);
    }
    for (Class<?> clazz : componentScan.getClassArray("basePackageClasses")) {
        basePackages.add(ClassUtils.getPackageName(clazz));
    }
    if (basePackages.isEmpty()) {
        basePackages.add(ClassUtils.getPackageName(declaringClass));
    }

    // 步骤8. 确保声明@ComponentScan的类本身不被注册为bean
    scanner.addExcludeFilter(new AbstractTypeHierarchyTraversingFilter(false, false) {
        @Override
        protected boolean matchClassName(String className) {
            return declaringClass.equals(className);
        }
    });
    
    // 步骤9. 使用配置好的扫描器执行实际的组件扫描
    return scanner.doScan(StringUtils.toStringArray(basePackages));
}
```

我们来到`org.springframework.context.annotation.ComponentScanAnnotationParser#parse`方法中的步骤1。在`org.springframework.context.annotation.ClassPathBeanDefinitionScanner#ClassPathBeanDefinitionScanner`方法中,首先在这个构造方法初始化了一个新的`ClassPathBeanDefinitionScanner`对象,根据传入的参数决定是否使用默认过滤器,并设置了其环境和资源加载器。

```java
public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters,
			Environment environment, @Nullable ResourceLoader resourceLoader) {

    // 断言确保注册表不为空
    Assert.notNull(registry, "BeanDefinitionRegistry must not be null");

    // 将传入的BeanDefinitionRegistry赋值给成员变量registry
    this.registry = registry;

    // 根据useDefaultFilters决定是否注册默认的过滤器
    if (useDefaultFilters) {
        registerDefaultFilters();
    }

    // 设置扫描器的环境
    setEnvironment(environment);

    // 设置资源加载器
    setResourceLoader(resourceLoader);
}
```

在`org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider#registerDefaultFilters`方法中,此方法主要用于注册默认的类型过滤器。它首先注册了用于查找带有`@Component`注解的类的过滤器。然后,它尝试注册两个JSR标准的注解过滤器:JSR-250的`@ManagedBean`和JSR-330的`@Named`。如果相关的类不在类路径上,那么这两个过滤器将不会被注册。

```java
protected void registerDefaultFilters() {
    // 添加一个过滤器来包括带有@Component注解的类
    this.includeFilters.add(new AnnotationTypeFilter(Component.class));

    // 获取当前类的类加载器
    ClassLoader cl = ClassPathScanningCandidateComponentProvider.class.getClassLoader();
    
    try {
        // 尝试添加一个过滤器来包括带有JSR-250 'javax.annotation.ManagedBean'注解的类
        this.includeFilters.add(new AnnotationTypeFilter(
            ((Class<? extends Annotation>) ClassUtils.forName("javax.annotation.ManagedBean", cl)), false));
        logger.trace("JSR-250 'javax.annotation.ManagedBean' found and supported for component scanning");
    }
    catch (ClassNotFoundException ex) {
        // 如果JSR-250 1.1 API(如Java EE 6中包含的)不可用,仅仅跳过
    }
    
    try {
        // 尝试添加一个过滤器来包括带有JSR-330 'javax.inject.Named'注解的类
        this.includeFilters.add(new AnnotationTypeFilter(
            ((Class<? extends Annotation>) ClassUtils.forName("javax.inject.Named", cl)), false));
        logger.trace("JSR-330 'javax.inject.Named' annotation found and supported for component scanning");
    }
    catch (ClassNotFoundException ex) {
        // 如果JSR-330 API不可用,仅仅跳过
    }
}
```

我们来到`org.springframework.context.annotation.ComponentScanAnnotationParser#parse`方法中的步骤9。在`org.springframework.context.annotation.ClassPathBeanDefinitionScanner#doScan`方法中,主要目标是找到指定`basePackages`中所有的组件,并为它们创建 `BeanDefinition`。这些 `BeanDefinition` 之后会被 Spring 容器用来创建实际的 bean 实例。

```java
protected Set<BeanDefinitionHolder> doScan(String... basePackages) {
    // 断言确保至少有一个基础包被指定
    Assert.notEmpty(basePackages, "At least one base package must be specified");

    // 用于保存找到的bean定义的集合
    Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet<>();

    // 遍历每个基础包
    for (String basePackage : basePackages) {
        // 步骤1. 在给定的基础包中找到所有候选的bean定义
        Set<BeanDefinition> candidates = findCandidateComponents(basePackage);

        // 遍历找到的bean定义
        for (BeanDefinition candidate : candidates) {
            // 步骤2. 解析bean的作用域元数据
            ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate);
            // 设置bean的作用域
            candidate.setScope(scopeMetadata.getScopeName());
            // 步骤3. 生成bean的名字
            String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry);

            // 步骤4. 如果是AbstractBeanDefinition,进行后处理
            if (candidate instanceof AbstractBeanDefinition) {
                postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName);
            }

            // 步骤5. 如果是AnnotatedBeanDefinition,处理常见的注解定义
            if (candidate instanceof AnnotatedBeanDefinition) {
                AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate);
            }

            // 步骤6. 检查给定的bean名字是否已经存在,如果不存在,进行注册
            if (checkCandidate(beanName, candidate)) {
                BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);
                // 步骤7. 应用作用域代理模式,如有必要为bean创建代理
                definitionHolder =
                    AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
                // 将bean定义加入集合中
                beanDefinitions.add(definitionHolder);
                // 步骤8. 在bean注册表中注册bean定义
                registerBeanDefinition(definitionHolder, this.registry);
            }
        }
    }
    // 返回所有注册的bean定义
    return beanDefinitions;
}
```

我们来到`org.springframework.context.annotation.ClassPathBeanDefinitionScanner#doScan`方法中的步骤1。在`org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider#findCandidateComponents`方法中,主要提供了两种方式查找组件:通过预先生成的索引(如果可用且支持)或通过传统的扫描方式(我们重点关注传统的扫描方式)。

```java
public Set<BeanDefinition> findCandidateComponents(String basePackage) {
    // 如果存在组件索引并且支持include过滤器
    if (this.componentsIndex != null && indexSupportsIncludeFilters()) {
        // 从索引中添加候选组件
        return addCandidateComponentsFromIndex(this.componentsIndex, basePackage);
    } 
    else {
        // 扫描给定基础包中的候选组件
        return scanCandidateComponents(basePackage);
    }
}
```

在`org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider#scanCandidateComponents`方法中,首先是构建搜索路径,用于在类路径中搜索指定包,然后是扫描类路径,获取匹配的资源(通常是 `.class` 文件),再然后是对于每个资源,检查是否是候选组件,例如是否有 `@Component` 注解,最后对于是候选组件的类,创建一个 `BeanDefinition` 对象并添加到结果集中。

```java
private Set<BeanDefinition> scanCandidateComponents(String basePackage) {
    // 用于保存候选的Bean定义
    Set<BeanDefinition> candidates = new LinkedHashSet<>();
    try {
        // 构建包搜索路径,例如:"classpath*:com/example/*"
        String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX +
            resolveBasePackage(basePackage) + '/' + this.resourcePattern;

        // 使用模式解析器获取所有匹配的资源(即.class文件)
        Resource[] resources = getResourcePatternResolver().getResources(packageSearchPath);
        
        // ... [代码部分省略以简化]
        
        for (Resource resource : resources) {
            // ... [代码部分省略以简化]
            // 检查资源是否可读
            if (resource.isReadable()) {
                try {
                    // 使用元数据读取器获取类的元数据
                    MetadataReader metadataReader = getMetadataReaderFactory().getMetadataReader(resource);
                    // 检查类是否是候选组件(例如,是否带有@Component注释)
                    if (isCandidateComponent(metadataReader)) {
                        ScannedGenericBeanDefinition sbd = new ScannedGenericBeanDefinition(metadataReader);
                        sbd.setSource(resource);
                        // 再次检查Bean定义是否是候选组件
                        if (isCandidateComponent(sbd)) {
                            // ... [代码部分省略以简化]
                            candidates.add(sbd);
                        } 
                        else {
                            // ... [代码部分省略以简化]
                        }
                    } 
                    else {
                        // ... [代码部分省略以简化]
                    }
                }
                catch (Throwable ex) {
                    // ... [代码部分省略以简化]
                }
            } 
            else {
                // ... [代码部分省略以简化]
            }
        }
    }
    catch (IOException ex) {
        // ... [代码部分省略以简化]
    }
    return candidates;
}
```

在`org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider#isCandidateComponent`方法中,首先确保类不在排除列表中,然后检查它是否在包含列表中,并确保它满足任何其他指定条件。

```java
protected boolean isCandidateComponent(MetadataReader metadataReader) throws IOException {
    // 遍历所有的排除过滤器
    for (TypeFilter tf : this.excludeFilters) {
        // 如果当前类与任一排除过滤器匹配,则直接返回false,说明不是候选组件
        if (tf.match(metadataReader, getMetadataReaderFactory())) {
            return false;
        }
    }

    // 遍历所有的包含过滤器
    for (TypeFilter tf : this.includeFilters) {
        // 如果当前类与任一包含过滤器匹配
        if (tf.match(metadataReader, getMetadataReaderFactory())) {
            // 判断该组件是否满足特定的条件
            return isConditionMatch(metadataReader);
        }
    }

    // 默认返回false,说明不是候选组件
    return false;
}
```

我们来到`org.springframework.context.annotation.ClassPathBeanDefinitionScanner#doScan`方法中的步骤6。在org.springframework.context.annotation.ClassPathBeanDefinitionScanner#checkCandidate方法中,确保Spring容器中没有重名的、不兼容的bean定义。

```java
protected boolean checkCandidate(String beanName, BeanDefinition beanDefinition) throws IllegalStateException {
    // 检查bean定义注册表中是否已包含给定名称的bean定义
    if (!this.registry.containsBeanDefinition(beanName)) {
        return true;  // 如果不存在相同名称的bean定义,则返回true
    }

    // 获取已存在的bean定义
    BeanDefinition existingDef = this.registry.getBeanDefinition(beanName);

    // 获取原始的bean定义(如果有的话)
    BeanDefinition originatingDef = existingDef.getOriginatingBeanDefinition();
    if (originatingDef != null) {
        existingDef = originatingDef;
    }

    // 检查给定的bean定义与已存在的bean定义是否兼容
    if (isCompatible(beanDefinition, existingDef)) {
        return false;  // 如果它们是兼容的,则返回false
    }

    // 如果给定的bean定义与已存在的bean定义不兼容,则抛出异常
    throw new ConflictingBeanDefinitionException("Annotation-specified bean name '" + beanName +
                                                 "' for bean class [" + beanDefinition.getBeanClassName() + "] conflicts with existing, " +
                                                 "non-compatible bean definition of same name and class [" + existingDef.getBeanClassName() + "]");
}
```

我们来到`org.springframework.context.annotation.ClassPathBeanDefinitionScanner#doScan`方法中的步骤8。在`org.springframework.context.annotation.ClassPathBeanDefinitionScanner#registerBeanDefinition`方法中,主要调用 `BeanDefinitionReaderUtils` 类的 `registerBeanDefinition` 方法,用于实际的 `BeanDefinition` 注册过程。

```java
protected void registerBeanDefinition(BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry) {
	BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, registry);
}
```

在`org.springframework.beans.factory.support.BeanDefinitionReaderUtils#registerBeanDefinition`方法中,主要用于将提供的 `BeanDefinitionHolder` 中的 `BeanDefinition` 及其所有别名注册到 `BeanDefinitionRegistry` 中。对于`@ComponentScan`的扫描和注册阶段而言,当`registerBeanDefinition`方法被调用时,已经完成了。但对于整个Spring容器的生命周期来说,还有其他重要的步骤将在后续发生,如bean的生命周期回调、bean的实例化、bean的初始化等。

```java
public static void registerBeanDefinition(
    BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
    throws BeanDefinitionStoreException {

    // 获取 bean 的主名称,并在 registry 中注册它
    String beanName = definitionHolder.getBeanName();
    registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());

    // 如果提供了 bean 的别名,则注册这些别名
    String[] aliases = definitionHolder.getAliases();
    if (aliases != null) {
        for (String alias : aliases) {
            registry.registerAlias(beanName, alias);
        }
    }
}
```

### 八、注意事项

**默认扫描**

+ 如果未指定具体的包,`@ComponentScan` 默认会扫描声明此注解的类所在的包及其子包。

**性能考虑**

+ 避免扫描不必要的包,因为这可能导致性能问题。尤其是在大型项目中,指定扫描的精确路径可以加速启动时间。

**默认过滤器**

+ 默认情况下,`@ComponentScan` 使用的过滤器会搜索带有 `@Component`, `@Service`, `@Repository`, 和 `@Controller` 的类。可以通过 `includeFilters` 和 `excludeFilters` 属性进行定制。

**冲突的 Bean 名称**

+ 确保没有重复的 Bean 名称,否则可能会导致 `BeanDefinitionStoreException`。

**使用 `basePackages` 和 `basePackageClasses`**

+ `basePackages` 允许我们指定要扫描的包的名称,而 `basePackageClasses` 允许我们指定一个或多个类,Spring 将扫描这些类所在的包。

**避免使用多个配置**

+ 不建议在同一个配置类中使用多个 `@ComponentScan`。如果确实需要,考虑使用 `@ComponentScans`。

**代理模式**

+ 考虑如何使用 `scopedProxy` 属性,特别是当我们使用非单例作用域的 beans 时。

**注解属性的覆盖**

+ 当多个 `@ComponentScan` 在多个配置类中定义时,后面的定义将覆盖前面的定义。这里需要我们自己去确认。

**对于大型项目,考虑使用模块化**

+ 在大型项目中,为了更好的管理和维护,可以考虑将应用分成多个模块,每个模块有其自己的配置类和 `@ComponentScan`。

### 九、总结

#### 最佳实践总结

1. **应用启动**
   + 在 `ComponentScanApplication` 的主方法中,使用 `AnnotationConfigApplicationContext` 初始化了 Spring 上下文,并将配置类 `MyConfiguration` 传递给它。这告诉 Spring 在 `MyConfiguration` 类中查找配置信息。
2. **配置类**
   + `MyConfiguration` 类被标记为 `@Configuration`,表明它是一个配置类。这个类进一步使用 `@ComponentScan` 注解指定了 Spring 应该在哪里寻找组件。具体来说,Spring 将扫描 `com.xcs.spring` 包及其所有子包。
3. **扫描规则**
   + 在 `@ComponentScan` 中,我们使用 `includeFilters` 明确指定 `SpecialComponent` 类被包含在 Spring 容器中,即使它没有使用任何 Spring 注解。同时,使用 `excludeFilters` 指定 `AdminService` 类不应该被 Spring 容器管理,即使它被标记为一个 `@Service`。
4. **组件类**:
   - `UserRepository` 类在 `com.xcs.spring.repository` 包中,并被标记为 `@Repository`,因此它自动被 Spring 容器管理。
   - `UserService` 类在 `com.xcs.spring.service` 包中,并被标记为 `@Service`,因此它也自动被 Spring 容器管理。
   - `AdminService` 虽然也被标记为 `@Service`,但由于 `@ComponentScan` 的 `excludeFilters` 配置,它没有被 Spring 容器管理。
   - `SpecialComponent` 类没有使用任何 Spring 注解,但由于 `@ComponentScan` 的 `includeFilters` 配置,它被 Spring 容器管理。
5. **运行结果**
   + 当应用启动时,所有被 Spring 容器管理的 beans 的名字都被打印出来,这包括了 `UserRepository`, `UserService`, 和 `SpecialComponent`。不包括 `AdminService`,因为它被排除了。

#### 源码分析总结

1. **应用启动**
   + 通过 `AnnotationConfigApplicationContext` 的构造方法,传入配置类 `MyConfiguration`,来启动Spring应用。
2. **刷新上下文**
   + 在构造方法内部,调用了 `refresh()` 方法开始执行容器的刷新操作。
3. **执行BeanFactory的后处理器**
   + `invokeBeanFactoryPostProcessors(beanFactory)` 方法被调用,它主要执行 `BeanDefinitionRegistryPostProcessor` 和 `BeanFactoryPostProcessor`。其中, `BeanDefinitionRegistryPostProcessor` 是在所有其他bean定义加载之前,用来修改默认的bean定义。
4. **处理配置类**
   + `ConfigurationClassPostProcessor` 是一个核心的后处理器,它会解析配置类(如带有 `@Configuration` 的类),找到 `@ComponentScan` 注解并解析它的属性,然后进行组件扫描。
5. **执行组件扫描**
   + 通过 `ComponentScanAnnotationParser` 类进行详细的扫描操作。它创建一个 `ClassPathBeanDefinitionScanner` 对象,设置其属性(如是否使用默认过滤器、资源加载器、作用域解析器、资源模式、包含和排除的过滤器等),然后扫描指定的基础包。
6. **扫描候选组件**
   + 对于每个基础包,它会查找所有的组件,并为这些组件创建 `BeanDefinition` 对象。
7. **注册Bean定义**
   + 找到的组件都会被注册到Spring容器中。这是通过调用 `registerBeanDefinition` 方法来完成的。如果在容器中已存在同名的bean定义,会进行冲突检查。
8. **完成组件扫描**
   + 当所有的基础包都被扫描完成,`@ComponentScan` 的操作就执行结束了。

================================================
FILE: spring-annotation/spring-annotation-componentScan/pom.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>spring-annotation</artifactId>
        <groupId>com.xcs.spring</groupId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>

    <modelVersion>4.0.0</modelVersion>

    <artifactId>spring-annotation-componentScan</artifactId>

</project>

================================================
FILE: spring-annotation/spring-annotation-componentScan/src/main/java/com/xcs/spring/ComponentScanApplication.java
================================================
package com.xcs.spring;

import com.xcs.spring.config.MyConfiguration;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

/**
 * @author xcs
 * @date 2023年08月07日 16时21分
 **/
public class ComponentScanApplication {

    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MyConfiguration.class);
        for (String beanDefinitionName : context.getBeanDefinitionNames()) {
            System.out.println("beanName = " + beanDefinitionName);
        }
    }
}


================================================
FILE: spring-annotation/spring-annotation-componentScan/src/main/java/com/xcs/spring/config/MyConfiguration.java
================================================
package com.xcs.spring.config;

import com.xcs.spring.service.AdminService;
import com.xcs.spring.special.SpecialComponent;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;

/**
 * @author xcs
 * @date 2023年08月07日 16时25分
 **/
@Configuration
@ComponentScan(
        basePackages = "com.xcs.spring",
        includeFilters = @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = SpecialComponent.class),
        excludeFilters = @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = AdminService.class)
)
public class MyConfiguration {

}


================================================
FILE: spring-annotation/spring-annotation-componentScan/src/main/java/com/xcs/spring/repository/UserRepository.java
================================================
package com.xcs.spring.repository;

import org.springframework.stereotype.Repository;

/**
 * @author xcs
 * @date 2023年10月07日 11时51分
 **/
@Repository
public class UserRepository {

}


================================================
FILE: spring-annotation/spring-annotation-componentScan/src/main/java/com/xcs/spring/service/AdminService.java
================================================
package com.xcs.spring.service;

import org.springframework.stereotype.Service;

/**
 * @author xcs
 * @date 2023年10月07日 11时51分
 **/
@Service
public class AdminService {

}


================================================
FILE: spring-annotation/spring-annotation-componentScan/src/main/java/com/xcs/spring/service/UserService.java
================================================
package com.xcs.spring.service;

import org.springframework.stereotype.Service;

/**
 * @author xcs
 * @date 2023年10月07日 11时50分
 **/
@Service
public class UserService {

}


================================================
FILE: spring-annotation/spring-annotation-componentScan/src/main/java/com/xcs/spring/special/SpecialComponent.java
================================================
package com.xcs.spring.special;

/**
 * @author xcs
 * @date 2023年10月07日 11时52分
 **/
public class SpecialComponent {
}


================================================
FILE: spring-annotation/spring-annotation-conditional/README.md
================================================
## @Conditional

- [@Conditional](#conditional)
  - [一、基本信息](#一基本信息)
  - [二、注解描述](#二注解描述)
  - [三、注解源码](#三注解源码)
  - [四、主要功能](#四主要功能)
  - [五、最佳实践](#五最佳实践)
    - [在@Bean上使用](#在bean上使用)
    - [在@Configuration上使用](#在configuration上使用)
    - [自定义组合注解](#自定义组合注解)
  - [六、时序图](#六时序图)
  - [七、源码分析](#七源码分析)
  - [八、注意事项](#八注意事项)
  - [九、总结](#九总结)
    - [最佳实践总结](#最佳实践总结)
    - [源码分析总结](#源码分析总结)


### 一、基本信息

✒️ **作者** - Lex 📝 **博客** - [我的CSDN](https://blog.csdn.net/duzhuang2399/article/details/133800722) 📚 **文章目录** - [所有文章](https://github.com/xuchengsheng/spring-reading) 🔗 **源码地址** - [@Conditional源码](https://github.com/xuchengsheng/spring-reading/tree/master/spring-annotation/spring-annotation-conditional)

### 二、注解描述

`@Conditional`注解,是用来基于满足某些特定条件来决定一个Bean是否应该被注册到Spring容器的。这提供了一种灵活的方式来根据环境、配置或其他因素来决定是否激活或者创建某个Bean。

### 三、注解源码

`@Conditional`注解是 Spring 框架自 3.0 版本开始引入的一个核心注解,用于指示一个组件只在所有指定条件匹配时才能被注册。

```java
/**
 * 表明只有当所有指定的条件都满足时,组件才有资格被注册。
 *
 * 条件是可以在bean定义被注册前以编程方式确定的任何状态(参考 Condition 获取详情)。
 *
 * @Conditional 注解可以以下列方式使用:
 * 
 * 作为直接或间接使用 @Component 注解的任何类的类型级别注解,包括 Configuration @Configuration 类
 * 作为元注解,用于组合自定义的范型注解
 * 作为任何 Bean @Bean 方法的方法级别注解
 * 
 *
 * 如果一个 @Configuration 类标记为 @Conditional,与该类关联的所有 @Bean 方法、Import @Import 注解,
 * 和 ComponentScan @ComponentScan 注解都将受到这些条件的限制。
 *
 * 注意:不支持 @Conditional 注解的继承;任何从超类或从被覆盖的方法继承的条件都不会被考虑。
 * 为了强制这些语义,@Conditional 本身未声明为 java.lang.annotation.Inherited @Inherited;
 * 此外,任何用  @Conditional 作为元注解的自定义组成注解也不应声明为 @Inherited。
 *
 * @author Phillip Webb
 * @author Sam Brannen
 * @since 4.0
 * @see Condition
 */
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Conditional {

	/**
	 * 所有必须满足的 {@link Condition} 类,以便组件可以被注册。
	 */
	Class<? extends Condition>[] value();
}
```

### 四、主要功能

1. **条件化 Bean 注册**
   + 可以根据特定的条件来决定是否创建并注册一个 Bean。这允许我们根据环境、配置或其他因素动态地选择哪些 Bean 需要被实例化。
2. **条件化配置类**
   + 不仅可以对单个 Bean 使用,还可以对整个配置类使用。如果配置类上的条件不满足,那么该配置类中定义的所有 Beans 都不会被注册。
3. **灵活性**
   + 与一个实现了 `Condition` 接口的类一起使用。这个接口允许我们定义自己的条件逻辑,使得其可以非常灵活地根据各种场景来决定是否注册 Bean。
4. **与其他注解组合**
   + 除了与 `@Bean` 和 `@Configuration` 注解一起使用外,`@Conditional` 还可以作为元注解,用于创建自定义的组合注解,这些组合注解内部使用 `@Conditional` 来应用条件逻辑。
5. **对整个配置类的影响**
   + 当 `@Conditional` 用于配置类时,不仅仅是该类,还有与该类关联的所有 `@Bean` 方法、`@Import` 注解和 `@ComponentScan` 注解都将受到条件的影响。
6. **不支持继承**
   + `@Conditional` 注解本身不是继承的,因此,从父类或接口继承的条件不会被子类考虑。

### 五、最佳实践

#### 在@Bean上使用

首先来看看启动类入口,首先设置一个系统属性`enable.bean`为`true`,然后上下文环境使用`AnnotationConfigApplicationContext`(此类是使用Java注解来配置Spring容器的方式),构造参数我们给定了一个`MyConfiguration`组件类,最后打印了Spring上下文中所有的bean定义名称。

```java
public class ConditionBeanApplication {

    public static void main(String[] args) {
        System.setProperty("enable.bean","true");
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MyBeanConfiguration.class);
        for (String beanDefinitionName : context.getBeanDefinitionNames()) {
            System.out.println("beanDefinitionName = " + beanDefinitionName);
        }
    }
}
```

`MyBeanConfiguration`,其中定义了两个bean:`user1`和`user2`。`user1` bean的创建是基于条件的,具体取决于`BeanPropertyCondition`条件的结果。而`user2` bean则无条件创建。

```java
@Configuration
public class MyBeanConfiguration {

    @Bean
    @Conditional(BeanPropertyCondition.class)
    public User1 user1() {
        return new User1();
    }

    @Bean
    public User2 user2() {
        return new User2();
    }
}
```

`BeanPropertyCondition`。这个实现会根据`enable.bean`属性的值决定是否满足条件。具体来说:如果环境属性`enable.bean`的值是`true`,则`user1` bean会被创建并添加到Spring容器。如果`enable.bean`不是`true`(或者没有设置这个属性),`user1` bean不会被创建。

```java
public class BeanPropertyCondition implements Condition {
    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        return "true".equals(context.getEnvironment().getProperty("enable.bean"));
    }
}
```

定义两个简单的Java类:`User1`和`User2`。

```java
public class User1 {

}

public class User2 {

}
```

当`enable.bean`为`true`运行结果发现,根据`enable.bean`属性的值来注册`user1` bean,而`user2` bean则不受此属性的影响。

```java
beanDefinitionName = myBeanConfiguration
beanDefinitionName = user1
beanDefinitionName = user2
```

当`enable.bean`为`false`运行结果发现,`enable.bean`值为`false`,所以条件不满足。因此`user1`bean不会被注册,`user2` bean不受任何条件的影响。

```java
beanDefinitionName = myBeanConfiguration
beanDefinitionName = user2
```

#### 在@Configuration上使用

首先来看看启动类入口,首先设置一个系统属性`enable.config`为`true`,然后上下文环境使用`AnnotationConfigApplicationContext`(此类是使用Java注解来配置Spring容器的方式),构造参数我们给定了一个`MyConfiguration`组件类,最后打印了Spring上下文中所有的bean定义名称。

```java
public class ConditionConfigurationApplication {

    public static void main(String[] args) {
        System.setProperty("enable.config","true");
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MyConfigConfiguration.class);
        for (String beanDefinitionName : context.getBeanDefinitionNames()) {
            System.out.println("beanDefinitionName = " + beanDefinitionName);
        }
    }
}
```

`MyConfigConfiguration`,其中定义了两个bean:`user3`和`user4`。当`ConfigPropertyCondition`条件不满足时`MyConfigConfiguration`配置类不被激活,该配置类中定义的`user3`和`user4`不会被注册。

```java
@Configuration
@Conditional(ConfigPropertyCondition.class)
public class MyConfigConfiguration {

    @Bean
    public User3 user3() {
        return new User3();
    }

    @Bean
    public User4 user4() {
        return new User4();
    }
}
```

`ConfigPropertyCondition`。这个实现会根据`enable.config`属性的值决定是否满足条件。具体来说:当`enable.config`设置为`true`,`ConfigPropertyCondition`满足,`MyConfigConfiguration`配置类被激活,`user3`和`user4` beans都将被注册到Spring上下文。当`enable.config`设置为`false`或未设置,`ConfigPropertyCondition`不满足,`MyConfigConfiguration`配置类不被激活,`user3`和`user4` beans都不会被注册。

```java
public class ConfigPropertyCondition implements Condition {
    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        return "true".equals(System.getProperty("enable.config"));
    }
}
```

定义两个简单的Java类:`User3`和`User4`。

```java
public class User3 {
    
}

public class User4 {
    
}
```

当`enable.config`为`true`运行结果发现,`MyConfigConfiguration`中的`user3`和`user4`都被注册了。

```java
beanDefinitionName = myConfigConfiguration
beanDefinitionName = user3
beanDefinitionName = user4
```

当`enable.config`为`false`运行结果发现,我们不会看到任何与 `MyConfigConfiguration` (包括它自己)相关的 beans 被注册了。

```java
无任何bean
```

#### 自定义组合注解

首先来看看启动类入口,首先设置一个系统属性`enable.custom`为`true`,然后上下文环境使用`AnnotationConfigApplicationContext`(此类是使用Java注解来配置Spring容器的方式),构造参数我们给定了一个`MyConfiguration`组件类,最后打印了Spring上下文中所有的bean定义名称。

```java
public class ConditionCustomApplication {

    public static void main(String[] args) {
        System.setProperty("enable.custom","true");
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MyCustomConfiguration.class);
        for (String beanDefinitionName : context.getBeanDefinitionNames()) {
            System.out.println("beanDefinitionName = " + beanDefinitionName);
        }
    }
}
```

`MyCustomConfiguration`,其中定义了两个bean:`user5`和`user6`。如果`@ConditionalOnCustomActive`的条件满足,`MyCustomConfiguration`配置类将被激活,在此配置类中定义`user5`和`user6`将被注册到Spring容器中。如果`@ConditionalOnCustomActive`的条件不满足,`MyCustomConfiguration`配置类将不被激活。`user5`和`user6` beans都不会被注册。

```java
@Configuration
@ConditionalOnCustomActive
public class MyCustomConfiguration {

    @Bean
    public User5 user5() {
        return new User5();
    }

    @Bean
    public User6 user6() {
        return new User6();
    }
}
```

`@ConditionalOnCustomActive`定义了一个组合注解,并通过`@Conditional`元注解将其关联到`CustomActiveCondition`。

```java
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Conditional(CustomActiveCondition.class)
public @interface ConditionalOnCustomActive {

}
```

`CustomActiveCondition`。这个实现会根据`enable.custom`属性的值决定是否满足条件。具体来说:当`enable.custom`设置为`true`,`CustomActiveCondition`满足条件,因为`matches`方法会返回`true`,`MyCustomConfiguration`配置类由于带有`@ConditionalOnCustomActive`注解(该注解内部引用了`CustomActiveCondition`)将被激活,在该配置类中定义的`user5`和`user6`将被注册到Spring容器中。当`enable.custom`设置为`false`或未设置`CustomActiveCondition`不满足条件,因为`matches`方法会返回`false`,由于`MyCustomConfiguration`带有`@ConditionalOnCustomActive`注解,该配置类不被激活。`user5`和`user6` beans都不会被注册。

```java
public class CustomActiveCondition implements Condition {
    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        return "true".equals(System.getProperty("enable.custom"));
    }
}
```

定义两个简单的Java类:`User5`和`User6`。

```java
public class User5 {
    
}

public class User6 {
    
}
```

当`enable.custom`为`true`运行结果发现,我们的组合注解 `@ConditionalOnCustomActive` 和相应的条件 `CustomActiveCondition` 正常工作,正确地根据 `enable.custom` 系统属性的值来激活 `MyCustomConfiguration` 配置类。

```java
beanDefinitionName = myCustomConfiguration
beanDefinitionName = user5
beanDefinitionName = user6
```

当`enable.custom`为`false`运行结果发现,与 `MyCustomConfiguration` 相关的任何 beans(包括它自己)都不会被注册到 Spring 容器中。

```java
无任何bean
```

### 六、时序图

~~~mermaid
sequenceDiagram 
ConditionCustomApplication->>AnnotationConfigApplicationContext: AnnotationConfigApplicationContext(componentClasses)<br>启动上下文
AnnotationConfigApplicationContext-->>ConfigurationApplication: 返回context<br>返回上下文实例
AnnotationConfigApplicationContext->>AnnotationConfigApplicationContext: register(componentClasses)<br>注册组件类
AnnotationConfigApplicationContext->>AnnotatedBeanDefinitionReader: register(componentClasses)<br>读取器注册类
AnnotatedBeanDefinitionReader-->>AnnotatedBeanDefinitionReader: registerBean(beanClass)<br>注册Bean类
AnnotatedBeanDefinitionReader-->>AnnotatedBeanDefinitionReader: doRegisterBean(beanClass,name,qualifiers, supplier,customizers)<br>执行Bean注册
AnnotatedBeanDefinitionReader->>ConditionEvaluator:shouldSkip(metadata)
ConditionEvaluator->>ConditionEvaluator:shouldSkip(metadata,phase)
ConditionEvaluator->>ConditionEvaluator:getConditionClasses(metadata)
Note right of ConditionEvaluator: 返回 List<String[]>
ConditionEvaluator->>ConditionEvaluator:getCondition(conditionClassName,classloader)
ConditionEvaluator->>AnnotationAwareOrderComparator:sort(conditions)
ConditionEvaluator->>CustomActiveCondition:matches(context,metadata)
CustomActiveCondition->>ConditionEvaluator:返回true or false
ConditionEvaluator->>AnnotatedBeanDefinitionReader:返回true or false
AnnotatedBeanDefinitionReader->>AnnotatedBeanDefinitionReader:如果shouldSkip返回是true,跳过Bean的注册
~~~

### 七、源码分析

首先来看看启动类入口,首先设置一个系统属性`enable.custom`为`true`,然后上下文环境使用`AnnotationConfigApplicationContext`(此类是使用Java注解来配置Spring容器的方式),构造参数我们给定了一个`MyConfiguration`组件类,最后打印了Spring上下文中所有的bean定义名称。

```java
public class ConditionCustomApplication {

    public static void main(String[] args) {
        System.setProperty("enable.custom","true");
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MyCustomConfiguration.class);
        for (String beanDefinitionName : context.getBeanDefinitionNames()) {
            System.out.println("beanDefinitionName = " + beanDefinitionName);
        }
    }
}
```

在`org.springframework.context.annotation.AnnotationConfigApplicationContext#AnnotationConfigApplicationContext`构造函数中,执行了三个步骤,我们重点关注`refresh()`方法。

```java
public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
    this();
    register(componentClasses);
    refresh();
}
```

在`org.springframework.context.annotation.AnnotationConfigApplicationContext#register`方法中,主要是允许我们注册一个或多个组件类(例如,那些使用 `@Component`, `@Service`, `@Repository`, `@Controller`, `@Configuration` 等注解的类)到Spring容器。

```java
@Override
public void register(Class<?>... componentClasses) {
    Assert.notEmpty(componentClasses, "At least one component class must be specified");
    StartupStep registerComponentClass = this.getApplicationStartup().start("spring.context.component-classes.register")
        .tag("classes", () -> Arrays.toString(componentClasses));
    this.reader.register(componentClasses);
    registerComponentClass.end();
}
```

在`org.springframework.context.annotation.AnnotatedBeanDefinitionReader#register`方法中,遍历每一个传入的组件类,并逐一调用另一个方法来完成实际的注册工作。

```java
public void register(Class<?>... componentClasses) {
    for (Class<?> componentClass : componentClasses) {
        registerBean(componentClass);
    }
}
```

在`org.springframework.context.annotation.AnnotatedBeanDefinitionReader#registerBean(beanClass)`方法中,主要目的是快速注册一个 bean 类型,而不需要指定其他详细的配置或参数。

```java
public void registerBean(Class<?> beanClass) {
    doRegisterBean(beanClass, null, null, null, null);
}
```

在`org.springframework.context.annotation.AnnotatedBeanDefinitionReader#doRegisterBean`方法中,主要用于条件性注册 bean 的逻辑,只有当特定的条件满足时,bean 才会被注册。

```java
private <T> void doRegisterBean(Class<T> beanClass, @Nullable String name,
			@Nullable Class<? extends Annotation>[] qualifiers, @Nullable Supplier<T> supplier,
			@Nullable BeanDefinitionCustomizer[] customizers) {

    // 基于给定的 bean 类创建一个带注解的 bean 定义。
    AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);

    // 利用条件评估器检查是否应该跳过当前 bean 的注册。
    // 如果 bean 不满足指定的条件,那么将直接返回,不继续执行后续的注册逻辑。
    if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
        return;
    }

	// ... [代码部分省略以简化]
}
```

在`org.springframework.context.annotation.ConditionEvaluator#shouldSkip(metadata)`方法中,又委托给另一个版本的 `shouldSkip` 方法,并为第二个参数传入 `null`。

```java
public boolean shouldSkip(AnnotatedTypeMetadata metadata) {
    return shouldSkip(metadata, null);
}
```

在`org.springframework.context.annotation.ConditionEvaluator#shouldSkip(metadata,phase)`方法中,主要目的是决定是否应根据给定的条件(通常由 `@Conditional` 注解定义)跳过某个配置类或 bean 的注册。

```java
/**
 * 根据提供的元数据和配置阶段判断是否应跳过某个操作或逻辑。
 *
 * @param metadata 元数据,与注解相关。
 * @param phase    当前的配置阶段,可能为 null。
 * @return 如果应跳过,则返回 true;否则返回 false。
 */
public boolean shouldSkip(@Nullable AnnotatedTypeMetadata metadata, @Nullable ConfigurationPhase phase) {
    // 如果元数据为空或未标注 @Conditional 注解,则不跳过。
    if (metadata == null || !metadata.isAnnotated(Conditional.class.getName())) {
        return false;
    }

    // 如果没有指定配置阶段,确定正确的配置阶段。
    if (phase == null) {
        // 如果元数据是注解元数据,并且是配置候选项,则选择 PARSE_CONFIGURATION 阶段。
        if (metadata instanceof AnnotationMetadata &&
            ConfigurationClassUtils.isConfigurationCandidate((AnnotationMetadata) metadata)) {
            return shouldSkip(metadata, ConfigurationPhase.PARSE_CONFIGURATION);
        }
        // 否则选择 REGISTER_BEAN 阶段。
        return shouldSkip(metadata, ConfigurationPhase.REGISTER_BEAN);
    }

    // 获取所有的条件,并从相关的条件类实例化它们。
    List<Condition> conditions = new ArrayList<>();
    for (String[] conditionClasses : getConditionClasses(metadata)) {
        for (String conditionClass : conditionClasses) {
            Condition condition = getCondition(conditionClass, this.context.getClassLoader());
            conditions.add(condition);
        }
    }

    // 对条件进行排序。
    AnnotationAwareOrderComparator.sort(conditions);

    // 遍历所有条件,检查它们是否与当前配置阶段匹配。
    for (Condition condition : conditions) {
        ConfigurationPhase requiredPhase = null;
        if (condition instanceof ConfigurationCondition) {
            requiredPhase = ((ConfigurationCondition) condition).getConfigurationPhase();
        }
        // 如果条件不匹配上下文和元数据,则跳过。
        if ((requiredPhase == null || requiredPhase == phase) && !condition.matches(this.context, metadata)) {
            return true;
        }
    }

    return false;
}
```

在`org.springframework.context.annotation.ConditionEvaluator#getConditionClasses`方法中,从提供的注解元数据中获取与 `@Conditional` 注解关联的条件类的名称。

```java
/**
 * 从提供的注解元数据中获取与 @Conditional 注解关联的条件类的名称。
 *
 * @param metadata 元数据,通常与某个 bean 或配置类的注解相关。
 * @return 一个列表,其中包含与 @Conditional 注解关联的条件类的名称。如果没有相关的条件类,则返回一个空列表。
 */
private List<String[]> getConditionClasses(AnnotatedTypeMetadata metadata) {
    // 获取 @Conditional 注解的所有属性值。
    MultiValueMap<String, Object> attributes = metadata.getAllAnnotationAttributes(Conditional.class.getName(), true);
    
    // 试图从属性值中获取 "value",它应该是一个指向条件类名称的引用。
    Object values = (attributes != null ? attributes.get("value") : null);

    // 返回条件类名称的列表,或者如果没有条件类,则返回一个空列表。
    return (List<String[]>) (values != null ? values : Collections.emptyList());
}
```

在`org.springframework.context.annotation.ConditionEvaluator#getCondition`方法中,根据给定的条件类名称和类加载器实例化一个 `Condition` 对象。

```java
/**
 * 根据提供的条件类名称和类加载器实例化一个 Condition 对象。
 *
 * @param conditionClassName 条件类的完全限定名。
 * @param classloader 用于加载条件类的类加载器,可以为 null。
 * @return 实例化的 Condition 对象。
 */
private Condition getCondition(String conditionClassName, @Nullable ClassLoader classloader) {
    // 使用类加载器解析并加载指定的条件类。
    Class<?> conditionClass = ClassUtils.resolveClassName(conditionClassName, classloader);
    
    // 实例化解析的条件类并返回。
    return (Condition) BeanUtils.instantiateClass(conditionClass);
}
```

### 八、注意事项

1. **实现 `Condition` 接口**
   + 为了使用 `@Conditional`, 我们需要实现 `Condition` 接口。该接口只有一个方法,`matches(ConditionContext context, AnnotatedTypeMetadata metadata)`,我们需要在这里放置我们的条件逻辑。
2. **类级别和方法级别**:
   - `@Conditional` 可以应用于 `@Bean` 方法,用于控制特定 bean 的创建。
   - 也可以应用于 `@Configuration` 类,控制整个配置类的加载。
3. **组合多个条件**
   + 可以使用 `@Conditional` 注解的数组形式来组合多个条件,所有条件都必须满足才能创建 bean。
4. **与其他注解的组合**
   + `@Conditional` 可以与其他注解一起使用,如 `@Profile`。但是注意他们之间的交互效果。例如,如果一个 bean 标记为特定的 `@Profile` 并且使用 `@Conditional`,那么两者都必须为 true 才能创建该 bean。
5. **避免复杂的逻辑**
   + 虽然 `Condition` 允许我们编写任意的条件逻辑,但最好避免过于复杂。简单明了的逻辑更易于理解和维护。
6. **性能**
   + `matches` 方法可能会在应用的生命周期中被多次调用,因此应确保其执行效率,避免在此方法中进行高开销的操作。
7. **配合 `ConditionContext`**:
   + `ConditionContext` 提供了关于当前应用上下文、环境属性、系统属性等的信息,可以使我们的条件判断更加具体和强大。
8. **自定义条件注解**
   + 为了重用或组合多个条件,我们可以创建自己的条件注解。例如,我们可以创建一个 `@ConditionalOnCustomActive` 注解,它封装了检查`enable.custom`的条件。
9. **注意与 `@Profile` 的区别**
   + 虽然 `@Conditional` 和 `@Profile` 在某些情况下可以达到相同的效果,但它们的目的不同。`@Profile` 基于环境,而 `@Conditional` 更加通用,允许我们基于任意条件创建 bean。

### 九、总结

#### 最佳实践总结

1. **基于`@Bean`的条件配置**

   - **场景描述**
  - 在单个bean的创建上应用条件。
   - **实现方法**
  - 通过在`@Bean`注解方法上直接使用`@Conditional`。
   - **结果**:
     - 当条件满足(如`enable.bean`为`true`),特定的bean(如`user1`)会被注册。
     - 当条件不满足,该bean不会被注册。

2. **基于`@Configuration`的条件配置**

   - **场景描述**
  - 控制整个配置类的激活状态,从而影响该配置中定义的所有beans。
   - **实现方法**
  - 在`@Configuration`注解的类上直接使用`@Conditional`。
   - **结果**:
     - 当条件满足(如`enable.config`为`true`),配置类被激活,其内部的所有beans(如`user3`和`user4`)都会被注册。
     - 当条件不满足,配置类及其内部定义的所有beans都不会被注册。

3. **使用自定义组合注解**

   - **场景描述**
     - 创建自己的条件注解,以提供更清晰、更简洁的语法,或为特定的业务逻辑封装条件逻辑。
   - **实现方法**
     - 定义一个新的注解(如`@ConditionalOnCustomActive`),并使用`@Conditional`元注解将其关联到特定的条件类。
   - **结果**:
     - 当条件满足(如`enable.custom`为`true`),带有`@ConditionalOnCustomActive`注解的配置类或bean会被注册。
     - 当条件不满足,它们不会被注册。

#### 源码分析总结

1. **初始化与启动**
   - 通过 `AnnotationConfigApplicationContext` 构造函数初始化 Spring 上下文,并通过 `register` 和 `refresh` 方法完成 bean 的注册和容器的刷新。

2. **注册组件类**
   + 使用 `AnnotatedBeanDefinitionReader` 来注册组件类。在 `register` 方法中,每一个组件类都会通过 `registerBean` 方法进行注册。

3. **条件检查**
   + 在 `doRegisterBean` 方法中,执行了核心的条件检查逻辑。使用 `ConditionEvaluator` 来评估与给定 bean 或配置类关联的条件是否满足。

4. **元数据检查**
   + `ConditionEvaluator` 会首先检查提供的元数据(通常与特定的 bean 或配置类的注解关联)是否包含 `@Conditional` 注解。如果没有,直接进行下一步。如果存在,继续检查条件是否满足。

5. **条件匹配**
   + `ConditionEvaluator` 获取与 `@Conditional` 注解关联的所有条件类,并为每一个条件类创建一个实例。随后,它会遍历所有的条件,并检查它们是否满足。这是通过调用每一个条件的 `matches` 方法来完成的。如果任何一个条件不满足,整个条件检查逻辑返回 `false`,表示不应注册与 `@Conditional` 注解关联的 bean 或配置类。

6. **条件实例化**
   + 通过 `getCondition` 方法,`ConditionEvaluator` 能够根据提供的条件类名称和类加载器实例化一个 `Condition` 对象。

================================================
FILE: spring-annotation/spring-annotation-conditional/pom.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>spring-annotation</artifactId>
        <groupId>com.xcs.spring</groupId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>

    <modelVersion>4.0.0</modelVersion>
    <artifactId>spring-annotation-conditional</artifactId>

</project>

================================================
FILE: spring-annotation/spring-annotation-conditional/src/main/java/com/xcs/spring/bean/ConditionBeanApplication.java
================================================
package com.xcs.spring.bean;

import com.xcs.spring.bean.config.MyBeanConfiguration;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

/**
 * @author xcs
 * @date 2023年08月07日 16时21分
 **/
public class ConditionBeanApplication {

    public static void main(String[] args) {
        System.setProperty("enable.bean","false");
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MyBeanConfiguration.class);
        for (String beanDefinitionName : context.getBeanDefinitionNames()) {
            System.out.println("beanDefinitionName = " + beanDefinitionName);
        }
    }
}


================================================
FILE: spring-annotation/spring-annotation-conditional/src/main/java/com/xcs/spring/bean/condition/BeanPropertyCondition.java
================================================
package com.xcs.spring.bean.condition;

import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.type.AnnotatedTypeMetadata;

public class BeanPropertyCondition implements Condition {
    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        return "true".equals(context.getEnvironment().getProperty("enable.bean"));
    }
}


================================================
FILE: spring-annotation/spring-annotation-conditional/src/main/java/com/xcs/spring/bean/config/MyBeanConfiguration.java
================================================
package com.xcs.spring.bean.config;

import com.xcs.spring.bean.condition.BeanPropertyCondition;
import com.xcs.spring.bean.entity.User1;
import com.xcs.spring.bean.entity.User2;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;

@Configuration
public class MyBeanConfiguration {

    @Bean
    @Conditional(BeanPropertyCondition.class)
    public User1 user1() {
        return new User1();
    }

    @Bean
    public User2 user2() {
        return new User2();
    }
}


================================================
FILE: spring-annotation/spring-annotation-conditional/src/main/java/com/xcs/spring/bean/entity/User1.java
================================================
package com.xcs.spring.bean.entity;

public class User1 {

}


================================================
FILE: spring-annotation/spring-annotation-conditional/src/main/java/com/xcs/spring/bean/entity/User2.java
================================================
package com.xcs.spring.bean.entity;

public class User2 {

}


================================================
FILE: spring-annotation/spring-annotation-conditional/src/main/java/com/xcs/spring/configuration/ConditionConfigurationApplication.java
================================================
package com.xcs.spring.configuration;

import com.xcs.spring.configuration.config.MyConfigConfiguration;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

/**
 * @author xcs
 * @date 2023年08月07日 16时21分
 **/
public class ConditionConfigurationApplication {

    public static void main(String[] args) {
        System.setProperty("enable.config","false");
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MyConfigConfiguration.class);
        for (String beanDefinitionName : context.getBeanDefinitionNames()) {
            System.out.println("beanDefinitionName = " + beanDefinitionName);
        }
    }
}


================================================
FILE: spring-annotation/spring-annotation-conditional/src/main/java/com/xcs/spring/configuration/condition/ConfigPropertyCondition.java
================================================
package com.xcs.spring.configuration.condition;

import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.type.AnnotatedTypeMetadata;

public class ConfigPropertyCondition implements Condition {
    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        return "true".equals(System.getProperty("enable.config"));
    }
}


================================================
FILE: spring-annotation/spring-annotation-conditional/src/main/java/com/xcs/spring/configuration/config/MyConfigConfiguration.java
================================================
package com.xcs.spring.configuration.config;

import com.xcs.spring.configuration.condition.ConfigPropertyCondition;
import com.xcs.spring.configuration.entity.User3;
import com.xcs.spring.configuration.entity.User4;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;

@Configuration
@Conditional(ConfigPropertyCondition.class)
public class MyConfigConfiguration {

    @Bean
    public User3 user3() {
        return new User3();
    }

    @Bean
    public User4 user4() {
        return new User4();
    }
}


================================================
FILE: spring-annotation/spring-annotation-conditional/src/main/java/com/xcs/spring/configuration/entity/User3.java
================================================
package com.xcs.spring.configuration.entity;

public class User3 {
}


================================================
FILE: spring-annotation/spring-annotation-conditional/src/main/java/com/xcs/spring/configuration/entity/User4.java
==================
Download .txt
gitextract_1jka44ep/

├── .gitignore
├── LICENSE
├── README.md
├── index.html
├── pom.xml
├── spring-annotation/
│   ├── pom.xml
│   ├── spring-annotation-autowired/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── AutowiredApplication.java
│   │                           ├── config/
│   │                           │   └── MyConfiguration.java
│   │                           ├── controller/
│   │                           │   └── MyController.java
│   │                           └── service/
│   │                               └── MyService.java
│   ├── spring-annotation-bean/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── BeanApplication.java
│   │                           ├── bean/
│   │                           │   └── MyBean.java
│   │                           └── config/
│   │                               └── MyConfiguration.java
│   ├── spring-annotation-componentScan/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── ComponentScanApplication.java
│   │                           ├── config/
│   │                           │   └── MyConfiguration.java
│   │                           ├── repository/
│   │                           │   └── UserRepository.java
│   │                           ├── service/
│   │                           │   ├── AdminService.java
│   │                           │   └── UserService.java
│   │                           └── special/
│   │                               └── SpecialComponent.java
│   ├── spring-annotation-conditional/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── bean/
│   │                           │   ├── ConditionBeanApplication.java
│   │                           │   ├── condition/
│   │                           │   │   └── BeanPropertyCondition.java
│   │                           │   ├── config/
│   │                           │   │   └── MyBeanConfiguration.java
│   │                           │   └── entity/
│   │                           │       ├── User1.java
│   │                           │       └── User2.java
│   │                           ├── configuration/
│   │                           │   ├── ConditionConfigurationApplication.java
│   │                           │   ├── condition/
│   │                           │   │   └── ConfigPropertyCondition.java
│   │                           │   ├── config/
│   │                           │   │   └── MyConfigConfiguration.java
│   │                           │   └── entity/
│   │                           │       ├── User3.java
│   │                           │       └── User4.java
│   │                           └── custom/
│   │                               ├── ConditionCustomApplication.java
│   │                               ├── annotation/
│   │                               │   └── ConditionalOnCustomActive.java
│   │                               ├── condition/
│   │                               │   └── CustomActiveCondition.java
│   │                               ├── config/
│   │                               │   └── MyCustomConfiguration.java
│   │                               └── entity/
│   │                                   ├── User5.java
│   │                                   └── User6.java
│   ├── spring-annotation-configuration/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── ConfigurationApplication.java
│   │                           ├── bean/
│   │                           │   └── MyBean.java
│   │                           └── config/
│   │                               └── MyConfiguration.java
│   ├── spring-annotation-dependsOn/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── DependsOnApplication.java
│   │                           ├── bean/
│   │                           │   ├── BeanA.java
│   │                           │   ├── BeanB.java
│   │                           │   └── BeanC.java
│   │                           └── config/
│   │                               └── MyConfiguration.java
│   ├── spring-annotation-import/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── ImportApplication.java
│   │                           ├── bean/
│   │                           │   ├── MyBean.java
│   │                           │   ├── MyBeanA.java
│   │                           │   ├── MyBeanB.java
│   │                           │   └── MyBeanC.java
│   │                           └── config/
│   │                               ├── MyConfiguration.java
│   │                               ├── MyDeferredImportSelector.java
│   │                               ├── MyImportBeanDefinitionRegistrar.java
│   │                               └── MyImportSelector.java
│   ├── spring-annotation-lazy/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── LazyApplication.java
│   │                           ├── bean/
│   │                           │   └── MyBean.java
│   │                           ├── config/
│   │                           │   └── MyConfiguration.java
│   │                           └── service/
│   │                               └── MyService.java
│   ├── spring-annotation-profile/
│   │   ├── README.md
│   │   └── pom.xml
│   ├── spring-annotation-propertySource/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           ├── java/
│   │           │   └── com/
│   │           │       └── xcs/
│   │           │           └── spring/
│   │           │               ├── PropertySourceApplication.java
│   │           │               └── config/
│   │           │                   └── MyConfiguration.java
│   │           └── resources/
│   │               └── my-application.yml
│   └── spring-annotation-value/
│       ├── README.md
│       ├── pom.xml
│       └── src/
│           └── main/
│               ├── java/
│               │   └── com/
│               │       └── xcs/
│               │           └── spring/
│               │               ├── ValueApplication.java
│               │               ├── config/
│               │               │   └── MyConfiguration.java
│               │               └── service/
│               │                   └── MyService.java
│               └── resources/
│                   └── application.properties
├── spring-aop/
│   ├── pom.xml
│   ├── spring-aop-advice/
│   │   ├── README.md
│   │   └── pom.xml
│   ├── spring-aop-advice-afterReturningAdvice/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── AfterReturningAdviceDemo.java
│   │                           ├── MyAfterReturningAdvice.java
│   │                           └── MyService.java
│   ├── spring-aop-advice-introductionInterceptor/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── IntroductionInterceptorDemo.java
│   │                           ├── MyMonitoringCapable.java
│   │                           ├── MyMonitoringIntroductionAdvice.java
│   │                           └── MyService.java
│   ├── spring-aop-advice-methodBeforeAdvice/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── MethodBeforeAdviceDemo.java
│   │                           ├── MyMethodBeforeAdvice.java
│   │                           └── MyService.java
│   ├── spring-aop-advice-methodInterceptor/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── MethodInterceptorDemo.java
│   │                           ├── MyMethodInterceptor.java
│   │                           └── MyService.java
│   ├── spring-aop-advice-throwsAdvice/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── MyService.java
│   │                           ├── MyThrowsAdvice.java
│   │                           └── ThrowsAdviceDemo.java
│   ├── spring-aop-advised/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── AdvisedDemo.java
│   │                           ├── MyService.java
│   │                           └── MyServiceImpl.java
│   ├── spring-aop-advisor/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── AdvisorDemo.java
│   │                           ├── MyAdvice.java
│   │                           ├── MyCustomAdvisor.java
│   │                           ├── MyCustomAnnotation.java
│   │                           └── MyService.java
│   ├── spring-aop-advisorAdapter/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── AdvisorAdapterDemo.java
│   │                           ├── MyNullReturningAdvice.java
│   │                           ├── MyService.java
│   │                           ├── NullReturningAdvice.java
│   │                           ├── NullReturningAdviceAdapter.java
│   │                           └── NullReturningAdviceInterceptor.java
│   ├── spring-aop-advisorAdapterRegistry/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── AdvisorAdapterRegistryDemo.java
│   │                           └── MyMethodBeforeAdvice.java
│   ├── spring-aop-advisorChainFactory/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── AdvisorChainFactoryDemo.java
│   │                           ├── MyAfterReturningAdvice.java
│   │                           ├── MyMethodBeforeAdvice.java
│   │                           └── MyService.java
│   ├── spring-aop-annotationAwareAspectJAutoProxyCreator/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── AnnotationAwareAspectJAutoProxyCreatorDemo.java
│   │                           ├── AppConfig.java
│   │                           ├── MyAspect.java
│   │                           └── MyService.java
│   ├── spring-aop-aopContext/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── AopContextDemo.java
│   │                           ├── MyAnnotation.java
│   │                           ├── MyMethodBeforeAdvice.java
│   │                           └── MyService.java
│   ├── spring-aop-aopProxy/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── AopProxyDemo.java
│   │                           ├── MyMethodInterceptor.java
│   │                           ├── MyService.java
│   │                           └── MyServiceImpl.java
│   ├── spring-aop-aopProxyFactory/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── AopProxyFactoryDemo.java
│   │                           ├── MyService.java
│   │                           └── MyServiceImpl.java
│   ├── spring-aop-aspectInstanceFactory/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── AspectInstanceFactoryDemo.java
│   │                           └── MyAspect.java
│   ├── spring-aop-aspectJAdvisorFactory/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── AspectJAdvisorFactoryDemo.java
│   │                           ├── MyAspect.java
│   │                           └── MyService.java
│   ├── spring-aop-beanFactoryAdvisorRetrievalHelper/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── AppConfig.java
│   │                           ├── BeanFactoryAdvisorRetrievalHelperDemo.java
│   │                           ├── MyAdvice.java
│   │                           ├── MyAdvisor.java
│   │                           └── MyService.java
│   ├── spring-aop-beanFactoryAspectJAdvisorsBuilder/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── AppConfig.java
│   │                           ├── BeanFactoryAspectJAdvisorsBuilderDemo.java
│   │                           ├── MyAspect.java
│   │                           └── MyService.java
│   ├── spring-aop-cglibProxy/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── CglibProxyDemo.java
│   │                           ├── MyMethodInterceptor.java
│   │                           ├── MyService.java
│   │                           └── MyServiceImpl.java
│   ├── spring-aop-classFilter/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── ClassFilterDemo.java
│   │                           ├── MyClassAnnotation.java
│   │                           ├── MyService.java
│   │                           └── MySubService.java
│   ├── spring-aop-enableAspectJAutoProxy/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── AppConfig.java
│   │                           ├── EnableAspectJAutoProxyDemo.java
│   │                           ├── MyAspect.java
│   │                           └── MyService.java
│   ├── spring-aop-enableLoadTimeWeaving/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           ├── java/
│   │           │   └── com/
│   │           │       └── xcs/
│   │           │           └── spring/
│   │           │               ├── AppConfig.java
│   │           │               ├── EnableLoadTimeWeavingDemo.java
│   │           │               ├── MyLTWAspect.java
│   │           │               └── MyService.java
│   │           └── resources/
│   │               └── META-INF/
│   │                   └── aop.xml
│   ├── spring-aop-exposeInvocationInterceptor/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── AppConfig.java
│   │                           ├── ExposeInvocationInterceptorDemo.java
│   │                           ├── LogUtil.java
│   │                           ├── MyMethodInterceptor.java
│   │                           └── MyService.java
│   ├── spring-aop-jdkProxy/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── JdkProxyDemo.java
│   │                           ├── MyInvocationHandler.java
│   │                           ├── MyService.java
│   │                           └── MyServiceImpl.java
│   ├── spring-aop-metadataAwareAspectInstanceFactory/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── MetadataAwareAspectInstanceFactoryDemo.java
│   │                           └── MyAspect.java
│   ├── spring-aop-methodMatcher/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── MethodMatcherDemo.java
│   │                           ├── MyMethodAnnotation.java
│   │                           └── MyService.java
│   ├── spring-aop-pointcut/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── MyClassAnnotation.java
│   │                           ├── MyCustomAdvice.java
│   │                           ├── MyCustomPointcut.java
│   │                           ├── MyMethodAnnotation.java
│   │                           ├── MyService.java
│   │                           └── PointcutDemo.java
│   ├── spring-aop-proxyFactory/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── MyService.java
│   │                           └── ProxyFactoryDemo.java
│   ├── spring-aop-proxyMethodInvocation/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── MyInvocationHandler.java
│   │                           ├── MyMethodInterceptor.java
│   │                           ├── MyReflectiveMethodInvocation.java
│   │                           ├── MyService.java
│   │                           ├── MyServiceImpl.java
│   │                           └── ProxyMethodInvocationDemo.java
│   ├── spring-aop-targetSource/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── ConnectionPoolTargetSource.java
│   │                           ├── MyConnection.java
│   │                           └── TargetSourceDemo.java
│   └── spring-aop-targetSourceCreator/
│       ├── README.md
│       ├── pom.xml
│       └── src/
│           └── main/
│               └── java/
│                   └── com/
│                       └── xcs/
│                           └── spring/
│                               ├── AppConfig.java
│                               ├── ConnectionPoolTargetSource.java
│                               ├── MyConnection.java
│                               ├── MyTargetSourceCreator.java
│                               ├── SetMyTargetSourceCreator.java
│                               └── TargetSourceCreatorDemo.java
├── spring-aware/
│   ├── pom.xml
│   ├── spring-aware-applicationContextAware/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── ApplicationContextAwareApplication.java
│   │                           └── config/
│   │                               ├── MyApplicationContextAware.java
│   │                               └── MyConfiguration.java
│   ├── spring-aware-applicationEventPublisherAware/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── ApplicationEventPublisherAwareApplication.java
│   │                           ├── config/
│   │                           │   ├── MyApplicationEventPublisherAware.java
│   │                           │   └── MyConfiguration.java
│   │                           └── event/
│   │                               ├── MyEvent.java
│   │                               └── MyEventListener.java
│   ├── spring-aware-applicationStartupAware/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── ApplicationStartupAwareApplication.java
│   │                           └── config/
│   │                               ├── MyApplicationStartupAware.java
│   │                               └── MyConfiguration.java
│   ├── spring-aware-beanClassLoaderAware/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── BeanClassLoaderAwareApplication.java
│   │                           ├── config/
│   │                           │   ├── MyBeanClassLoaderAware.java
│   │                           │   └── MyConfiguration.java
│   │                           └── service/
│   │                               ├── UserService.java
│   │                               └── UserServiceImpl.java
│   ├── spring-aware-beanFactoryAware/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── BeanFactoryAwareApplication.java
│   │                           ├── config/
│   │                           │   └── MyConfiguration.java
│   │                           ├── service/
│   │                           │   └── UserService.java
│   │                           └── validate/
│   │                               ├── ComplexUserValidator.java
│   │                               ├── SimpleUserValidator.java
│   │                               └── UserValidator.java
│   ├── spring-aware-beanNameAware/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── BeanNameAwareApplication.java
│   │                           ├── config/
│   │                           │   └── MyConfiguration.java
│   │                           └── service/
│   │                               ├── MyAliPayService.java
│   │                               ├── MyBasePayService.java
│   │                               └── MyWeChatPayService.java
│   ├── spring-aware-embeddedValueResolverAware/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── EmbeddedValueResolverAwareApplication.java
│   │                           └── config/
│   │                               ├── MyConfiguration.java
│   │                               └── MyEmbeddedValueResolverAware.java
│   ├── spring-aware-environmentAware/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           ├── java/
│   │           │   └── com/
│   │           │       └── xcs/
│   │           │           └── spring/
│   │           │               ├── EnvironmentAwareApplication.java
│   │           │               └── config/
│   │           │                   ├── MyConfiguration.java
│   │           │                   └── MyEnvironmentAware.java
│   │           └── resources/
│   │               └── application.properties
│   ├── spring-aware-importAware/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── ImportAwareApplication.java
│   │                           ├── annotation/
│   │                           │   └── EnableXcs.java
│   │                           └── config/
│   │                               ├── MyConfiguration.java
│   │                               └── MyImportAware.java
│   ├── spring-aware-messageSourceAware/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           ├── java/
│   │           │   └── com/
│   │           │       └── xcs/
│   │           │           └── spring/
│   │           │               ├── MessageSourceAwareApplication.java
│   │           │               └── config/
│   │           │                   ├── MyConfiguration.java
│   │           │                   └── MyMessageSourceAware.java
│   │           └── resources/
│   │               └── i18n/
│   │                   ├── messages_en.properties
│   │                   └── messages_zh_CN.properties
│   └── spring-aware-resourceLoaderAware/
│       ├── README.md
│       ├── pom.xml
│       └── src/
│           └── main/
│               ├── java/
│               │   └── com/
│               │       └── xcs/
│               │           └── spring/
│               │               ├── ResourceLoaderAwareApplication.java
│               │               └── config/
│               │                   ├── MyConfiguration.java
│               │                   └── MyResourceLoaderAware.java
│               └── resources/
│                   └── xcs.txt
├── spring-beans/
│   ├── pom.xml
│   ├── spring-bean-annotatedBeanDefinitionReader/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── AnnotatedBeanDefinitionReaderDemo.java
│   │                           └── bean/
│   │                               └── MyBean.java
│   ├── spring-bean-beanDefinition/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── BeanDefinitionDemo.java
│   │                           └── bean/
│   │                               └── MyBean.java
│   ├── spring-bean-beanDefinitionHolder/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── BeanDefinitionHolderDemo.java
│   │                           └── bean/
│   │                               └── MyBean.java
│   ├── spring-bean-beanDefinitionRegistry/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── BeanDefinitionRegistryDemo.java
│   │                           └── bean/
│   │                               └── MyBean.java
│   ├── spring-bean-classPathBeanDefinitionScanner/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── ClassPathBeanDefinitionScannerDemo.java
│   │                           ├── controller/
│   │                           │   └── MyController.java
│   │                           ├── repository/
│   │                           │   └── MyRepository.java
│   │                           └── service/
│   │                               └── MyService.java
│   ├── spring-bean-groovyBeanDefinitionReader/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           ├── java/
│   │           │   └── com/
│   │           │       └── xcs/
│   │           │           └── spring/
│   │           │               ├── GroovyBeanDefinitionReaderDemo.java
│   │           │               └── service/
│   │           │                   └── MyService.java
│   │           └── resources/
│   │               └── my-beans.groovy
│   ├── spring-bean-propertiesBeanDefinitionReader/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           ├── java/
│   │           │   └── com/
│   │           │       └── xcs/
│   │           │           └── spring/
│   │           │               ├── PropertiesBeanDefinitionReaderDemo.java
│   │           │               └── bean/
│   │           │                   └── MyBean.java
│   │           └── resources/
│   │               └── bean-definitions.properties
│   └── spring-bean-xmlBeanDefinitionReader/
│       ├── README.md
│       ├── pom.xml
│       └── src/
│           └── main/
│               ├── java/
│               │   └── com/
│               │       └── xcs/
│               │           └── spring/
│               │               ├── XmlBeanDefinitionReaderDemo.java
│               │               └── bean/
│               │                   └── MyBean.java
│               └── resources/
│                   └── beans.xml
├── spring-context/
│   ├── pom.xml
│   ├── spring-context-annotationConfigApplicationContext/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── AnnotationConfigApplicationContextDemo.java
│   │                           ├── bean/
│   │                           │   └── MyBean.java
│   │                           ├── controller/
│   │                           │   └── MyController.java
│   │                           ├── repository/
│   │                           │   └── MyRepository.java
│   │                           └── service/
│   │                               └── MyService.java
│   ├── spring-context-classPathXmlApplicationContext/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           ├── java/
│   │           │   └── com/
│   │           │       └── xcs/
│   │           │           └── spring/
│   │           │               ├── ClassPathXmlApplicationContextDemo.java
│   │           │               └── bean/
│   │           │                   └── MyBean.java
│   │           └── resources/
│   │               └── beans.xml
│   └── spring-context-genericApplicationContext/
│       └── pom.xml
├── spring-core/
│   ├── pom.xml
│   ├── spring-core-destroyBean/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── DestroyBeanApplication.java
│   │                           └── bean/
│   │                               └── MyBean.java
│   ├── spring-core-getBean/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── GetBeanApplication.java
│   │                           ├── config/
│   │                           │   └── MyConfiguration.java
│   │                           └── service/
│   │                               ├── MyServiceA.java
│   │                               └── MyServiceB.java
│   ├── spring-core-registerBeanDefinition/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── RegisterBeanDefinitionApplication.java
│   │                           ├── bean/
│   │                           │   └── MyBean.java
│   │                           ├── controller/
│   │                           │   └── MyController.java
│   │                           ├── repository/
│   │                           │   └── MyRepository.java
│   │                           └── service/
│   │                               └── MyService.java
│   └── spring-core-resolveDependency/
│       ├── README.md
│       ├── pom.xml
│       └── src/
│           └── main/
│               ├── java/
│               │   └── com/
│               │       └── xcs/
│               │           └── spring/
│               │               ├── ResolveDependencyApplication.java
│               │               ├── config/
│               │               │   └── MyConfiguration.java
│               │               └── service/
│               │                   ├── MyServiceA.java
│               │                   └── MyServiceB.java
│               └── resources/
│                   └── application.properties
├── spring-dataops/
│   ├── pom.xml
│   ├── spring-dataops-conditionalConverter/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── ConditionalConverterDemo.java
│   │                           └── converter/
│   │                               └── StringToIntegerConditionalConverter.java
│   ├── spring-dataops-conversionService/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           └── ConversionServiceDemo.java
│   ├── spring-dataops-converter/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── ConverterDemo.java
│   │                           └── converter/
│   │                               ├── StringToBooleanConverter.java
│   │                               └── StringToLocalDateConverter.java
│   ├── spring-dataops-converterFactory/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── CharacterToNumberFactoryDemo.java
│   │                           └── converter/
│   │                               └── StringToNumberConverterFactory.java
│   ├── spring-dataops-genericConverter/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── GenericConverterDemo.java
│   │                           ├── annotation/
│   │                           │   └── DateFormat.java
│   │                           ├── bean/
│   │                           │   └── MyBean.java
│   │                           └── convert/
│   │                               └── AnnotatedStringToDateConverter.java
│   ├── spring-dataops-parser/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── ParserDemo.java
│   │                           └── parser/
│   │                               └── CurrencyParser.java
│   ├── spring-dataops-printer/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── PrinterDemo.java
│   │                           └── printer/
│   │                               └── CurrencyPrinter.java
│   ├── spring-dataops-propertyEditor/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── MyCustomDateEditor.java
│   │                           ├── PropertyEditorDemo.java
│   │                           └── bean/
│   │                               └── MyBean.java
│   └── spring-dataops-validator/
│       ├── README.md
│       ├── pom.xml
│       └── src/
│           └── main/
│               └── java/
│                   └── com/
│                       └── xcs/
│                           └── spring/
│                               ├── Person.java
│                               ├── PersonValidator.java
│                               └── ValidatorDemo.java
├── spring-env/
│   ├── pom.xml
│   ├── spring-env-configurableEnvironment/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           └── ConfigurableEnvironmentDemo.java
│   ├── spring-env-configurablePropertyResolver/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           └── ConfigurablePropertyResolverDemo.java
│   ├── spring-env-environment/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           └── EnvironmentDemo.java
│   ├── spring-env-propertyResolver/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           └── SimplePropertyResolverDemo.java
│   ├── spring-env-propertySource/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           ├── java/
│   │           │   └── com/
│   │           │       └── xcs/
│   │           │           └── spring/
│   │           │               └── PropertySourceDemo.java
│   │           └── resources/
│   │               └── application.properties
│   └── spring-env-propertySources/
│       ├── README.md
│       ├── pom.xml
│       └── src/
│           └── main/
│               └── java/
│                   └── com/
│                       └── xcs/
│                           └── spring/
│                               └── PropertySourcesDemo.java
├── spring-factory/
│   ├── pom.xml
│   ├── spring-factory-autowireCapableBeanFactory/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── AutowireCapableBeanFactoryDemo.java
│   │                           ├── config/
│   │                           │   ├── MyBeanPostProcessor.java
│   │                           │   └── MyConfiguration.java
│   │                           ├── repository/
│   │                           │   └── MyRepository.java
│   │                           └── service/
│   │                               └── MyService.java
│   ├── spring-factory-beanFactory/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           ├── java/
│   │           │   └── com/
│   │           │       └── xcs/
│   │           │           └── spring/
│   │           │               ├── BeanFactoryDemo.java
│   │           │               └── bean/
│   │           │                   └── MyBean.java
│   │           └── resources/
│   │               └── beans.xml
│   ├── spring-factory-configurableBeanFactory/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── ConfigurableBeanFactoryDemo.java
│   │                           ├── config/
│   │                           │   └── MyConfiguration.java
│   │                           └── service/
│   │                               ├── MyService.java
│   │                               └── impl/
│   │                                   └── MyServiceImpl.java
│   ├── spring-factory-configurableListableBeanFactory/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── ConfigurableListableBeanFactoryDemo.java
│   │                           ├── config/
│   │                           │   └── MyConfiguration.java
│   │                           ├── controller/
│   │                           │   └── MyController.java
│   │                           └── service/
│   │                               ├── MyService.java
│   │                               └── impl/
│   │                                   └── MyServiceImpl.java
│   ├── spring-factory-hierarchicalBeanFactory/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── HierarchicalBeanFactoryDemo.java
│   │                           └── bean/
│   │                               └── MyBean.java
│   └── spring-factory-listableBeanFactory/
│       ├── README.md
│       ├── pom.xml
│       └── src/
│           └── main/
│               └── java/
│                   └── com/
│                       └── xcs/
│                           └── spring/
│                               ├── ListableBeanFactoryDemo.java
│                               ├── config/
│                               │   └── MyConfiguration.java
│                               └── service/
│                                   └── MyService.java
├── spring-interface/
│   ├── pom.xml
│   ├── spring-interface-beanDefinitionRegistryPostProcessor/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── BeanDefinitionRegistryPostProcessorApplication.java
│   │                           └── config/
│   │                               ├── MyBeanDefinitionRegistryPostProcessor.java
│   │                               ├── MyConfiguration.java
│   │                               └── MySimpleBean.java
│   ├── spring-interface-beanFactoryPostProcessor/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── BeanFactoryPostProcessorApplication.java
│   │                           └── config/
│   │                               ├── MyBeanFactoryPostProcessor.java
│   │                               ├── MyConfiguration.java
│   │                               └── MySimpleBean.java
│   ├── spring-interface-beanPostProcessor/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── BeanPostProcessorApplication.java
│   │                           ├── config/
│   │                           │   ├── MyBeanPostProcessor.java
│   │                           │   └── MyConfiguration.java
│   │                           └── service/
│   │                               ├── MyService.java
│   │                               └── MyServiceImpl.java
│   ├── spring-interface-destructionAwareBeanPostProcessor/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── DestructionAwareBeanPostProcessorApplication.java
│   │                           ├── config/
│   │                           │   ├── MyConfiguration.java
│   │                           │   └── MyDestructionAwareBeanPostProcessor.java
│   │                           └── service/
│   │                               ├── ConnectionService.java
│   │                               └── ConnectionServiceImpl.java
│   ├── spring-interface-disposableBean/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── DisposableBeanApplication.java
│   │                           └── config/
│   │                               ├── MyConfiguration.java
│   │                               └── MyDisposableBean.java
│   ├── spring-interface-initializingBean/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── InitializingBeanApplication.java
│   │                           └── config/
│   │                               ├── MyConfiguration.java
│   │                               └── MyInitializingBean.java
│   ├── spring-interface-instantiationAwareBeanPostProcessor/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── InstantiationAwareBeanPostProcessorApplication.java
│   │                           ├── config/
│   │                           │   ├── MyConfiguration.java
│   │                           │   └── MyInstantiationAwareBeanPostProcessor.java
│   │                           └── service/
│   │                               ├── DataBase.java
│   │                               └── DataBaseImpl.java
│   ├── spring-interface-mergedBeanDefinitionPostProcessor/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── MergedBeanDefinitionPostProcessorApplication.java
│   │                           ├── annotation/
│   │                           │   └── MyValue.java
│   │                           ├── bean/
│   │                           │   └── MyBean.java
│   │                           └── config/
│   │                               ├── MyConfiguration.java
│   │                               └── MyMergedBeanDefinitionPostProcessor.java
│   ├── spring-interface-smartInitializingSingleton/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── SmartInitializingSingletonApplication.java
│   │                           ├── config/
│   │                           │   ├── MyConfiguration.java
│   │                           │   └── MySmartInitializingSingleton.java
│   │                           └── service/
│   │                               └── MyService.java
│   └── spring-interface-smartInstantiationAwareBeanPostProcessor/
│       ├── README.md
│       ├── pom.xml
│       └── src/
│           └── main/
│               └── java/
│                   └── com/
│                       └── xcs/
│                           └── spring/
│                               ├── SmartInstantiationAwareBeanPostProcessorApplication.java
│                               ├── annotation/
│                               │   └── MyAutowired.java
│                               ├── config/
│                               │   ├── MyConfiguration.java
│                               │   └── MySmartInstantiationAwareBeanPostProcessor.java
│                               └── service/
│                                   ├── MyService.java
│                                   ├── MyServiceA.java
│                                   └── MyServiceB.java
├── spring-jsr/
│   ├── pom.xml
│   ├── spring-jsr250-postConstruct/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── PostConstructApplication.java
│   │                           ├── config/
│   │                           │   └── MyConfiguration.java
│   │                           └── service/
│   │                               └── MyService.java
│   ├── spring-jsr250-preDestroy/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── PreDestroyApplication.java
│   │                           ├── config/
│   │                           │   └── MyConfiguration.java
│   │                           └── service/
│   │                               └── MyService.java
│   ├── spring-jsr250-resource/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── ResourceApplication.java
│   │                           ├── config/
│   │                           │   └── MyConfiguration.java
│   │                           ├── controller/
│   │                           │   └── MyController.java
│   │                           └── service/
│   │                               └── MyService.java
│   ├── spring-jsr330-inject/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── InjectApplication.java
│   │                           ├── config/
│   │                           │   └── MyConfiguration.java
│   │                           ├── controller/
│   │                           │   └── MyController.java
│   │                           └── service/
│   │                               └── MyService.java
│   ├── spring-jsr330-named/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── NamedApplication.java
│   │                           ├── config/
│   │                           │   └── MyConfiguration.java
│   │                           ├── controller/
│   │                           │   └── MyController.java
│   │                           └── service/
│   │                               ├── MyService.java
│   │                               ├── MyServiceA.java
│   │                               └── MyServiceB.java
│   ├── spring-jsr330-provider/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── ProviderApplication.java
│   │                           ├── config/
│   │                           │   └── MyConfiguration.java
│   │                           ├── controller/
│   │                           │   └── MyController.java
│   │                           └── service/
│   │                               └── MyService.java
│   ├── spring-jsr330-qualifier/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── QualifierApplication.java
│   │                           ├── annotation/
│   │                           │   ├── Email.java
│   │                           │   └── SMS.java
│   │                           ├── config/
│   │                           │   └── MyConfiguration.java
│   │                           ├── controller/
│   │                           │   └── MessageController.java
│   │                           └── service/
│   │                               ├── MessageService.java
│   │                               └── impl/
│   │                                   ├── EmailServiceImpl.java
│   │                                   └── SMSServiceImpl.java
│   ├── spring-jsr330-scope/
│   │   ├── README.md
│   │   └── pom.xml
│   └── spring-jsr330-singleton/
│       ├── README.md
│       └── pom.xml
├── spring-metadata/
│   ├── pom.xml
│   ├── spring-metadata-annotationMetadata/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── AnnotationMetadataDemoByASM.java
│   │                           ├── AnnotationMetadataDemoByReflection.java
│   │                           └── bean/
│   │                               └── MyBean.java
│   ├── spring-metadata-condition/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── ConditionDemo.java
│   │                           ├── bean/
│   │                           │   ├── MyBeanA.java
│   │                           │   └── MyBeanB.java
│   │                           └── condition/
│   │                               └── MyOnClassCondition.java
│   ├── spring-metadata-metadataReader/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── MetadataReaderDemo.java
│   │                           ├── annotation/
│   │                           │   ├── MyAnnotation.java
│   │                           │   └── MyClassAnnotation.java
│   │                           └── bean/
│   │                               ├── MyAbstract.java
│   │                               └── MyBean.java
│   └── spring-metadata-typeFilter/
│       ├── README.md
│       ├── pom.xml
│       └── src/
│           └── main/
│               └── java/
│                   └── com/
│                       └── xcs/
│                           └── spring/
│                               ├── TypeFilterDemo.java
│                               ├── annotation/
│                               │   └── MyAnnotation.java
│                               ├── component/
│                               │   └── MyComponent.java
│                               ├── controller/
│                               │   └── MyController.java
│                               ├── repository/
│                               │   └── MyRepository.java
│                               └── service/
│                                   └── MyService.java
├── spring-mvc/
│   └── pom.xml
├── spring-resources/
│   ├── pom.xml
│   ├── spring-resource/
│   │   ├── README.md
│   │   ├── myfile.txt
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           ├── java/
│   │           │   └── com/
│   │           │       └── xcs/
│   │           │           └── spring/
│   │           │               ├── ByteArrayResourceDemo.java
│   │           │               ├── ClassPathResourceDemo.java
│   │           │               ├── FileSystemResourceDemo.java
│   │           │               ├── InputStreamResourceDemo.java
│   │           │               └── UrlResourceDemo.java
│   │           └── resources/
│   │               └── application.properties
│   ├── spring-resource-documentLoader/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           ├── java/
│   │           │   └── com/
│   │           │       └── xcs/
│   │           │           └── spring/
│   │           │               ├── DocumentLoaderDemo.java
│   │           │               └── bean/
│   │           │                   └── MyBean.java
│   │           └── resources/
│   │               └── sample.xml
│   ├── spring-resource-resourceLoader/
│   │   ├── README.md
│   │   ├── myfile1.txt
│   │   ├── myfile2.txt
│   │   ├── myfile3.txt
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           ├── java/
│   │           │   └── com/
│   │           │       └── xcs/
│   │           │           └── spring/
│   │           │               ├── DefaultResourceLoaderDemo.java
│   │           │               └── PathMatchingResourcePatternResolverDemo.java
│   │           └── resources/
│   │               ├── application.properties
│   │               └── bootstrap.properties
│   └── spring-resource-resourcePatternResolver/
│       ├── README.md
│       ├── myfile1.txt
│       ├── myfile2.txt
│       ├── myfile3.txt
│       ├── pom.xml
│       └── src/
│           └── main/
│               ├── java/
│               │   └── com/
│               │       └── xcs/
│               │           └── spring/
│               │               └── ResourcePatternResolverDemo.java
│               └── resources/
│                   ├── application.properties
│                   └── bootstrap.properties
├── spring-spel/
│   ├── pom.xml
│   ├── spring-spel-beanResolver/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── BeanResolverDemo.java
│   │                           └── MyBean.java
│   ├── spring-spel-constructorResolver/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── ConstructorResolverDemo.java
│   │                           └── MyBean.java
│   ├── spring-spel-evaluationContext/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           └── EvaluationContextDemo.java
│   ├── spring-spel-expression/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           └── ExpressionDemo.java
│   ├── spring-spel-expressionParser/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           └── ExpressionParserDemo.java
│   ├── spring-spel-methodResolver/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── MethodResolverDemo.java
│   │                           └── MyBean.java
│   ├── spring-spel-operatorOverloader/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               ├── CustomOperatorOverloader.java
│   │               ├── MyBean.java
│   │               └── OperatorOverloaderDemo.java
│   ├── spring-spel-propertyAccessor/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           ├── MyBean.java
│   │                           └── PropertyAccessorDemo.java
│   ├── spring-spel-typeComparator/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           └── TypeComparatorDemo.java
│   ├── spring-spel-typeConverter/
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── xcs/
│   │                       └── spring/
│   │                           └── TypeConverterDemo.java
│   └── spring-spel-typeLocator/
│       ├── README.md
│       ├── pom.xml
│       └── src/
│           └── main/
│               └── java/
│                   └── com/
│                       └── xcs/
│                           └── spring/
│                               └── TypeLocatorDemo.java
└── spring-transaction/
    ├── pom.xml
    ├── spring-transaction-connection/
    │   ├── README.md
    │   ├── pom.xml
    │   └── src/
    │       └── main/
    │           └── java/
    │               └── com/
    │                   └── xcs/
    │                       └── spring/
    │                           └── ConnectionDemo.java
    ├── spring-transaction-dataSource/
    │   ├── README.md
    │   ├── pom.xml
    │   └── src/
    │       └── main/
    │           └── java/
    │               └── com/
    │                   └── xcs/
    │                       └── spring/
    │                           └── DataSourceDemo.java
    ├── spring-transaction-driverManager/
    │   ├── README.md
    │   ├── pom.xml
    │   └── src/
    │       └── main/
    │           └── java/
    │               └── com/
    │                   └── xcs/
    │                       └── spring/
    │                           └── DriverManagerDemo.java
    ├── spring-transaction-enableTransactionManagement/
    │   ├── README.md
    │   ├── pom.xml
    │   └── src/
    │       └── main/
    │           └── java/
    │               └── com/
    │                   └── xcs/
    │                       └── spring/
    │                           ├── AppConfig.java
    │                           ├── EnableTransactionManagementDemo.java
    │                           ├── ScoresService.java
    │                           └── ScoresServiceImpl.java
    ├── spring-transaction-jdbcTemplate/
    │   ├── README.md
    │   ├── pom.xml
    │   └── src/
    │       └── main/
    │           └── java/
    │               └── com/
    │                   └── xcs/
    │                       └── spring/
    │                           ├── JdbcTemplateDemo.java
    │                           └── Scores.java
    ├── spring-transaction-platformTransactionManager/
    │   ├── README.md
    │   ├── pom.xml
    │   └── src/
    │       └── main/
    │           └── java/
    │               └── com/
    │                   └── xcs/
    │                       └── spring/
    │                           └── PlatformTransactionManagerDemo.java
    ├── spring-transaction-springTransactionAnnotationParser/
    │   ├── README.md
    │   ├── pom.xml
    │   └── src/
    │       └── main/
    │           └── java/
    │               └── com/
    │                   └── xcs/
    │                       └── spring/
    │                           ├── ScoresService.java
    │                           ├── ScoresServiceImpl.java
    │                           └── SpringTransactionAnnotationParserDemo.java
    ├── spring-transaction-transactionAttributeSource/
    │   ├── README.md
    │   ├── pom.xml
    │   └── src/
    │       └── main/
    │           └── java/
    │               └── com/
    │                   └── xcs/
    │                       └── spring/
    │                           ├── ScoresService.java
    │                           ├── ScoresServiceImpl.java
    │                           └── TransactionAttributeSourceDemo.java
    ├── spring-transaction-transactionDefinition/
    │   ├── README.md
    │   ├── pom.xml
    │   └── src/
    │       └── main/
    │           └── java/
    │               └── com/
    │                   └── xcs/
    │                       └── spring/
    │                           └── TransactionDefinitionDemo.java
    ├── spring-transaction-transactionInterceptor/
    │   ├── README.md
    │   ├── pom.xml
    │   └── src/
    │       └── main/
    │           └── java/
    │               └── com/
    │                   └── xcs/
    │                       └── spring/
    │                           ├── ScoresService.java
    │                           ├── ScoresServiceImpl.java
    │                           └── TransactionInterceptorDemo.java
    ├── spring-transaction-transactionTemplate/
    │   ├── README.md
    │   ├── pom.xml
    │   └── src/
    │       └── main/
    │           └── java/
    │               └── com/
    │                   └── xcs/
    │                       └── spring/
    │                           └── TransactionTemplateDemo.java
    └── sql/
        └── test.sql
Download .txt
SYMBOL INDEX (968 symbols across 433 files)

FILE: spring-annotation/spring-annotation-autowired/src/main/java/com/xcs/spring/AutowiredApplication.java
  class AutowiredApplication (line 11) | public class AutowiredApplication {
    method main (line 13) | public static void main(String[] args) {

FILE: spring-annotation/spring-annotation-autowired/src/main/java/com/xcs/spring/config/MyConfiguration.java
  class MyConfiguration (line 6) | @Configuration

FILE: spring-annotation/spring-annotation-autowired/src/main/java/com/xcs/spring/controller/MyController.java
  class MyController (line 7) | @Controller
    method showService (line 13) | public void showService(){

FILE: spring-annotation/spring-annotation-autowired/src/main/java/com/xcs/spring/service/MyService.java
  class MyService (line 5) | @Service

FILE: spring-annotation/spring-annotation-bean/src/main/java/com/xcs/spring/BeanApplication.java
  class BeanApplication (line 11) | public class BeanApplication {
    method main (line 13) | public static void main(String[] args) {

FILE: spring-annotation/spring-annotation-bean/src/main/java/com/xcs/spring/bean/MyBean.java
  class MyBean (line 7) | public class MyBean {
    method init (line 9) | public void init(){
    method destroy (line 13) | public void destroy(){

FILE: spring-annotation/spring-annotation-bean/src/main/java/com/xcs/spring/config/MyConfiguration.java
  class MyConfiguration (line 11) | @Configuration
    method myBean (line 14) | @Bean(initMethod = "init",destroyMethod = "destroy")

FILE: spring-annotation/spring-annotation-componentScan/src/main/java/com/xcs/spring/ComponentScanApplication.java
  class ComponentScanApplication (line 10) | public class ComponentScanApplication {
    method main (line 12) | public static void main(String[] args) {

FILE: spring-annotation/spring-annotation-componentScan/src/main/java/com/xcs/spring/config/MyConfiguration.java
  class MyConfiguration (line 13) | @Configuration

FILE: spring-annotation/spring-annotation-componentScan/src/main/java/com/xcs/spring/repository/UserRepository.java
  class UserRepository (line 9) | @Repository

FILE: spring-annotation/spring-annotation-componentScan/src/main/java/com/xcs/spring/service/AdminService.java
  class AdminService (line 9) | @Service

FILE: spring-annotation/spring-annotation-componentScan/src/main/java/com/xcs/spring/service/UserService.java
  class UserService (line 9) | @Service

FILE: spring-annotation/spring-annotation-componentScan/src/main/java/com/xcs/spring/special/SpecialComponent.java
  class SpecialComponent (line 7) | public class SpecialComponent {

FILE: spring-annotation/spring-annotation-conditional/src/main/java/com/xcs/spring/bean/ConditionBeanApplication.java
  class ConditionBeanApplication (line 10) | public class ConditionBeanApplication {
    method main (line 12) | public static void main(String[] args) {

FILE: spring-annotation/spring-annotation-conditional/src/main/java/com/xcs/spring/bean/condition/BeanPropertyCondition.java
  class BeanPropertyCondition (line 7) | public class BeanPropertyCondition implements Condition {
    method matches (line 8) | @Override

FILE: spring-annotation/spring-annotation-conditional/src/main/java/com/xcs/spring/bean/config/MyBeanConfiguration.java
  class MyBeanConfiguration (line 10) | @Configuration
    method user1 (line 13) | @Bean
    method user2 (line 19) | @Bean

FILE: spring-annotation/spring-annotation-conditional/src/main/java/com/xcs/spring/bean/entity/User1.java
  class User1 (line 3) | public class User1 {

FILE: spring-annotation/spring-annotation-conditional/src/main/java/com/xcs/spring/bean/entity/User2.java
  class User2 (line 3) | public class User2 {

FILE: spring-annotation/spring-annotation-conditional/src/main/java/com/xcs/spring/configuration/ConditionConfigurationApplication.java
  class ConditionConfigurationApplication (line 10) | public class ConditionConfigurationApplication {
    method main (line 12) | public static void main(String[] args) {

FILE: spring-annotation/spring-annotation-conditional/src/main/java/com/xcs/spring/configuration/condition/ConfigPropertyCondition.java
  class ConfigPropertyCondition (line 7) | public class ConfigPropertyCondition implements Condition {
    method matches (line 8) | @Override

FILE: spring-annotation/spring-annotation-conditional/src/main/java/com/xcs/spring/configuration/config/MyConfigConfiguration.java
  class MyConfigConfiguration (line 10) | @Configuration
    method user3 (line 14) | @Bean
    method user4 (line 19) | @Bean

FILE: spring-annotation/spring-annotation-conditional/src/main/java/com/xcs/spring/configuration/entity/User3.java
  class User3 (line 3) | public class User3 {

FILE: spring-annotation/spring-annotation-conditional/src/main/java/com/xcs/spring/configuration/entity/User4.java
  class User4 (line 3) | public class User4 {

FILE: spring-annotation/spring-annotation-conditional/src/main/java/com/xcs/spring/custom/ConditionCustomApplication.java
  class ConditionCustomApplication (line 10) | public class ConditionCustomApplication {
    method main (line 12) | public static void main(String[] args) {

FILE: spring-annotation/spring-annotation-conditional/src/main/java/com/xcs/spring/custom/condition/CustomActiveCondition.java
  class CustomActiveCondition (line 7) | public class CustomActiveCondition implements Condition {
    method matches (line 8) | @Override

FILE: spring-annotation/spring-annotation-conditional/src/main/java/com/xcs/spring/custom/config/MyCustomConfiguration.java
  class MyCustomConfiguration (line 9) | @Configuration
    method user5 (line 13) | @Bean
    method user6 (line 18) | @Bean

FILE: spring-annotation/spring-annotation-conditional/src/main/java/com/xcs/spring/custom/entity/User5.java
  class User5 (line 3) | public class User5 {

FILE: spring-annotation/spring-annotation-conditional/src/main/java/com/xcs/spring/custom/entity/User6.java
  class User6 (line 3) | public class User6 {

FILE: spring-annotation/spring-annotation-configuration/src/main/java/com/xcs/spring/ConfigurationApplication.java
  class ConfigurationApplication (line 10) | public class ConfigurationApplication {
    method main (line 12) | public static void main(String[] args) {

FILE: spring-annotation/spring-annotation-configuration/src/main/java/com/xcs/spring/bean/MyBean.java
  class MyBean (line 7) | public class MyBean {

FILE: spring-annotation/spring-annotation-configuration/src/main/java/com/xcs/spring/config/MyConfiguration.java
  class MyConfiguration (line 11) | @Configuration
    method myBean (line 14) | @Bean

FILE: spring-annotation/spring-annotation-dependsOn/src/main/java/com/xcs/spring/DependsOnApplication.java
  class DependsOnApplication (line 10) | public class DependsOnApplication {
    method main (line 12) | public static void main(String[] args) {

FILE: spring-annotation/spring-annotation-dependsOn/src/main/java/com/xcs/spring/bean/BeanA.java
  class BeanA (line 9) | public class BeanA implements DisposableBean {
    method BeanA (line 11) | public BeanA() {
    method destroy (line 15) | @Override

FILE: spring-annotation/spring-annotation-dependsOn/src/main/java/com/xcs/spring/bean/BeanB.java
  class BeanB (line 9) | public class BeanB implements DisposableBean {
    method BeanB (line 11) | public BeanB() {
    method destroy (line 15) | @Override

FILE: spring-annotation/spring-annotation-dependsOn/src/main/java/com/xcs/spring/bean/BeanC.java
  class BeanC (line 9) | public class BeanC implements DisposableBean {
    method BeanC (line 11) | public BeanC() {
    method destroy (line 15) | @Override

FILE: spring-annotation/spring-annotation-dependsOn/src/main/java/com/xcs/spring/config/MyConfiguration.java
  class MyConfiguration (line 14) | @Configuration
    method beanA (line 17) | @Bean
    method beanB (line 23) | @Bean
    method beanC (line 29) | @Bean

FILE: spring-annotation/spring-annotation-import/src/main/java/com/xcs/spring/ImportApplication.java
  class ImportApplication (line 10) | public class ImportApplication {
    method main (line 12) | public static void main(String[] args) {

FILE: spring-annotation/spring-annotation-import/src/main/java/com/xcs/spring/bean/MyBean.java
  class MyBean (line 7) | public class MyBean {

FILE: spring-annotation/spring-annotation-import/src/main/java/com/xcs/spring/bean/MyBeanA.java
  class MyBeanA (line 7) | public class MyBeanA {

FILE: spring-annotation/spring-annotation-import/src/main/java/com/xcs/spring/bean/MyBeanB.java
  class MyBeanB (line 7) | public class MyBeanB {

FILE: spring-annotation/spring-annotation-import/src/main/java/com/xcs/spring/bean/MyBeanC.java
  class MyBeanC (line 7) | public class MyBeanC {

FILE: spring-annotation/spring-annotation-import/src/main/java/com/xcs/spring/config/MyConfiguration.java
  class MyConfiguration (line 11) | @Configuration

FILE: spring-annotation/spring-annotation-import/src/main/java/com/xcs/spring/config/MyDeferredImportSelector.java
  class MyDeferredImportSelector (line 11) | public class MyDeferredImportSelector implements DeferredImportSelector {
    method selectImports (line 13) | @Override

FILE: spring-annotation/spring-annotation-import/src/main/java/com/xcs/spring/config/MyImportBeanDefinitionRegistrar.java
  class MyImportBeanDefinitionRegistrar (line 13) | public class MyImportBeanDefinitionRegistrar implements ImportBeanDefini...
    method registerBeanDefinitions (line 14) | @Override

FILE: spring-annotation/spring-annotation-import/src/main/java/com/xcs/spring/config/MyImportSelector.java
  class MyImportSelector (line 11) | public class MyImportSelector implements ImportSelector {
    method selectImports (line 12) | @Override

FILE: spring-annotation/spring-annotation-lazy/src/main/java/com/xcs/spring/LazyApplication.java
  class LazyApplication (line 11) | public class LazyApplication {
    method main (line 13) | public static void main(String[] args) {

FILE: spring-annotation/spring-annotation-lazy/src/main/java/com/xcs/spring/bean/MyBean.java
  class MyBean (line 3) | public class MyBean {
    method MyBean (line 5) | public MyBean() {
    method show (line 9) | public void show() {

FILE: spring-annotation/spring-annotation-lazy/src/main/java/com/xcs/spring/config/MyConfiguration.java
  class MyConfiguration (line 9) | @Configuration
    method myBean (line 12) | @Bean
    method myService (line 19) | @Bean

FILE: spring-annotation/spring-annotation-lazy/src/main/java/com/xcs/spring/service/MyService.java
  class MyService (line 7) | public class MyService  {
    method show (line 13) | public void show() {

FILE: spring-annotation/spring-annotation-propertySource/src/main/java/com/xcs/spring/PropertySourceApplication.java
  class PropertySourceApplication (line 10) | public class PropertySourceApplication {
    method main (line 12) | public static void main(String[] args) {

FILE: spring-annotation/spring-annotation-propertySource/src/main/java/com/xcs/spring/config/MyConfiguration.java
  class MyConfiguration (line 10) | @Configuration

FILE: spring-annotation/spring-annotation-value/src/main/java/com/xcs/spring/ValueApplication.java
  class ValueApplication (line 10) | public class ValueApplication {
    method main (line 12) | public static void main(String[] args) {

FILE: spring-annotation/spring-annotation-value/src/main/java/com/xcs/spring/config/MyConfiguration.java
  class MyConfiguration (line 12) | @Configuration
    method myService (line 16) | @Bean

FILE: spring-annotation/spring-annotation-value/src/main/java/com/xcs/spring/service/MyService.java
  class MyService (line 13) | public class MyService implements InitializingBean {
    method afterPropertiesSet (line 48) | @Override

FILE: spring-aop/spring-aop-advice-afterReturningAdvice/src/main/java/com/xcs/spring/AfterReturningAdviceDemo.java
  class AfterReturningAdviceDemo (line 5) | public class AfterReturningAdviceDemo {
    method main (line 7) | public static void main(String[] args) {

FILE: spring-aop/spring-aop-advice-afterReturningAdvice/src/main/java/com/xcs/spring/MyAfterReturningAdvice.java
  class MyAfterReturningAdvice (line 7) | public class MyAfterReturningAdvice implements AfterReturningAdvice {
    method afterReturning (line 8) | @Override

FILE: spring-aop/spring-aop-advice-afterReturningAdvice/src/main/java/com/xcs/spring/MyService.java
  class MyService (line 3) | public class MyService {
    method foo (line 5) | public void foo() {

FILE: spring-aop/spring-aop-advice-introductionInterceptor/src/main/java/com/xcs/spring/IntroductionInterceptorDemo.java
  class IntroductionInterceptorDemo (line 6) | public class IntroductionInterceptorDemo {
    method main (line 8) | public static void main(String[] args) {

FILE: spring-aop/spring-aop-advice-introductionInterceptor/src/main/java/com/xcs/spring/MyMonitoringCapable.java
  type MyMonitoringCapable (line 3) | public interface MyMonitoringCapable {
    method toggleMonitoring (line 4) | void toggleMonitoring();

FILE: spring-aop/spring-aop-advice-introductionInterceptor/src/main/java/com/xcs/spring/MyMonitoringIntroductionAdvice.java
  class MyMonitoringIntroductionAdvice (line 6) | public class MyMonitoringIntroductionAdvice extends DelegatingIntroducti...
    method setActive (line 10) | public void setActive(boolean active) {
    method toggleMonitoring (line 14) | @Override
    method doProceed (line 20) | @Override

FILE: spring-aop/spring-aop-advice-introductionInterceptor/src/main/java/com/xcs/spring/MyService.java
  class MyService (line 3) | public class MyService {
    method foo (line 5) | public void foo() {

FILE: spring-aop/spring-aop-advice-methodBeforeAdvice/src/main/java/com/xcs/spring/MethodBeforeAdviceDemo.java
  class MethodBeforeAdviceDemo (line 5) | public class MethodBeforeAdviceDemo {
    method main (line 7) | public static void main(String[] args) {

FILE: spring-aop/spring-aop-advice-methodBeforeAdvice/src/main/java/com/xcs/spring/MyMethodBeforeAdvice.java
  class MyMethodBeforeAdvice (line 7) | public class MyMethodBeforeAdvice implements MethodBeforeAdvice {
    method before (line 8) | @Override

FILE: spring-aop/spring-aop-advice-methodBeforeAdvice/src/main/java/com/xcs/spring/MyService.java
  class MyService (line 3) | public class MyService {
    method foo (line 5) | public void foo() {

FILE: spring-aop/spring-aop-advice-methodInterceptor/src/main/java/com/xcs/spring/MethodInterceptorDemo.java
  class MethodInterceptorDemo (line 5) | public class MethodInterceptorDemo {
    method main (line 7) | public static void main(String[] args) {

FILE: spring-aop/spring-aop-advice-methodInterceptor/src/main/java/com/xcs/spring/MyMethodInterceptor.java
  class MyMethodInterceptor (line 6) | public class MyMethodInterceptor implements MethodInterceptor {
    method invoke (line 7) | @Override

FILE: spring-aop/spring-aop-advice-methodInterceptor/src/main/java/com/xcs/spring/MyService.java
  class MyService (line 3) | public class MyService {
    method foo (line 5) | public void foo() {

FILE: spring-aop/spring-aop-advice-throwsAdvice/src/main/java/com/xcs/spring/MyService.java
  class MyService (line 3) | public class MyService {
    method foo (line 5) | public void foo() {

FILE: spring-aop/spring-aop-advice-throwsAdvice/src/main/java/com/xcs/spring/MyThrowsAdvice.java
  class MyThrowsAdvice (line 5) | public class MyThrowsAdvice implements ThrowsAdvice {
    method afterThrowing (line 6) | public void afterThrowing(Exception ex) throws Throwable {

FILE: spring-aop/spring-aop-advice-throwsAdvice/src/main/java/com/xcs/spring/ThrowsAdviceDemo.java
  class ThrowsAdviceDemo (line 5) | public class ThrowsAdviceDemo {
    method main (line 7) | public static void main(String[] args) {

FILE: spring-aop/spring-aop-advised/src/main/java/com/xcs/spring/AdvisedDemo.java
  class AdvisedDemo (line 7) | public class AdvisedDemo {
    method main (line 9) | public static void main(String[] args) {

FILE: spring-aop/spring-aop-advised/src/main/java/com/xcs/spring/MyService.java
  type MyService (line 3) | public interface MyService {
    method foo (line 4) | void foo();

FILE: spring-aop/spring-aop-advised/src/main/java/com/xcs/spring/MyServiceImpl.java
  class MyServiceImpl (line 3) | public class MyServiceImpl implements MyService {
    method foo (line 5) | @Override

FILE: spring-aop/spring-aop-advisor/src/main/java/com/xcs/spring/AdvisorDemo.java
  class AdvisorDemo (line 5) | public class AdvisorDemo {
    method main (line 7) | public static void main(String[] args) {

FILE: spring-aop/spring-aop-advisor/src/main/java/com/xcs/spring/MyAdvice.java
  class MyAdvice (line 6) | public class MyAdvice implements MethodInterceptor {
    method invoke (line 8) | @Override

FILE: spring-aop/spring-aop-advisor/src/main/java/com/xcs/spring/MyCustomAdvisor.java
  class MyCustomAdvisor (line 11) | public class MyCustomAdvisor implements PointcutAdvisor {
    method getPointcut (line 23) | @Override
    method getAdvice (line 28) | @Override
    method isPerInstance (line 33) | @Override

FILE: spring-aop/spring-aop-advisor/src/main/java/com/xcs/spring/MyService.java
  class MyService (line 3) | public class MyService {
    method foo (line 5) | @MyCustomAnnotation

FILE: spring-aop/spring-aop-advisorAdapter/src/main/java/com/xcs/spring/AdvisorAdapterDemo.java
  class AdvisorAdapterDemo (line 6) | public class AdvisorAdapterDemo {
    method main (line 8) | public static void main(String[] args) {

FILE: spring-aop/spring-aop-advisorAdapter/src/main/java/com/xcs/spring/MyNullReturningAdvice.java
  class MyNullReturningAdvice (line 5) | public class MyNullReturningAdvice implements NullReturningAdvice {
    method nullReturning (line 7) | @Override

FILE: spring-aop/spring-aop-advisorAdapter/src/main/java/com/xcs/spring/MyService.java
  class MyService (line 3) | public class MyService {
    method foo (line 5) | public String foo() {
    method bar (line 10) | public String bar() {

FILE: spring-aop/spring-aop-advisorAdapter/src/main/java/com/xcs/spring/NullReturningAdvice.java
  type NullReturningAdvice (line 11) | public interface NullReturningAdvice extends AfterAdvice {
    method nullReturning (line 21) | Object nullReturning(Method method, Object[] args, @Nullable Object ta...

FILE: spring-aop/spring-aop-advisorAdapter/src/main/java/com/xcs/spring/NullReturningAdviceAdapter.java
  class NullReturningAdviceAdapter (line 11) | public class NullReturningAdviceAdapter implements AdvisorAdapter {
    method supportsAdvice (line 18) | @Override
    method getInterceptor (line 28) | @Override

FILE: spring-aop/spring-aop-advisorAdapter/src/main/java/com/xcs/spring/NullReturningAdviceInterceptor.java
  class NullReturningAdviceInterceptor (line 11) | public class NullReturningAdviceInterceptor implements MethodInterceptor...
    method NullReturningAdviceInterceptor (line 20) | public NullReturningAdviceInterceptor(NullReturningAdvice advice) {
    method invoke (line 31) | @Override

FILE: spring-aop/spring-aop-advisorAdapterRegistry/src/main/java/com/xcs/spring/AdvisorAdapterRegistryDemo.java
  class AdvisorAdapterRegistryDemo (line 7) | public class AdvisorAdapterRegistryDemo {
    method main (line 9) | public static void main(String[] args) {

FILE: spring-aop/spring-aop-advisorAdapterRegistry/src/main/java/com/xcs/spring/MyMethodBeforeAdvice.java
  class MyMethodBeforeAdvice (line 7) | public class MyMethodBeforeAdvice implements MethodBeforeAdvice {
    method before (line 8) | @Override

FILE: spring-aop/spring-aop-advisorChainFactory/src/main/java/com/xcs/spring/AdvisorChainFactoryDemo.java
  class AdvisorChainFactoryDemo (line 9) | public class AdvisorChainFactoryDemo {
    method main (line 11) | public static void main(String[] args) throws NoSuchMethodException {

FILE: spring-aop/spring-aop-advisorChainFactory/src/main/java/com/xcs/spring/MyAfterReturningAdvice.java
  class MyAfterReturningAdvice (line 7) | public class MyAfterReturningAdvice implements AfterReturningAdvice {
    method afterReturning (line 8) | @Override

FILE: spring-aop/spring-aop-advisorChainFactory/src/main/java/com/xcs/spring/MyMethodBeforeAdvice.java
  class MyMethodBeforeAdvice (line 7) | public class MyMethodBeforeAdvice implements MethodBeforeAdvice {
    method before (line 8) | @Override

FILE: spring-aop/spring-aop-advisorChainFactory/src/main/java/com/xcs/spring/MyService.java
  class MyService (line 3) | public class MyService {
    method foo (line 5) | public void foo() {

FILE: spring-aop/spring-aop-annotationAwareAspectJAutoProxyCreator/src/main/java/com/xcs/spring/AnnotationAwareAspectJAutoProxyCreatorDemo.java
  class AnnotationAwareAspectJAutoProxyCreatorDemo (line 5) | public class AnnotationAwareAspectJAutoProxyCreatorDemo {
    method main (line 7) | public static void main(String[] args) {

FILE: spring-aop/spring-aop-annotationAwareAspectJAutoProxyCreator/src/main/java/com/xcs/spring/AppConfig.java
  class AppConfig (line 7) | @Configuration

FILE: spring-aop/spring-aop-annotationAwareAspectJAutoProxyCreator/src/main/java/com/xcs/spring/MyAspect.java
  class MyAspect (line 7) | @Aspect
    method before (line 11) | @Before("execution(* com.xcs.spring.MyService+.*(..))")

FILE: spring-aop/spring-aop-annotationAwareAspectJAutoProxyCreator/src/main/java/com/xcs/spring/MyService.java
  class MyService (line 5) | @Service
    method foo (line 8) | public void foo() {

FILE: spring-aop/spring-aop-aopContext/src/main/java/com/xcs/spring/AopContextDemo.java
  class AopContextDemo (line 7) | public class AopContextDemo {
    method main (line 9) | public static void main(String[] args) {

FILE: spring-aop/spring-aop-aopContext/src/main/java/com/xcs/spring/MyMethodBeforeAdvice.java
  class MyMethodBeforeAdvice (line 7) | public class MyMethodBeforeAdvice implements MethodBeforeAdvice {
    method before (line 8) | @Override

FILE: spring-aop/spring-aop-aopContext/src/main/java/com/xcs/spring/MyService.java
  class MyService (line 5) | @MyAnnotation
    method foo (line 8) | public void foo() {
    method bar (line 16) | public void bar() {

FILE: spring-aop/spring-aop-aopProxy/src/main/java/com/xcs/spring/AopProxyDemo.java
  class AopProxyDemo (line 8) | public class AopProxyDemo {
    method main (line 10) | public static void main(String[] args) throws Exception {
    method cglibProxy (line 20) | private static void cglibProxy() throws Exception {
    method jdkProxy (line 52) | private static void jdkProxy() throws Exception {

FILE: spring-aop/spring-aop-aopProxy/src/main/java/com/xcs/spring/MyMethodInterceptor.java
  class MyMethodInterceptor (line 6) | public class MyMethodInterceptor implements MethodInterceptor {
    method invoke (line 7) | @Override

FILE: spring-aop/spring-aop-aopProxy/src/main/java/com/xcs/spring/MyService.java
  type MyService (line 3) | public interface MyService {
    method foo (line 4) | void foo();

FILE: spring-aop/spring-aop-aopProxy/src/main/java/com/xcs/spring/MyServiceImpl.java
  class MyServiceImpl (line 3) | public class MyServiceImpl implements MyService {
    method foo (line 5) | @Override

FILE: spring-aop/spring-aop-aopProxyFactory/src/main/java/com/xcs/spring/AopProxyFactoryDemo.java
  class AopProxyFactoryDemo (line 7) | public class AopProxyFactoryDemo {
    method main (line 9) | public static void main(String[] args) {
    method jdkProxy (line 18) | private static void jdkProxy() {
    method cglibProxy (line 37) | private static void cglibProxy() {

FILE: spring-aop/spring-aop-aopProxyFactory/src/main/java/com/xcs/spring/MyService.java
  type MyService (line 3) | public interface MyService {
    method doSomething (line 5) | String doSomething();

FILE: spring-aop/spring-aop-aopProxyFactory/src/main/java/com/xcs/spring/MyServiceImpl.java
  class MyServiceImpl (line 3) | public class MyServiceImpl implements MyService {
    method doSomething (line 5) | @Override

FILE: spring-aop/spring-aop-aspectInstanceFactory/src/main/java/com/xcs/spring/AspectInstanceFactoryDemo.java
  class AspectInstanceFactoryDemo (line 9) | public class AspectInstanceFactoryDemo {
    method main (line 11) | public static void main(String[] args) {

FILE: spring-aop/spring-aop-aspectInstanceFactory/src/main/java/com/xcs/spring/MyAspect.java
  class MyAspect (line 5) | @Aspect

FILE: spring-aop/spring-aop-aspectJAdvisorFactory/src/main/java/com/xcs/spring/AspectJAdvisorFactoryDemo.java
  class AspectJAdvisorFactoryDemo (line 11) | public class AspectJAdvisorFactoryDemo {
    method main (line 13) | public static void main(String[] args) {

FILE: spring-aop/spring-aop-aspectJAdvisorFactory/src/main/java/com/xcs/spring/MyAspect.java
  class MyAspect (line 7) | @Aspect
    method before (line 10) | @Before("execution(* com.xcs.spring.MyService.foo(..))")
    method after (line 15) | @After("execution(* com.xcs.spring.MyService.foo(..))")

FILE: spring-aop/spring-aop-aspectJAdvisorFactory/src/main/java/com/xcs/spring/MyService.java
  class MyService (line 3) | public class MyService {
    method foo (line 4) | public void foo() {

FILE: spring-aop/spring-aop-beanFactoryAdvisorRetrievalHelper/src/main/java/com/xcs/spring/AppConfig.java
  class AppConfig (line 7) | @Configuration

FILE: spring-aop/spring-aop-beanFactoryAdvisorRetrievalHelper/src/main/java/com/xcs/spring/BeanFactoryAdvisorRetrievalHelperDemo.java
  class BeanFactoryAdvisorRetrievalHelperDemo (line 5) | public class BeanFactoryAdvisorRetrievalHelperDemo {
    method main (line 7) | public static void main(String[] args) {

FILE: spring-aop/spring-aop-beanFactoryAdvisorRetrievalHelper/src/main/java/com/xcs/spring/MyAdvice.java
  class MyAdvice (line 7) | public class MyAdvice implements MethodBeforeAdvice {
    method before (line 8) | @Override

FILE: spring-aop/spring-aop-beanFactoryAdvisorRetrievalHelper/src/main/java/com/xcs/spring/MyAdvisor.java
  class MyAdvisor (line 8) | @Component
    method getPointcut (line 11) | @Override
    method getAdvice (line 16) | @Override

FILE: spring-aop/spring-aop-beanFactoryAdvisorRetrievalHelper/src/main/java/com/xcs/spring/MyService.java
  class MyService (line 5) | @Service
    method foo (line 8) | public void foo() {

FILE: spring-aop/spring-aop-beanFactoryAspectJAdvisorsBuilder/src/main/java/com/xcs/spring/AppConfig.java
  class AppConfig (line 7) | @Configuration

FILE: spring-aop/spring-aop-beanFactoryAspectJAdvisorsBuilder/src/main/java/com/xcs/spring/BeanFactoryAspectJAdvisorsBuilderDemo.java
  class BeanFactoryAspectJAdvisorsBuilderDemo (line 5) | public class BeanFactoryAspectJAdvisorsBuilderDemo {
    method main (line 7) | public static void main(String[] args) {

FILE: spring-aop/spring-aop-beanFactoryAspectJAdvisorsBuilder/src/main/java/com/xcs/spring/MyAspect.java
  class MyAspect (line 7) | @Aspect
    method before (line 11) | @Before("execution(* com.xcs.spring.MyService.foo(..))")

FILE: spring-aop/spring-aop-beanFactoryAspectJAdvisorsBuilder/src/main/java/com/xcs/spring/MyService.java
  class MyService (line 5) | @Service
    method foo (line 7) | public void foo() {

FILE: spring-aop/spring-aop-cglibProxy/src/main/java/com/xcs/spring/CglibProxyDemo.java
  class CglibProxyDemo (line 5) | public class CglibProxyDemo {
    method main (line 7) | public static void main(String[] args) {

FILE: spring-aop/spring-aop-cglibProxy/src/main/java/com/xcs/spring/MyMethodInterceptor.java
  class MyMethodInterceptor (line 8) | public class MyMethodInterceptor implements MethodInterceptor {
    method intercept (line 9) | @Override

FILE: spring-aop/spring-aop-cglibProxy/src/main/java/com/xcs/spring/MyService.java
  type MyService (line 3) | public interface MyService {
    method doSomething (line 4) | void doSomething();

FILE: spring-aop/spring-aop-cglibProxy/src/main/java/com/xcs/spring/MyServiceImpl.java
  class MyServiceImpl (line 3) | public class MyServiceImpl implements MyService {
    method doSomething (line 5) | @Override

FILE: spring-aop/spring-aop-classFilter/src/main/java/com/xcs/spring/ClassFilterDemo.java
  class ClassFilterDemo (line 9) | public class ClassFilterDemo {
    method main (line 10) | public static void main(String[] args) {

FILE: spring-aop/spring-aop-classFilter/src/main/java/com/xcs/spring/MyService.java
  class MyService (line 3) | @MyClassAnnotation

FILE: spring-aop/spring-aop-classFilter/src/main/java/com/xcs/spring/MySubService.java
  class MySubService (line 3) | public class MySubService extends MyService{

FILE: spring-aop/spring-aop-enableAspectJAutoProxy/src/main/java/com/xcs/spring/AppConfig.java
  class AppConfig (line 7) | @Configuration

FILE: spring-aop/spring-aop-enableAspectJAutoProxy/src/main/java/com/xcs/spring/EnableAspectJAutoProxyDemo.java
  class EnableAspectJAutoProxyDemo (line 5) | public class EnableAspectJAutoProxyDemo {
    method main (line 7) | public static void main(String[] args) {

FILE: spring-aop/spring-aop-enableAspectJAutoProxy/src/main/java/com/xcs/spring/MyAspect.java
  class MyAspect (line 7) | @Aspect
    method before (line 11) | @Before("execution(* com.xcs.spring.MyService+.*(..))")

FILE: spring-aop/spring-aop-enableAspectJAutoProxy/src/main/java/com/xcs/spring/MyService.java
  class MyService (line 5) | @Service
    method foo (line 8) | public void foo() {

FILE: spring-aop/spring-aop-enableLoadTimeWeaving/src/main/java/com/xcs/spring/AppConfig.java
  class AppConfig (line 6) | @Configuration

FILE: spring-aop/spring-aop-enableLoadTimeWeaving/src/main/java/com/xcs/spring/EnableLoadTimeWeavingDemo.java
  class EnableLoadTimeWeavingDemo (line 5) | public class EnableLoadTimeWeavingDemo {
    method main (line 7) | public static void main(String[] args) {

FILE: spring-aop/spring-aop-enableLoadTimeWeaving/src/main/java/com/xcs/spring/MyLTWAspect.java
  class MyLTWAspect (line 8) | @Aspect
    method around (line 11) | @Around("ltwPointcut()")
    method ltwPointcut (line 22) | @Pointcut("execution(public * com.xcs.spring.MyService.*(..))")

FILE: spring-aop/spring-aop-enableLoadTimeWeaving/src/main/java/com/xcs/spring/MyService.java
  class MyService (line 3) | public class MyService {
    method foo (line 5) | public void foo() {

FILE: spring-aop/spring-aop-exposeInvocationInterceptor/src/main/java/com/xcs/spring/AppConfig.java
  class AppConfig (line 7) | @EnableAspectJAutoProxy

FILE: spring-aop/spring-aop-exposeInvocationInterceptor/src/main/java/com/xcs/spring/ExposeInvocationInterceptorDemo.java
  class ExposeInvocationInterceptorDemo (line 5) | public class ExposeInvocationInterceptorDemo {
    method main (line 7) | public static void main(String[] args) {

FILE: spring-aop/spring-aop-exposeInvocationInterceptor/src/main/java/com/xcs/spring/LogUtil.java
  class LogUtil (line 6) | public class LogUtil {
    method print (line 8) | public static void print() {

FILE: spring-aop/spring-aop-exposeInvocationInterceptor/src/main/java/com/xcs/spring/MyMethodInterceptor.java
  class MyMethodInterceptor (line 7) | @Aspect
    method before (line 11) | @Before("execution(public * com.xcs.spring.MyService.*(..))")

FILE: spring-aop/spring-aop-exposeInvocationInterceptor/src/main/java/com/xcs/spring/MyService.java
  class MyService (line 5) | @Service
    method foo (line 8) | public void foo() {

FILE: spring-aop/spring-aop-jdkProxy/src/main/java/com/xcs/spring/JdkProxyDemo.java
  class JdkProxyDemo (line 5) | public class JdkProxyDemo {
    method main (line 7) | public static void main(String[] args) {

FILE: spring-aop/spring-aop-jdkProxy/src/main/java/com/xcs/spring/MyInvocationHandler.java
  class MyInvocationHandler (line 6) | class MyInvocationHandler implements InvocationHandler {
    method MyInvocationHandler (line 10) | public MyInvocationHandler(Object target) {
    method invoke (line 14) | @Override

FILE: spring-aop/spring-aop-jdkProxy/src/main/java/com/xcs/spring/MyService.java
  type MyService (line 3) | public interface MyService {
    method doSomething (line 5) | void doSomething();

FILE: spring-aop/spring-aop-jdkProxy/src/main/java/com/xcs/spring/MyServiceImpl.java
  class MyServiceImpl (line 3) | public class MyServiceImpl implements MyService {
    method doSomething (line 5) | @Override

FILE: spring-aop/spring-aop-metadataAwareAspectInstanceFactory/src/main/java/com/xcs/spring/MetadataAwareAspectInstanceFactoryDemo.java
  class MetadataAwareAspectInstanceFactoryDemo (line 7) | public class MetadataAwareAspectInstanceFactoryDemo {
    method main (line 9) | public static void main(String[] args) {

FILE: spring-aop/spring-aop-metadataAwareAspectInstanceFactory/src/main/java/com/xcs/spring/MyAspect.java
  class MyAspect (line 5) | @Aspect

FILE: spring-aop/spring-aop-methodMatcher/src/main/java/com/xcs/spring/MethodMatcherDemo.java
  class MethodMatcherDemo (line 10) | public class MethodMatcherDemo {
    method main (line 12) | public static void main(String[] args) throws Exception {

FILE: spring-aop/spring-aop-methodMatcher/src/main/java/com/xcs/spring/MyService.java
  class MyService (line 3) | public class MyService {
    method setName (line 5) | @MyMethodAnnotation

FILE: spring-aop/spring-aop-pointcut/src/main/java/com/xcs/spring/MyCustomAdvice.java
  class MyCustomAdvice (line 7) | class MyCustomAdvice implements MethodBeforeAdvice {
    method before (line 8) | @Override

FILE: spring-aop/spring-aop-pointcut/src/main/java/com/xcs/spring/MyCustomPointcut.java
  class MyCustomPointcut (line 9) | class MyCustomPointcut implements Pointcut {
    method getClassFilter (line 11) | @Override
    method getMethodMatcher (line 17) | @Override

FILE: spring-aop/spring-aop-pointcut/src/main/java/com/xcs/spring/MyService.java
  class MyService (line 3) | @MyClassAnnotation
    method getName (line 6) | public void getName() {
    method setName (line 10) | @MyMethodAnnotation
    method getAge (line 15) | public void getAge() {

FILE: spring-aop/spring-aop-pointcut/src/main/java/com/xcs/spring/PointcutDemo.java
  class PointcutDemo (line 17) | public class PointcutDemo {
    method main (line 18) | public static void main(String[] args) {
    method customPointcut (line 29) | private static void customPointcut() {
    method aspectJExpressionPointcut (line 37) | private static void aspectJExpressionPointcut() {
    method annotationMatchingPointcut (line 47) | private static void annotationMatchingPointcut() {
    method nameMatchMethodPointcut (line 56) | private static void nameMatchMethodPointcut() {
    method jdkRegexpMethodPointcut (line 66) | private static void jdkRegexpMethodPointcut() {
    method showMatchesLog (line 72) | public static void showMatchesLog(Pointcut pointcut) {

FILE: spring-aop/spring-aop-proxyFactory/src/main/java/com/xcs/spring/MyService.java
  class MyService (line 3) | public class MyService {

FILE: spring-aop/spring-aop-proxyFactory/src/main/java/com/xcs/spring/ProxyFactoryDemo.java
  class ProxyFactoryDemo (line 5) | public class ProxyFactoryDemo {
    method main (line 7) | public static void main(String[] args) {

FILE: spring-aop/spring-aop-proxyMethodInvocation/src/main/java/com/xcs/spring/MyInvocationHandler.java
  class MyInvocationHandler (line 10) | class MyInvocationHandler implements InvocationHandler {
    method MyInvocationHandler (line 19) | public MyInvocationHandler(Object target) {
    method invoke (line 31) | @Override

FILE: spring-aop/spring-aop-proxyMethodInvocation/src/main/java/com/xcs/spring/MyMethodInterceptor.java
  class MyMethodInterceptor (line 6) | public class MyMethodInterceptor implements MethodInterceptor {
    method invoke (line 7) | @Override

FILE: spring-aop/spring-aop-proxyMethodInvocation/src/main/java/com/xcs/spring/MyReflectiveMethodInvocation.java
  class MyReflectiveMethodInvocation (line 12) | public class MyReflectiveMethodInvocation extends ReflectiveMethodInvoca...
    method MyReflectiveMethodInvocation (line 23) | public MyReflectiveMethodInvocation(Object proxy, Object target, Metho...

FILE: spring-aop/spring-aop-proxyMethodInvocation/src/main/java/com/xcs/spring/MyService.java
  type MyService (line 3) | public interface MyService {
    method foo (line 4) | void foo();

FILE: spring-aop/spring-aop-proxyMethodInvocation/src/main/java/com/xcs/spring/MyServiceImpl.java
  class MyServiceImpl (line 3) | public class MyServiceImpl implements MyService {
    method foo (line 5) | @Override

FILE: spring-aop/spring-aop-proxyMethodInvocation/src/main/java/com/xcs/spring/ProxyMethodInvocationDemo.java
  class ProxyMethodInvocationDemo (line 5) | public class ProxyMethodInvocationDemo {
    method main (line 7) | public static void main(String[] args) {

FILE: spring-aop/spring-aop-targetSource/src/main/java/com/xcs/spring/ConnectionPoolTargetSource.java
  class ConnectionPoolTargetSource (line 14) | public class ConnectionPoolTargetSource implements TargetSource {
    method ConnectionPoolTargetSource (line 26) | public ConnectionPoolTargetSource(int poolSize) {
    method initializeConnectionPool (line 36) | private void initializeConnectionPool(int poolSize) {
    method getTargetClass (line 48) | @Override
    method isStatic (line 58) | @Override
    method getTarget (line 69) | @Override
    method releaseTarget (line 80) | @Override

FILE: spring-aop/spring-aop-targetSource/src/main/java/com/xcs/spring/MyConnection.java
  class MyConnection (line 3) | public class MyConnection {
    method MyConnection (line 7) | public MyConnection(String name) {
    method getName (line 11) | public String getName() {
    method setName (line 15) | public void setName(String name) {
    method toString (line 19) | @Override

FILE: spring-aop/spring-aop-targetSource/src/main/java/com/xcs/spring/TargetSourceDemo.java
  class TargetSourceDemo (line 5) | public class TargetSourceDemo {
    method main (line 7) | public static void main(String[] args) {

FILE: spring-aop/spring-aop-targetSourceCreator/src/main/java/com/xcs/spring/AppConfig.java
  class AppConfig (line 7) | @EnableAspectJAutoProxy

FILE: spring-aop/spring-aop-targetSourceCreator/src/main/java/com/xcs/spring/ConnectionPoolTargetSource.java
  class ConnectionPoolTargetSource (line 14) | public class ConnectionPoolTargetSource implements TargetSource {
    method ConnectionPoolTargetSource (line 26) | public ConnectionPoolTargetSource(int poolSize) {
    method initializeConnectionPool (line 36) | private void initializeConnectionPool(int poolSize) {
    method getTargetClass (line 48) | @Override
    method isStatic (line 58) | @Override
    method getTarget (line 69) | @Override
    method releaseTarget (line 80) | @Override

FILE: spring-aop/spring-aop-targetSourceCreator/src/main/java/com/xcs/spring/MyConnection.java
  class MyConnection (line 5) | @Service
    method MyConnection (line 10) | public MyConnection(String name) {
    method getName (line 14) | public String getName() {
    method setName (line 18) | public void setName(String name) {
    method toString (line 22) | @Override

FILE: spring-aop/spring-aop-targetSourceCreator/src/main/java/com/xcs/spring/MyTargetSourceCreator.java
  class MyTargetSourceCreator (line 6) | public class MyTargetSourceCreator implements TargetSourceCreator {
    method getTargetSource (line 7) | @Override

FILE: spring-aop/spring-aop-targetSourceCreator/src/main/java/com/xcs/spring/SetMyTargetSourceCreator.java
  class SetMyTargetSourceCreator (line 10) | @Component
    method postProcessAfterInitialization (line 13) | @Override
    method getOrder (line 21) | @Override

FILE: spring-aop/spring-aop-targetSourceCreator/src/main/java/com/xcs/spring/TargetSourceCreatorDemo.java
  class TargetSourceCreatorDemo (line 5) | public class TargetSourceCreatorDemo {
    method main (line 6) | public static void main(String[] args) {

FILE: spring-aware/spring-aware-applicationContextAware/src/main/java/com/xcs/spring/ApplicationContextAwareApplication.java
  class ApplicationContextAwareApplication (line 11) | public class ApplicationContextAwareApplication {
    method main (line 13) | public static void main(String[] args) {

FILE: spring-aware/spring-aware-applicationContextAware/src/main/java/com/xcs/spring/config/MyApplicationContextAware.java
  class MyApplicationContextAware (line 7) | public class MyApplicationContextAware implements ApplicationContextAware {
    method setApplicationContext (line 9) | @Override

FILE: spring-aware/spring-aware-applicationContextAware/src/main/java/com/xcs/spring/config/MyConfiguration.java
  class MyConfiguration (line 10) | @Configuration
    method myApplicationContextAware (line 13) | @Bean

FILE: spring-aware/spring-aware-applicationEventPublisherAware/src/main/java/com/xcs/spring/ApplicationEventPublisherAwareApplication.java
  class ApplicationEventPublisherAwareApplication (line 11) | public class ApplicationEventPublisherAwareApplication {
    method main (line 13) | public static void main(String[] args) {

FILE: spring-aware/spring-aware-applicationEventPublisherAware/src/main/java/com/xcs/spring/config/MyApplicationEventPublisherAware.java
  class MyApplicationEventPublisherAware (line 7) | public class MyApplicationEventPublisherAware implements ApplicationEven...
    method setApplicationEventPublisher (line 11) | @Override
    method publish (line 16) | public void publish(String message) {

FILE: spring-aware/spring-aware-applicationEventPublisherAware/src/main/java/com/xcs/spring/config/MyConfiguration.java
  class MyConfiguration (line 11) | @Configuration
    method myApplicationEventPublisherAware (line 14) | @Bean
    method MyEventListener (line 19) | @Bean

FILE: spring-aware/spring-aware-applicationEventPublisherAware/src/main/java/com/xcs/spring/event/MyEvent.java
  class MyEvent (line 5) | public class MyEvent extends ApplicationEvent {
    method MyEvent (line 9) | public MyEvent(Object source, String message) {
    method getMessage (line 14) | public String getMessage() {

FILE: spring-aware/spring-aware-applicationEventPublisherAware/src/main/java/com/xcs/spring/event/MyEventListener.java
  class MyEventListener (line 5) | public class MyEventListener implements ApplicationListener<MyEvent> {
    method onApplicationEvent (line 7) | @Override

FILE: spring-aware/spring-aware-applicationStartupAware/src/main/java/com/xcs/spring/ApplicationStartupAwareApplication.java
  class ApplicationStartupAwareApplication (line 11) | public class ApplicationStartupAwareApplication {
    method main (line 13) | public static void main(String[] args) {

FILE: spring-aware/spring-aware-applicationStartupAware/src/main/java/com/xcs/spring/config/MyApplicationStartupAware.java
  class MyApplicationStartupAware (line 10) | public class MyApplicationStartupAware implements ApplicationStartupAwar...
    method setApplicationStartup (line 14) | @Override
    method afterPropertiesSet (line 19) | @Override

FILE: spring-aware/spring-aware-applicationStartupAware/src/main/java/com/xcs/spring/config/MyConfiguration.java
  class MyConfiguration (line 10) | @Configuration
    method myApplicationStartupAware (line 13) | @Bean

FILE: spring-aware/spring-aware-beanClassLoaderAware/src/main/java/com/xcs/spring/BeanClassLoaderAwareApplication.java
  class BeanClassLoaderAwareApplication (line 11) | public class BeanClassLoaderAwareApplication {
    method main (line 13) | public static void main(String[] args) {

FILE: spring-aware/spring-aware-beanClassLoaderAware/src/main/java/com/xcs/spring/config/MyBeanClassLoaderAware.java
  class MyBeanClassLoaderAware (line 6) | public class MyBeanClassLoaderAware implements BeanClassLoaderAware {
    method setBeanClassLoader (line 10) | @Override
    method loadAndExecute (line 15) | public void loadAndExecute() {

FILE: spring-aware/spring-aware-beanClassLoaderAware/src/main/java/com/xcs/spring/config/MyConfiguration.java
  class MyConfiguration (line 10) | @Configuration
    method myBeanClassLoaderAware (line 13) | @Bean

FILE: spring-aware/spring-aware-beanClassLoaderAware/src/main/java/com/xcs/spring/service/UserService.java
  type UserService (line 3) | public interface UserService {
    method getUserInfo (line 5) | String getUserInfo();

FILE: spring-aware/spring-aware-beanClassLoaderAware/src/main/java/com/xcs/spring/service/UserServiceImpl.java
  class UserServiceImpl (line 3) | public class UserServiceImpl implements UserService {
    method getUserInfo (line 4) | @Override

FILE: spring-aware/spring-aware-beanFactoryAware/src/main/java/com/xcs/spring/BeanFactoryAwareApplication.java
  class BeanFactoryAwareApplication (line 11) | public class BeanFactoryAwareApplication {
    method main (line 13) | public static void main(String[] args) {

FILE: spring-aware/spring-aware-beanFactoryAware/src/main/java/com/xcs/spring/config/MyConfiguration.java
  class MyConfiguration (line 10) | @Configuration

FILE: spring-aware/spring-aware-beanFactoryAware/src/main/java/com/xcs/spring/service/UserService.java
  class UserService (line 10) | @Service
    method setBeanFactory (line 16) | @Override
    method afterPropertiesSet (line 21) | @Override
    method validateUser (line 30) | public void validateUser(String username, String password) {
    method someConfigurationMethod (line 39) | private boolean someConfigurationMethod() {

FILE: spring-aware/spring-aware-beanFactoryAware/src/main/java/com/xcs/spring/validate/ComplexUserValidator.java
  class ComplexUserValidator (line 5) | @Component("complexUserValidator")
    method validate (line 7) | @Override

FILE: spring-aware/spring-aware-beanFactoryAware/src/main/java/com/xcs/spring/validate/SimpleUserValidator.java
  class SimpleUserValidator (line 5) | @Component("simpleUserValidator")
    method validate (line 7) | @Override

FILE: spring-aware/spring-aware-beanFactoryAware/src/main/java/com/xcs/spring/validate/UserValidator.java
  type UserValidator (line 3) | public interface UserValidator {
    method validate (line 4) | boolean validate(String username, String password);

FILE: spring-aware/spring-aware-beanNameAware/src/main/java/com/xcs/spring/BeanNameAwareApplication.java
  class BeanNameAwareApplication (line 10) | public class BeanNameAwareApplication {
    method main (line 12) | public static void main(String[] args) {

FILE: spring-aware/spring-aware-beanNameAware/src/main/java/com/xcs/spring/config/MyConfiguration.java
  class MyConfiguration (line 10) | @Configuration

FILE: spring-aware/spring-aware-beanNameAware/src/main/java/com/xcs/spring/service/MyAliPayService.java
  class MyAliPayService (line 5) | @Service

FILE: spring-aware/spring-aware-beanNameAware/src/main/java/com/xcs/spring/service/MyBasePayService.java
  class MyBasePayService (line 7) | public abstract class MyBasePayService implements BeanNameAware, Initial...
    method setBeanName (line 11) | @Override
    method afterPropertiesSet (line 16) | @Override
    method destroy (line 21) | @Override

FILE: spring-aware/spring-aware-beanNameAware/src/main/java/com/xcs/spring/service/MyWeChatPayService.java
  class MyWeChatPayService (line 5) | @Service

FILE: spring-aware/spring-aware-embeddedValueResolverAware/src/main/java/com/xcs/spring/EmbeddedValueResolverAwareApplication.java
  class EmbeddedValueResolverAwareApplication (line 11) | public class EmbeddedValueResolverAwareApplication {
    method main (line 13) | public static void main(String[] args) {

FILE: spring-aware/spring-aware-embeddedValueResolverAware/src/main/java/com/xcs/spring/config/MyConfiguration.java
  class MyConfiguration (line 10) | @Configuration
    method myEmbeddedValueResolverAware (line 13) | @Bean

FILE: spring-aware/spring-aware-embeddedValueResolverAware/src/main/java/com/xcs/spring/config/MyEmbeddedValueResolverAware.java
  class MyEmbeddedValueResolverAware (line 6) | public class MyEmbeddedValueResolverAware implements EmbeddedValueResolv...
    method setEmbeddedValueResolver (line 10) | @Override
    method resolve (line 15) | public void resolve() {

FILE: spring-aware/spring-aware-environmentAware/src/main/java/com/xcs/spring/EnvironmentAwareApplication.java
  class EnvironmentAwareApplication (line 11) | public class EnvironmentAwareApplication {
    method main (line 13) | public static void main(String[] args) {

FILE: spring-aware/spring-aware-environmentAware/src/main/java/com/xcs/spring/config/MyConfiguration.java
  class MyConfiguration (line 11) | @Configuration
    method myEnvironmentAware (line 15) | @Bean

FILE: spring-aware/spring-aware-environmentAware/src/main/java/com/xcs/spring/config/MyEnvironmentAware.java
  class MyEnvironmentAware (line 6) | public class MyEnvironmentAware implements EnvironmentAware {
    method setEnvironment (line 10) | @Override
    method getAppProperty (line 15) | public String getAppProperty() {

FILE: spring-aware/spring-aware-importAware/src/main/java/com/xcs/spring/ImportAwareApplication.java
  class ImportAwareApplication (line 6) | public class ImportAwareApplication {
    method main (line 8) | public static void main(String[] args) {

FILE: spring-aware/spring-aware-importAware/src/main/java/com/xcs/spring/config/MyConfiguration.java
  class MyConfiguration (line 6) | @Configuration

FILE: spring-aware/spring-aware-importAware/src/main/java/com/xcs/spring/config/MyImportAware.java
  class MyImportAware (line 9) | public class MyImportAware implements ImportAware {
    method setImportMetadata (line 13) | @Override
    method customBean (line 23) | @Bean

FILE: spring-aware/spring-aware-messageSourceAware/src/main/java/com/xcs/spring/MessageSourceAwareApplication.java
  class MessageSourceAwareApplication (line 11) | public class MessageSourceAwareApplication {
    method main (line 13) | public static void main(String[] args) {

FILE: spring-aware/spring-aware-messageSourceAware/src/main/java/com/xcs/spring/config/MyConfiguration.java
  class MyConfiguration (line 12) | @Configuration
    method myMessageSourceAware (line 15) | @Bean
    method messageSource (line 20) | @Bean

FILE: spring-aware/spring-aware-messageSourceAware/src/main/java/com/xcs/spring/config/MyMessageSourceAware.java
  class MyMessageSourceAware (line 8) | public class MyMessageSourceAware implements MessageSourceAware {
    method setMessageSource (line 12) | @Override
    method getMessage (line 17) | public void getMessage() {

FILE: spring-aware/spring-aware-resourceLoaderAware/src/main/java/com/xcs/spring/ResourceLoaderAwareApplication.java
  class ResourceLoaderAwareApplication (line 11) | public class ResourceLoaderAwareApplication {
    method main (line 13) | public static void main(String[] args) {

FILE: spring-aware/spring-aware-resourceLoaderAware/src/main/java/com/xcs/spring/config/MyConfiguration.java
  class MyConfiguration (line 10) | @Configuration
    method myResourceLoaderAware (line 13) | @Bean

FILE: spring-aware/spring-aware-resourceLoaderAware/src/main/java/com/xcs/spring/config/MyResourceLoaderAware.java
  class MyResourceLoaderAware (line 10) | public class MyResourceLoaderAware implements ResourceLoaderAware {
    method setResourceLoader (line 14) | @Override
    method getResource (line 19) | public void getResource(String location){

FILE: spring-beans/spring-bean-annotatedBeanDefinitionReader/src/main/java/com/xcs/spring/AnnotatedBeanDefinitionReaderDemo.java
  class AnnotatedBeanDefinitionReaderDemo (line 11) | public class AnnotatedBeanDefinitionReaderDemo {
    method main (line 13) | public static void main(String[] args) {

FILE: spring-beans/spring-bean-annotatedBeanDefinitionReader/src/main/java/com/xcs/spring/bean/MyBean.java
  class MyBean (line 7) | public class MyBean {

FILE: spring-beans/spring-bean-beanDefinition/src/main/java/com/xcs/spring/BeanDefinitionDemo.java
  class BeanDefinitionDemo (line 17) | public class BeanDefinitionDemo {
    method main (line 18) | public static void main(String[] args) throws Exception {
    method createBeanDefinition (line 30) | private static BeanDefinition createBeanDefinition() throws IOException {

FILE: spring-beans/spring-bean-beanDefinition/src/main/java/com/xcs/spring/bean/MyBean.java
  class MyBean (line 7) | public class MyBean {
    method getName (line 13) | public String getName() {
    method setName (line 17) | public void setName(String name) {
    method getAge (line 21) | public String getAge() {
    method setAge (line 25) | public void setAge(String age) {
    method init (line 29) | public void init(){
    method destroy (line 33) | public void destroy(){
    method toString (line 37) | @Override

FILE: spring-beans/spring-bean-beanDefinitionHolder/src/main/java/com/xcs/spring/BeanDefinitionHolderDemo.java
  class BeanDefinitionHolderDemo (line 15) | public class BeanDefinitionHolderDemo {
    method main (line 17) | public static void main(String[] args) {

FILE: spring-beans/spring-bean-beanDefinitionHolder/src/main/java/com/xcs/spring/bean/MyBean.java
  class MyBean (line 7) | public class MyBean {

FILE: spring-beans/spring-bean-beanDefinitionRegistry/src/main/java/com/xcs/spring/BeanDefinitionRegistryDemo.java
  class BeanDefinitionRegistryDemo (line 13) | public class BeanDefinitionRegistryDemo {
    method main (line 15) | public static void main(String[] args) {

FILE: spring-beans/spring-bean-beanDefinitionRegistry/src/main/java/com/xcs/spring/bean/MyBean.java
  class MyBean (line 7) | public class MyBean {

FILE: spring-beans/spring-bean-classPathBeanDefinitionScanner/src/main/java/com/xcs/spring/ClassPathBeanDefinitionScannerDemo.java
  class ClassPathBeanDefinitionScannerDemo (line 13) | public class ClassPathBeanDefinitionScannerDemo {
    method main (line 15) | public static void main(String[] args) {

FILE: spring-beans/spring-bean-classPathBeanDefinitionScanner/src/main/java/com/xcs/spring/controller/MyController.java
  class MyController (line 9) | @Controller

FILE: spring-beans/spring-bean-classPathBeanDefinitionScanner/src/main/java/com/xcs/spring/repository/MyRepository.java
  class MyRepository (line 9) | @Repository

FILE: spring-beans/spring-bean-classPathBeanDefinitionScanner/src/main/java/com/xcs/spring/service/MyService.java
  class MyService (line 9) | @Service

FILE: spring-beans/spring-bean-groovyBeanDefinitionReader/src/main/java/com/xcs/spring/GroovyBeanDefinitionReaderDemo.java
  class GroovyBeanDefinitionReaderDemo (line 13) | public class GroovyBeanDefinitionReaderDemo {
    method main (line 15) | public static void main(String[] args) {

FILE: spring-beans/spring-bean-groovyBeanDefinitionReader/src/main/java/com/xcs/spring/service/MyService.java
  type MyService (line 3) | public interface MyService {
    method showMessage (line 4) | void showMessage();

FILE: spring-beans/spring-bean-propertiesBeanDefinitionReader/src/main/java/com/xcs/spring/PropertiesBeanDefinitionReaderDemo.java
  class PropertiesBeanDefinitionReaderDemo (line 11) | public class PropertiesBeanDefinitionReaderDemo {
    method main (line 13) | public static void main(String[] args) {

FILE: spring-beans/spring-bean-propertiesBeanDefinitionReader/src/main/java/com/xcs/spring/bean/MyBean.java
  class MyBean (line 7) | public class MyBean {
    method getMessage (line 11) | public String getMessage() {
    method setMessage (line 15) | public void setMessage(String message) {
    method toString (line 19) | @Override

FILE: spring-beans/spring-bean-xmlBeanDefinitionReader/src/main/java/com/xcs/spring/XmlBeanDefinitionReaderDemo.java
  class XmlBeanDefinitionReaderDemo (line 12) | public class XmlBeanDefinitionReaderDemo {
    method main (line 14) | public static void main(String[] args) {

FILE: spring-beans/spring-bean-xmlBeanDefinitionReader/src/main/java/com/xcs/spring/bean/MyBean.java
  class MyBean (line 7) | public class MyBean {
    method getMessage (line 11) | public String getMessage() {
    method setMessage (line 15) | public void setMessage(String message) {
    method toString (line 19) | @Override

FILE: spring-context/spring-context-annotationConfigApplicationContext/src/main/java/com/xcs/spring/AnnotationConfigApplicationContextDemo.java
  class AnnotationConfigApplicationContextDemo (line 10) | public class AnnotationConfigApplicationContextDemo {
    method main (line 12) | public static void main(String[] args) {

FILE: spring-context/spring-context-annotationConfigApplicationContext/src/main/java/com/xcs/spring/bean/MyBean.java
  class MyBean (line 7) | public class MyBean {

FILE: spring-context/spring-context-annotationConfigApplicationContext/src/main/java/com/xcs/spring/controller/MyController.java
  class MyController (line 9) | @Controller

FILE: spring-context/spring-context-annotationConfigApplicationContext/src/main/java/com/xcs/spring/repository/MyRepository.java
  class MyRepository (line 9) | @Repository

FILE: spring-context/spring-context-annotationConfigApplicationContext/src/main/java/com/xcs/spring/service/MyService.java
  class MyService (line 9) | @Service

FILE: spring-context/spring-context-classPathXmlApplicationContext/src/main/java/com/xcs/spring/ClassPathXmlApplicationContextDemo.java
  class ClassPathXmlApplicationContextDemo (line 10) | public class ClassPathXmlApplicationContextDemo {
    method main (line 12) | public static void main(String[] args) {

FILE: spring-context/spring-context-classPathXmlApplicationContext/src/main/java/com/xcs/spring/bean/MyBean.java
  class MyBean (line 7) | public class MyBean {
    method getMessage (line 11) | public String getMessage() {
    method setMessage (line 15) | public void setMessage(String message) {

FILE: spring-core/spring-core-destroyBean/src/main/java/com/xcs/spring/DestroyBeanApplication.java
  class DestroyBeanApplication (line 10) | public class DestroyBeanApplication {
    method main (line 12) | public static void main(String[] args) {

FILE: spring-core/spring-core-destroyBean/src/main/java/com/xcs/spring/bean/MyBean.java
  class MyBean (line 9) | public class MyBean implements DisposableBean {
    method destroy (line 11) | @Override

FILE: spring-core/spring-core-getBean/src/main/java/com/xcs/spring/GetBeanApplication.java
  class GetBeanApplication (line 10) | public class GetBeanApplication {
    method main (line 12) | public static void main(String[] args) {

FILE: spring-core/spring-core-getBean/src/main/java/com/xcs/spring/config/MyConfiguration.java
  class MyConfiguration (line 10) | @Configuration

FILE: spring-core/spring-core-getBean/src/main/java/com/xcs/spring/service/MyServiceA.java
  class MyServiceA (line 9) | @Component
    method destroy (line 12) | public void destroy(){

FILE: spring-core/spring-core-getBean/src/main/java/com/xcs/spring/service/MyServiceB.java
  class MyServiceB (line 9) | @Component

FILE: spring-core/spring-core-registerBeanDefinition/src/main/java/com/xcs/spring/RegisterBeanDefinitionApplication.java
  class RegisterBeanDefinitionApplication (line 10) | public class RegisterBeanDefinitionApplication {
    method main (line 12) | public static void main(String[] args) {

FILE: spring-core/spring-core-registerBeanDefinition/src/main/java/com/xcs/spring/bean/MyBean.java
  class MyBean (line 7) | public class MyBean {

FILE: spring-core/spring-core-registerBeanDefinition/src/main/java/com/xcs/spring/controller/MyController.java
  class MyController (line 9) | @Controller

FILE: spring-core/spring-core-registerBeanDefinition/src/main/java/com/xcs/spring/repository/MyRepository.java
  class MyRepository (line 9) | @Repository

FILE: spring-core/spring-core-registerBeanDefinition/src/main/java/com/xcs/spring/service/MyService.java
  class MyService (line 9) | @Service

FILE: spring-core/spring-core-resolveDependency/src/main/java/com/xcs/spring/ResolveDependencyApplication.java
  class ResolveDependencyApplication (line 20) | public class ResolveDependencyApplication {
    method main (line 22) | public static void main(String[] args) {
    method methodResolveDependency (line 44) | public static void methodResolveDependency(ConfigurableListableBeanFac...
    method fieldResolveDependency (line 77) | public static void fieldResolveDependency(ConfigurableListableBeanFact...

FILE: spring-core/spring-core-resolveDependency/src/main/java/com/xcs/spring/config/MyConfiguration.java
  class MyConfiguration (line 11) | @Configuration

FILE: spring-core/spring-core-resolveDependency/src/main/java/com/xcs/spring/service/MyServiceA.java
  class MyServiceA (line 9) | @Service

FILE: spring-core/spring-core-resolveDependency/src/main/java/com/xcs/spring/service/MyServiceB.java
  class MyServiceB (line 9) | public class MyServiceB {
    method setMethodMyServiceA (line 27) | public void setMethodMyServiceA(MyServiceA methodMyServiceA){
    method toString (line 31) | @Override

FILE: spring-dataops/spring-dataops-conditionalConverter/src/main/java/com/xcs/spring/ConditionalConverterDemo.java
  class ConditionalConverterDemo (line 10) | public class ConditionalConverterDemo {
    method main (line 12) | public static void main(String[] args) {

FILE: spring-dataops/spring-dataops-conditionalConverter/src/main/java/com/xcs/spring/converter/StringToIntegerConditionalConverter.java
  class StringToIntegerConditionalConverter (line 12) | public class StringToIntegerConditionalConverter implements Converter<St...
    method matches (line 14) | @Override
    method convert (line 20) | @Override

FILE: spring-dataops/spring-dataops-conversionService/src/main/java/com/xcs/spring/ConversionServiceDemo.java
  class ConversionServiceDemo (line 12) | public class ConversionServiceDemo {
    method main (line 14) | public static void main(String[] args) {

FILE: spring-dataops/spring-dataops-converter/src/main/java/com/xcs/spring/ConverterDemo.java
  class ConverterDemo (line 13) | public class ConverterDemo {
    method main (line 15) | public static void main(String[] args) {

FILE: spring-dataops/spring-dataops-converter/src/main/java/com/xcs/spring/converter/StringToBooleanConverter.java
  class StringToBooleanConverter (line 13) | public class StringToBooleanConverter implements Converter<String, Boole...
    method convert (line 31) | @Override

FILE: spring-dataops/spring-dataops-converter/src/main/java/com/xcs/spring/converter/StringToLocalDateConverter.java
  class StringToLocalDateConverter (line 12) | public class StringToLocalDateConverter implements Converter<String, Loc...
    method convert (line 14) | @Override

FILE: spring-dataops/spring-dataops-converterFactory/src/main/java/com/xcs/spring/CharacterToNumberFactoryDemo.java
  class CharacterToNumberFactoryDemo (line 7) | public class CharacterToNumberFactoryDemo {
    method main (line 9) | public static void main(String[] args) {

FILE: spring-dataops/spring-dataops-converterFactory/src/main/java/com/xcs/spring/converter/StringToNumberConverterFactory.java
  class StringToNumberConverterFactory (line 8) | public class StringToNumberConverterFactory implements ConverterFactory<...
    method getConverter (line 10) | @Override
    class StringToNumber (line 15) | private static final class StringToNumber<T extends Number> implements...
      method StringToNumber (line 19) | public StringToNumber(Class<T> targetType) {
      method convert (line 23) | @Override

FILE: spring-dataops/spring-dataops-genericConverter/src/main/java/com/xcs/spring/GenericConverterDemo.java
  class GenericConverterDemo (line 11) | public class GenericConverterDemo {
    method main (line 13) | public static void main(String[] args) {

FILE: spring-dataops/spring-dataops-genericConverter/src/main/java/com/xcs/spring/bean/MyBean.java
  class MyBean (line 7) | public class MyBean {
    method getDate (line 15) | public Date getDate() {
    method setDate (line 19) | public void setDate(Date date) {
    method getDateTime (line 23) | public Date getDateTime() {
    method setDateTime (line 27) | public void setDateTime(Date dateTime) {
    method toString (line 31) | @Override

FILE: spring-dataops/spring-dataops-genericConverter/src/main/java/com/xcs/spring/convert/AnnotatedStringToDateConverter.java
  class AnnotatedStringToDateConverter (line 12) | public class AnnotatedStringToDateConverter implements GenericConverter {
    method getConvertibleTypes (line 14) | @Override
    method convert (line 20) | @Override

FILE: spring-dataops/spring-dataops-parser/src/main/java/com/xcs/spring/ParserDemo.java
  class ParserDemo (line 9) | public class ParserDemo {
    method main (line 11) | public static void main(String[] args) {

FILE: spring-dataops/spring-dataops-parser/src/main/java/com/xcs/spring/parser/CurrencyParser.java
  class CurrencyParser (line 9) | public class CurrencyParser implements Parser<Number> {
    method parse (line 10) | @Override

FILE: spring-dataops/spring-dataops-printer/src/main/java/com/xcs/spring/PrinterDemo.java
  class PrinterDemo (line 9) | public class PrinterDemo {
    method main (line 11) | public static void main(String[] args) {

FILE: spring-dataops/spring-dataops-printer/src/main/java/com/xcs/spring/printer/CurrencyPrinter.java
  class CurrencyPrinter (line 8) | public class CurrencyPrinter implements Printer<Number> {
    method print (line 10) | @Override

FILE: spring-dataops/spring-dataops-propertyEditor/src/main/java/com/xcs/spring/MyCustomDateEditor.java
  class MyCustomDateEditor (line 11) | public class MyCustomDateEditor extends PropertyEditorSupport {
    method setAsText (line 15) | @Override
    method getAsText (line 25) | @Override

FILE: spring-dataops/spring-dataops-propertyEditor/src/main/java/com/xcs/spring/PropertyEditorDemo.java
  class PropertyEditorDemo (line 11) | public class PropertyEditorDemo {
    method main (line 13) | public static void main(String[] args) {

FILE: spring-dataops/spring-dataops-propertyEditor/src/main/java/com/xcs/spring/bean/MyBean.java
  class MyBean (line 6) | public class MyBean {
    method getPath (line 12) | public Path getPath() {
    method setPath (line 16) | public void setPath(Path path) {
    method getDate (line 20) | public Date getDate() {
    method setDate (line 24) | public void setDate(Date date) {
    method toString (line 28) | @Override

FILE: spring-dataops/spring-dataops-validator/src/main/java/com/xcs/spring/Person.java
  class Person (line 7) | public class Person {
    method getName (line 13) | public String getName() {
    method setName (line 17) | public void setName(String name) {
    method getAge (line 21) | public int getAge() {
    method setAge (line 25) | public void setAge(int age) {

FILE: spring-dataops/spring-dataops-validator/src/main/java/com/xcs/spring/PersonValidator.java
  class PersonValidator (line 11) | public class PersonValidator implements Validator {
    method supports (line 13) | @Override
    method validate (line 18) | @Override

FILE: spring-dataops/spring-dataops-validator/src/main/java/com/xcs/spring/ValidatorDemo.java
  class ValidatorDemo (line 10) | public class ValidatorDemo {
    method main (line 12) | public static void main(String[] args) {

FILE: spring-env/spring-env-configurableEnvironment/src/main/java/com/xcs/spring/ConfigurableEnvironmentDemo.java
  class ConfigurableEnvironmentDemo (line 15) | public class ConfigurableEnvironmentDemo {
    method main (line 17) | public static void main(String[] args) {

FILE: spring-env/spring-env-configurablePropertyResolver/src/main/java/com/xcs/spring/ConfigurablePropertyResolverDemo.java
  class ConfigurablePropertyResolverDemo (line 16) | public class ConfigurablePropertyResolverDemo {
    method main (line 18) | public static void main(String[] args) {

FILE: spring-env/spring-env-environment/src/main/java/com/xcs/spring/EnvironmentDemo.java
  class EnvironmentDemo (line 10) | public class EnvironmentDemo {
    method main (line 12) | public static void main(String[] args) {

FILE: spring-env/spring-env-propertyResolver/src/main/java/com/xcs/spring/SimplePropertyResolverDemo.java
  class SimplePropertyResolverDemo (line 15) | public class SimplePropertyResolverDemo {
    method main (line 17) | public static void main(String[] args) {

FILE: spring-env/spring-env-propertySource/src/main/java/com/xcs/spring/PropertySourceDemo.java
  class PropertySourceDemo (line 16) | public class PropertySourceDemo {
    method main (line 18) | public static void main(String[] args) throws Exception {

FILE: spring-env/spring-env-propertySources/src/main/java/com/xcs/spring/PropertySourcesDemo.java
  class PropertySourcesDemo (line 14) | public class PropertySourcesDemo {
    method main (line 16) | public static void main(String[] args) {

FILE: spring-factory/spring-factory-autowireCapableBeanFactory/src/main/java/com/xcs/spring/AutowireCapableBeanFactoryDemo.java
  class AutowireCapableBeanFactoryDemo (line 19) | public class AutowireCapableBeanFactoryDemo {
    method main (line 21) | public static void main(String[] args) {
    method createBean (line 61) | private static void createBean(AutowireCapableBeanFactory beanFactory) {
    method configureBean (line 66) | private static void configureBean(AutowireCapableBeanFactory beanFacto...
    method autowireBean (line 76) | private static void autowireBean(AutowireCapableBeanFactory beanFactor...
    method autowire (line 83) | private static void autowire(AutowireCapableBeanFactory beanFactory) {
    method autowireBeanProperties (line 88) | private static void autowireBeanProperties(AutowireCapableBeanFactory ...
    method applyBeanPropertyValues (line 95) | private static void applyBeanPropertyValues(AutowireCapableBeanFactory...
    method initializeBean (line 111) | private static void initializeBean(AutowireCapableBeanFactory beanFact...
    method destroyBean (line 118) | private static void destroyBean(AutowireCapableBeanFactory beanFactory) {
    method resolveDependency (line 122) | private static void resolveDependency(AutowireCapableBeanFactory beanF...

FILE: spring-factory/spring-factory-autowireCapableBeanFactory/src/main/java/com/xcs/spring/config/MyBeanPostProcessor.java
  class MyBeanPostProcessor (line 10) | public class MyBeanPostProcessor implements BeanPostProcessor {
    method postProcessBeforeInitialization (line 12) | @Override
    method postProcessAfterInitialization (line 18) | @Override

FILE: spring-factory/spring-factory-autowireCapableBeanFactory/src/main/java/com/xcs/spring/config/MyConfiguration.java
  class MyConfiguration (line 9) | @Configuration

FILE: spring-factory/spring-factory-autowireCapableBeanFactory/src/main/java/com/xcs/spring/repository/MyRepository.java
  class MyRepository (line 7) | public class MyRepository {

FILE: spring-factory/spring-factory-autowireCapableBeanFactory/src/main/java/com/xcs/spring/service/MyService.java
  class MyService (line 14) | public class MyService implements BeanNameAware, InitializingBean, Dispo...
    method setBeanName (line 22) | @Override
    method afterPropertiesSet (line 27) | @Override
    method destroy (line 32) | @Override
    method setJavaHome (line 37) | public void setJavaHome(String javaHome) {
    method toString (line 41) | @Override

FILE: spring-factory/spring-factory-beanFactory/src/main/java/com/xcs/spring/BeanFactoryDemo.java
  class BeanFactoryDemo (line 13) | public class BeanFactoryDemo {
    method main (line 15) | public static void main(String[] args) {

FILE: spring-factory/spring-factory-beanFactory/src/main/java/com/xcs/spring/bean/MyBean.java
  class MyBean (line 7) | public class MyBean {
    method getMessage (line 11) | public String getMessage() {
    method setMessage (line 15) | public void setMessage(String message) {

FILE: spring-factory/spring-factory-configurableBeanFactory/src/main/java/com/xcs/spring/ConfigurableBeanFactoryDemo.java
  class ConfigurableBeanFactoryDemo (line 18) | public class ConfigurableBeanFactoryDemo {
    method main (line 20) | public static void main(String[] args) {

FILE: spring-factory/spring-factory-configurableBeanFactory/src/main/java/com/xcs/spring/config/MyConfiguration.java
  class MyConfiguration (line 12) | @Configuration
    method myService (line 14) | @Bean

FILE: spring-factory/spring-factory-configurableBeanFactory/src/main/java/com/xcs/spring/service/MyService.java
  type MyService (line 7) | public interface MyService {
    method greet (line 9) | void greet();

FILE: spring-factory/spring-factory-configurableBeanFactory/src/main/java/com/xcs/spring/service/impl/MyServiceImpl.java
  class MyServiceImpl (line 9) | public class MyServiceImpl implements MyService {
    method greet (line 10) | @Override

FILE: spring-factory/spring-factory-configurableListableBeanFactory/src/main/java/com/xcs/spring/ConfigurableListableBeanFactoryDemo.java
  class ConfigurableListableBeanFactoryDemo (line 19) | public class ConfigurableListableBeanFactoryDemo {
    method main (line 21) | public static void main(String[] args) throws NoSuchFieldException {

FILE: spring-factory/spring-factory-configurableListableBeanFactory/src/main/java/com/xcs/spring/config/MyConfiguration.java
  class MyConfiguration (line 12) | @Configuration
    method myService (line 14) | @Bean

FILE: spring-factory/spring-factory-configurableListableBeanFactory/src/main/java/com/xcs/spring/controller/MyController.java
  class MyController (line 10) | public class MyController {

FILE: spring-factory/spring-factory-configurableListableBeanFactory/src/main/java/com/xcs/spring/service/MyService.java
  type MyService (line 7) | public interface MyService {
    method greet (line 9) | void greet();

FILE: spring-factory/spring-factory-configurableListableBeanFactory/src/main/java/com/xcs/spring/service/impl/MyServiceImpl.java
  class MyServiceImpl (line 9) | public class MyServiceImpl implements MyService {
    method greet (line 10) | @Override

FILE: spring-factory/spring-factory-hierarchicalBeanFactory/src/main/java/com/xcs/spring/HierarchicalBeanFactoryDemo.java
  class HierarchicalBeanFactoryDemo (line 12) | public class HierarchicalBeanFactoryDemo {
    method main (line 14) | public static void main(String[] args) {

FILE: spring-factory/spring-factory-hierarchicalBeanFactory/src/main/java/com/xcs/spring/bean/MyBean.java
  class MyBean (line 7) | public class MyBean {

FILE: spring-factory/spring-factory-listableBeanFactory/src/main/java/com/xcs/spring/ListableBeanFactoryDemo.java
  class ListableBeanFactoryDemo (line 17) | public class ListableBeanFactoryDemo {
    method main (line 19) | public static void main(String[] args) {

FILE: spring-factory/spring-factory-listableBeanFactory/src/main/java/com/xcs/spring/config/MyConfiguration.java
  class MyConfiguration (line 6) | @Configuration

FILE: spring-factory/spring-factory-listableBeanFactory/src/main/java/com/xcs/spring/service/MyService.java
  class MyService (line 9) | @Service

FILE: spring-interface/spring-interface-beanDefinitionRegistryPostProcessor/src/main/java/com/xcs/spring/BeanDefinitionRegistryPostProcessorApplication.java
  class BeanDefinitionRegistryPostProcessorApplication (line 11) | public class BeanDefinitionRegistryPostProcessorApplication {
    method main (line 13) | public static void main(String[] args) {

FILE: spring-interface/spring-interface-beanDefinitionRegistryPostProcessor/src/main/java/com/xcs/spring/config/MyBeanDefinitionRegistryPostProcessor.java
  class MyBeanDefinitionRegistryPostProcessor (line 14) | public class MyBeanDefinitionRegistryPostProcessor implements BeanDefini...
    method postProcessBeanFactory (line 16) | @Override
    method postProcessBeanDefinitionRegistry (line 21) | @Override

FILE: spring-interface/spring-interface-beanDefinitionRegistryPostProcessor/src/main/java/com/xcs/spring/config/MyConfiguration.java
  class MyConfiguration (line 10) | @Configuration
    method myBeanDefinitionRegistryPostProcessor (line 13) | @Bean

FILE: spring-interface/spring-interface-beanDefinitionRegistryPostProcessor/src/main/java/com/xcs/spring/config/MySimpleBean.java
  class MySimpleBean (line 7) | public class MySimpleBean {
    method show (line 9) | public void show() {

FILE: spring-interface/spring-interface-beanFactoryPostProcessor/src/main/java/com/xcs/spring/BeanFactoryPostProcessorApplication.java
  class BeanFactoryPostProcessorApplication (line 11) | public class BeanFactoryPostProcessorApplication {
    method main (line 13) | public static void main(String[] args) {

FILE: spring-interface/spring-interface-beanFactoryPostProcessor/src/main/java/com/xcs/spring/config/MyBeanFactoryPostProcessor.java
  class MyBeanFactoryPostProcessor (line 12) | public class MyBeanFactoryPostProcessor implements BeanFactoryPostProces...
    method postProcessBeanFactory (line 14) | @Override

FILE: spring-interface/spring-interface-beanFactoryPostProcessor/src/main/java/com/xcs/spring/config/MyConfiguration.java
  class MyConfiguration (line 10) | @Configuration
    method mySimpleBean (line 13) | @Bean
    method myBeanFactoryPostProcessor (line 18) | @Bean

FILE: spring-interface/spring-interface-beanFactoryPostProcessor/src/main/java/com/xcs/spring/config/MySimpleBean.java
  class MySimpleBean (line 7) | public class MySimpleBean {
    method show (line 9) | public void show() {

FILE: spring-interface/spring-interface-beanPostProcessor/src/main/java/com/xcs/spring/BeanPostProcessorApplication.java
  class BeanPostProcessorApplication (line 11) | public class BeanPostProcessorApplication {
    method main (line 13) | public static void main(String[] args) {

FILE: spring-interface/spring-interface-beanPostProcessor/src/main/java/com/xcs/spring/config/MyBeanPostProcessor.java
  class MyBeanPostProcessor (line 11) | public class MyBeanPostProcessor implements BeanPostProcessor {
    method postProcessBeforeInitialization (line 13) | @Override
    method postProcessAfterInitialization (line 22) | @Override

FILE: spring-interface/spring-interface-beanPostProcessor/src/main/java/com/xcs/spring/config/MyConfiguration.java
  class MyConfiguration (line 13) | @Configuration
    method myService (line 16) | @Bean
    method myBeanPostProcessor (line 21) | @Bean

FILE: spring-interface/spring-interface-beanPostProcessor/src/main/java/com/xcs/spring/service/MyService.java
  type MyService (line 7) | public interface MyService {
    method show (line 8) | String show();

FILE: spring-interface/spring-interface-beanPostProcessor/src/main/java/com/xcs/spring/service/MyServiceImpl.java
  class MyServiceImpl (line 7) | public class MyServiceImpl implements MyService{
    method show (line 11) | @Override
    method setMessage (line 16) | public void setMessage(String message) {
    method getMessage (line 20) | public String getMessage() {

FILE: spring-interface/spring-interface-destructionAwareBeanPostProcessor/src/main/java/com/xcs/spring/DestructionAwareBeanPostProcessorApplication.java
  class DestructionAwareBeanPostProcessorApplication (line 11) | public class DestructionAwareBeanPostProcessorApplication {
    method main (line 13) | public static void main(String[] args) {

FILE: spring-interface/spring-interface-destructionAwareBeanPostProcessor/src/main/java/com/xcs/spring/config/MyConfiguration.java
  class MyConfiguration (line 12) | @Configuration
    method myDestructionAwareBeanPostProcessor (line 15) | @Bean
    method connectionService (line 20) | @Bean

FILE: spring-interface/spring-interface-destructionAwareBeanPostProcessor/src/main/java/com/xcs/spring/config/MyDestructionAwareBeanPostProcessor.java
  class MyDestructionAwareBeanPostProcessor (line 11) | public class MyDestructionAwareBeanPostProcessor implements DestructionA...
    method postProcessAfterInitialization (line 13) | @Override
    method postProcessBeforeDestruction (line 21) | @Override
    method requiresDestruction (line 28) | @Override

FILE: spring-interface/spring-interface-destructionAwareBeanPostProcessor/src/main/java/com/xcs/spring/service/ConnectionService.java
  type ConnectionService (line 7) | public interface ConnectionService {
    method openConnection (line 9) | void openConnection();
    method closeConnection (line 11) | void closeConnection();
    method isConnected (line 13) | boolean isConnected();

FILE: spring-interface/spring-interface-destructionAwareBeanPostProcessor/src/main/java/com/xcs/spring/service/ConnectionServiceImpl.java
  class ConnectionServiceImpl (line 7) | public class ConnectionServiceImpl implements ConnectionService {
    method openConnection (line 11) | @Override
    method closeConnection (line 17) | @Override
    method isConnected (line 25) | @Override

FILE: spring-interface/spring-interface-disposableBean/src/main/java/com/xcs/spring/DisposableBeanApplication.java
  class DisposableBeanApplication (line 10) | public class DisposableBeanApplication {
    method main (line 12) | public static void main(String[] args) {

FILE: spring-interface/spring-interface-disposableBean/src/main/java/com/xcs/spring/config/MyConfiguration.java
  class MyConfiguration (line 10) | @Configuration
    method myDisposableBean (line 13) | @Bean

FILE: spring-interface/spring-interface-disposableBean/src/main/java/com/xcs/spring/config/MyDisposableBean.java
  class MyDisposableBean (line 9) | public class MyDisposableBean implements DisposableBean {
    method MyDisposableBean (line 14) | public MyDisposableBean() {
    method destroy (line 20) | @Override

FILE: spring-interface/spring-interface-initializingBean/src/main/java/com/xcs/spring/InitializingBeanApplication.java
  class InitializingBeanApplication (line 10) | public class InitializingBeanApplication {
    method main (line 12) | public static void main(String[] args) {

FILE: spring-interface/spring-interface-initializingBean/src/main/java/com/xcs/spring/config/MyConfiguration.java
  class MyConfiguration (line 10) | @Configuration
    method myInitializingBean (line 13) | @Bean

FILE: spring-interface/spring-interface-initializingBean/src/main/java/com/xcs/spring/config/MyInitializingBean.java
  class MyInitializingBean (line 12) | public class MyInitializingBean implements InitializingBean {
    method getData (line 16) | public List<String> getData() {
    method afterPropertiesSet (line 20) | @Override

FILE: spring-interface/spring-interface-instantiationAwareBeanPostProcessor/src/main/java/com/xcs/spring/InstantiationAwareBeanPostProcessorApplication.java
  class InstantiationAwareBeanPostProcessorApplication (line 11) | public class InstantiationAwareBeanPostProcessorApplication {
    method main (line 13) | public static void main(String[] args) {

FILE: spring-interface/spring-interface-instantiationAwareBeanPostProcessor/src/main/java/com/xcs/spring/config/MyConfiguration.java
  class MyConfiguration (line 13) | @Configuration
    method myInstantiationAwareBeanPostProcessor (line 16) | @Bean
    method dataBase (line 21) | @Bean
    method afterPropertiesSet (line 26) | @Override

FILE: spring-interface/spring-interface-instantiationAwareBeanPostProcessor/src/main/java/com/xcs/spring/config/MyInstantiationAwareBeanPostProcessor.java
  class MyInstantiationAwareBeanPostProcessor (line 13) | public class MyInstantiationAwareBeanPostProcessor implements Instantiat...
    method postProcessBeforeInstantiation (line 15) | @Override
    method postProcessAfterInstantiation (line 23) | @Override
    method postProcessProperties (line 33) | @Override

FILE: spring-interface/spring-interface-instantiationAwareBeanPostProcessor/src/main/java/com/xcs/spring/service/DataBase.java
  type DataBase (line 7) | public interface DataBase {
    method getUsername (line 8) | String getUsername();
    method setUsername (line 9) | void setUsername(String username);
    method getPassword (line 10) | String getPassword();
    method setPassword (line 11) | void setPassword(String password);
    method isPostInstantiationFlag (line 12) | boolean isPostInstantiationFlag();
    method setPostInstantiationFlag (line 13) | void setPostInstantiationFlag(boolean flag);

FILE: spring-interface/spring-interface-instantiationAwareBeanPostProcessor/src/main/java/com/xcs/spring/service/DataBaseImpl.java
  class DataBaseImpl (line 10) | public class DataBaseImpl implements DataBase , InitializingBean {
    method getUsername (line 20) | @Override
    method setUsername (line 25) | @Override
    method getPassword (line 30) | @Override
    method setPassword (line 35) | @Override
    method isPostInstantiationFlag (line 40) | @Override
    method setPostInstantiationFlag (line 45) | @Override
    method afterPropertiesSet (line 50) | @Override

FILE: spring-interface/spring-interface-mergedBeanDefinitionPostProcessor/src/main/java/com/xcs/spring/MergedBeanDefinitionPostProcessorApplication.java
  class MergedBeanDefinitionPostProcessorApplication (line 11) | public class MergedBeanDefinitionPostProcessorApplication {
    method main (line 13) | public static void main(String[] args) {

FILE: spring-interface/spring-interface-mergedBeanDefinitionPostProcessor/src/main/java/com/xcs/spring/bean/MyBean.java
  class MyBean (line 9) | public class MyBean {
    method getMessage (line 14) | public String getMessage() {

FILE: spring-interface/spring-interface-mergedBeanDefinitionPostProcessor/src/main/java/com/xcs/spring/config/MyConfiguration.java
  class MyConfiguration (line 12) | @Configuration
    method myBeanPostProcessor (line 15) | @Bean
    method myBean (line 20) | @Bean

FILE: spring-interface/spring-interface-mergedBeanDefinitionPostProcessor/src/main/java/com/xcs/spring/config/MyMergedBeanDefinitionPostProcessor.java
  class MyMergedBeanDefinitionPostProcessor (line 16) | public class MyMergedBeanDefinitionPostProcessor implements MergedBeanDe...
    method postProcessMergedBeanDefinition (line 23) | @Override
    method postProcessAfterInitialization (line 38) | @Override

FILE: spring-interface/spring-interface-smartInitializingSingleton/src/main/java/com/xcs/spring/SmartInitializingSingletonApplication.java
  class SmartInitializingSingletonApplication (line 10) | public class SmartInitializingSingletonApplication {
    method main (line 12) | public static void main(String[] args) {

FILE: spring-interface/spring-interface-smartInitializingSingleton/src/main/java/com/xcs/spring/config/MyConfiguration.java
  class MyConfiguration (line 11) | @Configuration
    method mySmartInitializingSingleton (line 15) | @Bean

FILE: spring-interface/spring-interface-smartInitializingSingleton/src/main/java/com/xcs/spring/config/MySmartInitializingSingleton.java
  class MySmartInitializingSingleton (line 11) | public class MySmartInitializingSingleton implements SmartInitializingSi...
    method afterSingletonsInstantiated (line 16) | @Override

FILE: spring-interface/spring-interface-smartInitializingSingleton/src/main/java/com/xcs/spring/service/MyService.java
  class MyService (line 12) | @Service
    method startScheduledTask (line 18) | public void startScheduledTask() {
    method getDate (line 36) | public String getDate() {

FILE: spring-interface/spring-interface-smartInstantiationAwareBeanPostProcessor/src/main/java/com/xcs/spring/SmartInstantiationAwareBeanPostProcessorApplication.java
  class SmartInstantiationAwareBeanPostProcessorApplication (line 10) | public class SmartInstantiationAwareBeanPostProcessorApplication {
    method main (line 12) | public static void main(String[] args) {

FILE: spring-interface/spring-interface-smartInstantiationAwareBeanPostProcessor/src/main/java/com/xcs/spring/config/MyConfiguration.java
  class MyConfiguration (line 11) | @Configuration
    method mySmartInstantiationAwareBeanPostProcessor (line 15) | @Bean

FILE: spring-interface/spring-interface-smartInstantiationAwareBeanPostProcessor/src/main/java/com/xcs/spring/config/MySmartInstantiationAwareBeanPostProcessor.java
  class MySmartInstantiationAwareBeanPostProcessor (line 16) | public class MySmartInstantiationAwareBeanPostProcessor implements Smart...
    method determineCandidateConstructors (line 18) | @Override

FILE: spring-interface/spring-interface-smartInstantiationAwareBeanPostProcessor/src/main/java/com/xcs/spring/service/MyService.java
  class MyService (line 10) | @Component
    method MyService (line 16) | public MyService() {
    method MyService (line 22) | public MyService(MyServiceA myServiceA) {
    method MyService (line 28) | public MyService(MyServiceB serviceB) {
    method MyService (line 34) | @MyAutowired

FILE: spring-interface/spring-interface-smartInstantiationAwareBeanPostProcessor/src/main/java/com/xcs/spring/service/MyServiceA.java
  class MyServiceA (line 9) | @Component
    method execute (line 12) | public void execute() {

FILE: spring-interface/spring-interface-smartInstantiationAwareBeanPostProcessor/src/main/java/com/xcs/spring/service/MyServiceB.java
  class MyServiceB (line 9) | @Component
    method execute (line 12) | public void execute() {

FILE: spring-jsr/spring-jsr250-postConstruct/src/main/java/com/xcs/spring/PostConstructApplication.java
  class PostConstructApplication (line 10) | public class PostConstructApplication {
    method main (line 12) | public static void main(String[] args) {

FILE: spring-jsr/spring-jsr250-postConstruct/src/main/java/com/xcs/spring/config/MyConfiguration.java
  class MyConfiguration (line 10) | @Configuration

FILE: spring-jsr/spring-jsr250-postConstruct/src/main/java/com/xcs/spring/service/MyService.java
  class MyService (line 7) | @Service
    method MyService (line 10) | public MyService(){
    method postConstruct (line 14) | @PostConstruct

FILE: spring-jsr/spring-jsr250-preDestroy/src/main/java/com/xcs/spring/PreDestroyApplication.java
  class PreDestroyApplication (line 10) | public class PreDestroyApplication {
    method main (line 12) | public static void main(String[] args) {

FILE: spring-jsr/spring-jsr250-preDestroy/src/main/java/com/xcs/spring/config/MyConfiguration.java
  class MyConfiguration (line 10) | @Configuration

FILE: spring-jsr/spring-jsr250-preDestroy/src/main/java/com/xcs/spring/service/MyService.java
  class MyService (line 7) | @Service
    method MyService (line 10) | public MyService(){
    method preDestroy (line 14) | @PreDestroy

FILE: spring-jsr/spring-jsr250-resource/src/main/java/com/xcs/spring/ResourceApplication.java
  class ResourceApplication (line 11) | public class ResourceApplication {
    method main (line 13) | public static void main(String[] args) {

FILE: spring-jsr/spring-jsr250-resource/src/main/java/com/xcs/spring/config/MyConfiguration.java
  class MyConfiguration (line 6) | @Configuration

FILE: spring-jsr/spring-jsr250-resource/src/main/java/com/xcs/spring/controller/MyController.java
  class MyController (line 9) | @Controller
    method showService (line 15) | public void showService(){

FILE: spring-jsr/spring-jsr250-resource/src/main/java/com/xcs/spring/service/MyService.java
  class MyService (line 5) | @Service

FILE: spring-jsr/spring-jsr330-inject/src/main/java/com/xcs/spring/InjectApplication.java
  class InjectApplication (line 11) | public class InjectApplication {
    method main (line 13) | public static void main(String[] args) {

FILE: spring-jsr/spring-jsr330-inject/src/main/java/com/xcs/spring/config/MyConfiguration.java
  class MyConfiguration (line 6) | @Configuration

FILE: spring-jsr/spring-jsr330-inject/src/main/java/com/xcs/spring/controller/MyController.java
  class MyController (line 9) | @Controller
    method showService (line 15) | public void showService(){

FILE: spring-jsr/spring-jsr330-inject/src/main/java/com/xcs/spring/service/MyService.java
  class MyService (line 5) | @Service

FILE: spring-jsr/spring-jsr330-named/src/main/java/com/xcs/spring/NamedApplication.java
  class NamedApplication (line 11) | public class NamedApplication {
    method main (line 13) | public static void main(String[] args) {

FILE: spring-jsr/spring-jsr330-named/src/main/java/com/xcs/spring/config/MyConfiguration.java
  class MyConfiguration (line 6) | @Configuration

FILE: spring-jsr/spring-jsr330-named/src/main/java/com/xcs/spring/controller/MyController.java
  class MyController (line 10) | @Controller
    method showService (line 17) | public void showService(){

FILE: spring-jsr/spring-jsr330-named/src/main/java/com/xcs/spring/service/MyService.java
  class MyService (line 7) | public class MyService {

FILE: spring-jsr/spring-jsr330-named/src/main/java/com/xcs/spring/service/MyServiceA.java
  class MyServiceA (line 9) | @Named("myServiceA")

FILE: spring-jsr/spring-jsr330-named/src/main/java/com/xcs/spring/service/MyServiceB.java
  class MyServiceB (line 9) | @Named("myServiceB")

FILE: spring-jsr/spring-jsr330-provider/src/main/java/com/xcs/spring/ProviderApplication.java
  class ProviderApplication (line 11) | public class ProviderApplication {
    method main (line 13) | public static void main(String[] args) {

FILE: spring-jsr/spring-jsr330-provider/src/main/java/com/xcs/spring/config/MyConfiguration.java
  class MyConfiguration (line 6) | @Configuration

FILE: spring-jsr/spring-jsr330-provider/src/main/java/com/xcs/spring/controller/MyController.java
  class MyController (line 11) | @Controller
    method showService (line 17) | public void showService(){

FILE: spring-jsr/spring-jsr330-provider/src/main/java/com/xcs/spring/service/MyService.java
  class MyService (line 10) | @Service

FILE: spring-jsr/spring-jsr330-qualifier/src/main/java/com/xcs/spring/QualifierApplication.java
  class QualifierApplication (line 11) | public class QualifierApplication {
    method main (line 13) | public static void main(String[] args) {

FILE: spring-jsr/spring-jsr330-qualifier/src/main/java/com/xcs/spring/config/MyConfiguration.java
  class MyConfiguration (line 10) | @Configuration

FILE: spring-jsr/spring-jsr330-qualifier/src/main/java/com/xcs/spring/controller/MessageController.java
  class MessageController (line 14) | @Controller
    method showMessage (line 25) | public void showMessage() {

FILE: spring-jsr/spring-jsr330-qualifier/src/main/java/com/xcs/spring/service/MessageService.java
  type MessageService (line 7) | public interface MessageService {
    method getMessage (line 8) | String getMessage();

FILE: spring-jsr/spring-jsr330-qualifier/src/main/java/com/xcs/spring/service/impl/EmailServiceImpl.java
  class EmailServiceImpl (line 12) | @Email
    method getMessage (line 15) | @Override

FILE: spring-jsr/spring-jsr330-qualifier/src/main/java/com/xcs/spring/service/impl/SMSServiceImpl.java
  class SMSServiceImpl (line 12) | @SMS
    method getMessage (line 15) | @Override

FILE: spring-metadata/spring-metadata-annotationMetadata/src/main/java/com/xcs/spring/AnnotationMetadataDemoByASM.java
  class AnnotationMetadataDemoByASM (line 16) | public class AnnotationMetadataDemoByASM {
    method main (line 18) | public static void main(String[] args) throws Exception {

FILE: spring-metadata/spring-metadata-annotationMetadata/src/main/java/com/xcs/spring/AnnotationMetadataDemoByReflection.java
  class AnnotationMetadataDemoByReflection (line 13) | public class AnnotationMetadataDemoByReflection {
    method main (line 15) | public static void main(String[] args) throws Exception {

FILE: spring-metadata/spring-metadata-annotationMetadata/src/main/java/com/xcs/spring/bean/MyBean.java
  class MyBean (line 9) | @Component("myBean")

FILE: spring-metadata/spring-metadata-condition/src/main/java/com/xcs/spring/ConditionDemo.java
  class ConditionDemo (line 12) | public class ConditionDemo {
    method main (line 14) | public static void main(String[] args) throws IOException {

FILE: spring-metadata/spring-metadata-condition/src/main/java/com/xcs/spring/bean/MyBeanA.java
  class MyBeanA (line 7) | public class MyBeanA {

FILE: spring-metadata/spring-metadata-condition/src/main/java/com/xcs/spring/bean/MyBeanB.java
  class MyBeanB (line 7) | public class MyBeanB {

FILE: spring-metadata/spring-metadata-condition/src/main/java/com/xcs/spring/condition/MyOnClassCondition.java
  class MyOnClassCondition (line 11) | public class MyOnClassCondition implements Condition {
    method MyOnClassCondition (line 15) | public MyOnClassCondition(String className) {
    method matches (line 19) | @Override

FILE: spring-metadata/spring-metadata-metadataReader/src/main/java/com/xcs/spring/MetadataReaderDemo.java
  class MetadataReaderDemo (line 22) | public class MetadataReaderDemo {
    method main (line 23) | public static void main(String[] args) throws IOException {

FILE: spring-metadata/spring-metadata-metadataReader/src/main/java/com/xcs/spring/bean/MyAbstract.java
  class MyAbstract (line 7) | public abstract class MyAbstract {

FILE: spring-metadata/spring-metadata-metadataReader/src/main/java/com/xcs/spring/bean/MyBean.java
  class MyBean (line 12) | @MyClassAnnotation
    method myMethod1 (line 19) | @MyAnnotation
    method myMethod2 (line 24) | @MyAnnotation
    method myMethod3 (line 29) | public void myMethod3() {
    class MyInnerClass (line 33) | public static class MyInnerClass {

FILE: spring-metadata/spring-metadata-typeFilter/src/main/java/com/xcs/spring/TypeFilterDemo.java
  class TypeFilterDemo (line 18) | public class TypeFilterDemo {
    method main (line 20) | public static void main(String[] args) throws IOException {

FILE: spring-metadata/spring-metadata-typeFilter/src/main/java/com/xcs/spring/component/MyComponent.java
  class MyComponent (line 9) | @MyAnnotation

FILE: spring-metadata/spring-metadata-typeFilter/src/main/java/com/xcs/spring/controller/MyController.java
  class MyController (line 7) | public class MyController {

FILE: spring-metadata/spring-metadata-typeFilter/src/main/java/com/xcs/spring/repository/MyRepository.java
  class MyRepository (line 7) | public class MyRepository {

FILE: spring-metadata/spring-metadata-typeFilter/src/main/java/com/xcs/spring/service/MyService.java
  class MyService (line 7) | public class MyService {

FILE: spring-resources/spring-resource-documentLoader/src/main/java/com/xcs/spring/DocumentLoaderDemo.java
  class DocumentLoaderDemo (line 13) | public class DocumentLoaderDemo {
    method main (line 15) | public static void main(String[] args) {
    method printDetailedDocumentInfo (line 38) | private static void printDetailedDocumentInfo(Document document) {
    method printElementInfo (line 49) | private static void printElementInfo(Element element, String indent) {

FILE: spring-resources/spring-resource-documentLoader/src/main/java/com/xcs/spring/bean/MyBean.java
  class MyBean (line 7) | public class MyBean {
    method getMessage (line 11) | public String getMessage() {
    method setMessage (line 15) | public void setMessage(String message) {

FILE: spring-resources/spring-resource-resourceLoader/src/main/java/com/xcs/spring/DefaultResourceLoaderDemo.java
  class DefaultResourceLoaderDemo (line 10) | public class DefaultResourceLoaderDemo {
    method main (line 11) | public static void main(String[] args) {

FILE: spring-resources/spring-resource-resourceLoader/src/main/java/com/xcs/spring/PathMatchingResourcePatternResolverDemo.java
  class PathMatchingResourcePatternResolverDemo (line 10) | public class PathMatchingResourcePatternResolverDemo {
    method main (line 11) | public static void main(String[] args) throws Exception {

FILE: spring-resources/spring-resource-resourcePatternResolver/src/main/java/com/xcs/spring/ResourcePatternResolverDemo.java
  class ResourcePatternResolverDemo (line 11) | public class ResourcePatternResolverDemo {
    method main (line 12) | public static void main(String[] args) throws Exception {

FILE: spring-resources/spring-resource/src/main/java/com/xcs/spring/ByteArrayResourceDemo.java
  class ByteArrayResourceDemo (line 12) | public class ByteArrayResourceDemo {
    method main (line 13) | public static void main(String[] args) throws Exception {

FILE: spring-resources/spring-resource/src/main/java/com/xcs/spring/ClassPathResourceDemo.java
  class ClassPathResourceDemo (line 12) | public class ClassPathResourceDemo {
    method main (line 13) | public static void main(String[] args) throws Exception {

FILE: spring-resources/spring-resource/src/main/java/com/xcs/spring/FileSystemResourceDemo.java
  class FileSystemResourceDemo (line 12) | public class FileSystemResourceDemo {
    method main (line 13) | public static void main(String[] args) throws Exception {

FILE: spring-resources/spring-resource/src/main/java/com/xcs/spring/InputStreamResourceDemo.java
  class InputStreamResourceDemo (line 13) | public class InputStreamResourceDemo {
    method main (line 14) | public static void main(String[] args) throws Exception {

FILE: spring-resources/spring-resource/src/main/java/com/xcs/spring/UrlResourceDemo.java
  class UrlResourceDemo (line 12) | public class UrlResourceDemo {
    method main (line 13) | public static void main(String[] args) throws Exception {

FILE: spring-spel/spring-spel-beanResolver/src/main/java/com/xcs/spring/BeanResolverDemo.java
  class BeanResolverDemo (line 10) | public class BeanResolverDemo {
    method main (line 11) | public static void main(String[] args) {

FILE: spring-spel/spring-spel-beanResolver/src/main/java/com/xcs/spring/MyBean.java
  class MyBean (line 3) | public class MyBean {

FILE: spring-spel/spring-spel-constructorResolver/src/main/java/com/xcs/spring/ConstructorResolverDemo.java
  class ConstructorResolverDemo (line 10) | public class ConstructorResolverDemo {
    method main (line 11) | public static void main(String[] args) {

FILE: spring-spel/spring-spel-constructorResolver/src/main/java/com/xcs/spring/MyBean.java
  class MyBean (line 3) | public class MyBean {
    method MyBean (line 7) | public MyBean(String name) {
    method getName (line 11) | public String getName() {
    method setName (line 15) | public void setName(String name) {
    method toString (line 19) | @Override

FILE: spring-spel/spring-spel-evaluationContext/src/main/java/com/xcs/spring/EvaluationContextDemo.java
  class EvaluationContextDemo (line 12) | public class EvaluationContextDemo {
    method main (line 13) | public static void main(String[] args) {
    class MyRootObject (line 59) | static class MyRootObject {
      method MyRootObject (line 62) | public MyRootObject(String data) {
      method getData (line 66) | public String getData() {
      method setData (line 70) | public void setData(String data) {

FILE: spring-spel/spring-spel-expression/src/main/java/com/xcs/spring/ExpressionDemo.java
  class ExpressionDemo (line 7) | public class ExpressionDemo {
    method main (line 8) | public static void main(String[] args) {

FILE: spring-spel/spring-spel-expressionParser/src/main/java/com/xcs/spring/ExpressionParserDemo.java
  class ExpressionParserDemo (line 13) | public class ExpressionParserDemo {
    method main (line 15) | public static void main(String[] args) {

FILE: spring-spel/spring-spel-methodResolver/src/main/java/com/xcs/spring/MethodResolverDemo.java
  class MethodResolverDemo (line 12) | public class MethodResolverDemo {
    method main (line 14) | public static void main(String[] args) {

FILE: spring-spel/spring-spel-methodResolver/src/main/java/com/xcs/spring/MyBean.java
  class MyBean (line 3) | public class MyBean {
    method add (line 4) | public int add(int a, int b) {

FILE: spring-spel/spring-spel-operatorOverloader/src/main/java/CustomOperatorOverloader.java
  class CustomOperatorOverloader (line 5) | public class CustomOperatorOverloader implements OperatorOverloader {
    method overridesOperation (line 6) | @Override
    method operate (line 11) | @Override

FILE: spring-spel/spring-spel-operatorOverloader/src/main/java/MyBean.java
  class MyBean (line 1) | public class MyBean {
    method MyBean (line 5) | public MyBean(int age) {
    method getAge (line 9) | public int getAge() {
    method setAge (line 13) | public void setAge(int age) {
    method toString (line 17) | @Override

FILE: spring-spel/spring-spel-operatorOverloader/src/main/java/OperatorOverloaderDemo.java
  class OperatorOverloaderDemo (line 6) | public class OperatorOverloaderDemo {
    method main (line 8) | public static void main(String[] args) {

FILE: spring-spel/spring-spel-propertyAccessor/src/main/java/com/xcs/spring/MyBean.java
  class MyBean (line 3) | public class MyBean {
    method MyBean (line 5) | public MyBean(String name) {
    method getName (line 12) | public String getName() {
    method setName (line 16) | public void setName(String name) {

FILE: spring-spel/spring-spel-propertyAccessor/src/main/java/com/xcs/spring/PropertyAccessorDemo.java
  class PropertyAccessorDemo (line 14) | public class PropertyAccessorDemo {
    method main (line 15) | public static void main(String[] args)  {

FILE: spring-spel/spring-spel-typeComparator/src/main/java/com/xcs/spring/TypeComparatorDemo.java
  class TypeComparatorDemo (line 7) | public class TypeComparatorDemo {
    method main (line 8) | public static void main(String[] args) {

FILE: spring-spel/spring-spel-typeConverter/src/main/java/com/xcs/spring/TypeConverterDemo.java
  class TypeConverterDemo (line 7) | public class TypeConverterDemo {
    method main (line 9) | public static void main(String[] args) {

FILE: spring-spel/spring-spel-typeLocator/src/main/java/com/xcs/spring/TypeLocatorDemo.java
  class TypeLocatorDemo (line 6) | public class TypeLocatorDemo {
    method main (line 7) | public static void main(String[] args) {

FILE: spring-transaction/spring-transaction-connection/src/main/java/com/xcs/spring/ConnectionDemo.java
  class ConnectionDemo (line 10) | public class ConnectionDemo {
    method main (line 12) | public static void main(String[] args) {

FILE: spring-transaction/spring-transaction-dataSource/src/main/java/com/xcs/spring/DataSourceDemo.java
  class DataSourceDemo (line 9) | public class DataSourceDemo {
    method main (line 11) | public static void main(String[] args) throws Exception {

FILE: spring-transaction/spring-transaction-driverManager/src/main/java/com/xcs/spring/DriverManagerDemo.java
  class DriverManagerDemo (line 8) | public class DriverManagerDemo {
    method main (line 10) | public static void main(String[] args) throws Exception {

FILE: spring-transaction/spring-transaction-enableTransactionManagement/src/main/java/com/xcs/spring/AppConfig.java
  class AppConfig (line 16) | @Configuration
    method transactionManager (line 21) | @Bean
    method jdbcTemplate (line 26) | @Bean
    method dataSource (line 31) | @Bean

FILE: spring-transaction/spring-transaction-enableTransactionManagement/src/main/java/com/xcs/spring/EnableTransactionManagementDemo.java
  class EnableTransactionManagementDemo (line 5) | public class EnableTransactionManagementDemo {
    method main (line 7) | public static void main(String[] args) {

FILE: spring-transaction/spring-transaction-enableTransactionManagement/src/main/java/com/xcs/spring/ScoresService.java
  type ScoresService (line 3) | public interface ScoresService {
    method insertScore (line 4) | void insertScore();

FILE: spring-transaction/spring-transaction-enableTransactionManagement/src/main/java/com/xcs/spring/ScoresServiceImpl.java
  class ScoresServiceImpl (line 10) | @Service
    method insertScore (line 16) | @Override

FILE: spring-transaction/spring-transaction-jdbcTemplate/src/main/java/com/xcs/spring/JdbcTemplateDemo.java
  class JdbcTemplateDemo (line 9) | public class JdbcTemplateDemo {
    method main (line 11) | public static void main(String[] args) throws Exception {

FILE: spring-transaction/spring-transaction-jdbcTemplate/src/main/java/com/xcs/spring/Scores.java
  class Scores (line 3) | public class Scores {
    method getId (line 9) | public long getId() {
    method setId (line 13) | public void setId(long id) {
    method getScore (line 17) | public long getScore() {
    method setScore (line 21) | public void setScore(long score) {
    method toString (line 25) | @Override

FILE: spring-transaction/spring-transaction-platformTransactionManager/src/main/java/com/xcs/spring/PlatformTransactionManagerDemo.java
  class PlatformTransactionManagerDemo (line 15) | public class PlatformTransactionManagerDemo {
    method main (line 20) | public static void main(String[] args) throws SQLException {
    method insertScore (line 38) | private static void insertScore() {
    method insertScoreLog (line 62) | private static void insertScoreLog(long scoreId) {

FILE: spring-transaction/spring-transaction-springTransactionAnnotationParser/src/main/java/com/xcs/spring/ScoresService.java
  type ScoresService (line 3) | public interface ScoresService {
    method insertScore (line 4) | void insertScore();

FILE: spring-transaction/spring-transaction-springTransactionAnnotationParser/src/main/java/com/xcs/spring/ScoresServiceImpl.java
  class ScoresServiceImpl (line 6) | public class ScoresServiceImpl implements ScoresService {
    method insertScore (line 8) | @Override

FILE: spring-transaction/spring-transaction-springTransactionAnnotationParser/src/main/java/com/xcs/spring/SpringTransactionAnnotationParserDemo.java
  class SpringTransactionAnnotationParserDemo (line 8) | public class SpringTransactionAnnotationParserDemo {
    method main (line 10) | public static void main(String[] args) throws NoSuchMethodException {

FILE: spring-transaction/spring-transaction-transactionAttributeSource/src/main/java/com/xcs/spring/ScoresService.java
  type ScoresService (line 3) | public interface ScoresService {
    method insertScore (line 4) | void insertScore();

FILE: spring-transaction/spring-transaction-transactionAttributeSource/src/main/java/com/xcs/spring/ScoresServiceImpl.java
  class ScoresServiceImpl (line 6) | public class ScoresServiceImpl implements ScoresService {
    method insertScore (line 8) | @Override

FILE: spring-transaction/spring-transaction-transactionAttributeSource/src/main/java/com/xcs/spring/TransactionAttributeSourceDemo.java
  class TransactionAttributeSourceDemo (line 9) | public class TransactionAttributeSourceDemo {
    method main (line 11) | public static void main(String[] args) throws NoSuchMethodException {

FILE: spring-transaction/spring-transaction-transactionDefinition/src/main/java/com/xcs/spring/TransactionDefinitionDemo.java
  class TransactionDefinitionDemo (line 5) | public class TransactionDefinitionDemo {
    method main (line 7) | public static void main(String[] args) {

FILE: spring-transaction/spring-transaction-transactionInterceptor/src/main/java/com/xcs/spring/ScoresService.java
  type ScoresService (line 3) | public interface ScoresService {
    method insertScore (line 4) | void insertScore() throws Exception;

FILE: spring-transaction/spring-transaction-transactionInterceptor/src/main/java/com/xcs/spring/ScoresServiceImpl.java
  class ScoresServiceImpl (line 8) | public class ScoresServiceImpl implements ScoresService {
    method ScoresServiceImpl (line 12) | public ScoresServiceImpl(JdbcTemplate jdbcTemplate) {
    method insertScore (line 16) | @Override

FILE: spring-transaction/spring-transaction-transactionInterceptor/src/main/java/com/xcs/spring/TransactionInterceptorDemo.java
  class TransactionInterceptorDemo (line 12) | public class TransactionInterceptorDemo {
    method main (line 14) | public static void main(String[] args) throws Exception {

FILE: spring-transaction/spring-transaction-transactionTemplate/src/main/java/com/xcs/spring/TransactionTemplateDemo.java
  class TransactionTemplateDemo (line 14) | public class TransactionTemplateDemo {
    method main (line 16) | public static void main(String[] args) throws SQLException {

FILE: spring-transaction/sql/test.sql
  type `scores` (line 1) | CREATE TABLE `scores`
  type `scores_log` (line 11) | CREATE TABLE `scores_log`
Condensed preview — 774 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (2,530K chars).
[
  {
    "path": ".gitignore",
    "chars": 395,
    "preview": "HELP.md\ntarget/\n!.mvn/wrapper/maven-wrapper.jar\n!**/src/main/**/target/\n!**/src/test/**/target/\n\n### STS ###\n.apt_genera"
  },
  {
    "path": "LICENSE",
    "chars": 1069,
    "preview": "MIT License\n\nCopyright (c) 2024 xuchengsheng\n\nPermission is hereby granted, free of charge, to any person obtaining a co"
  },
  {
    "path": "README.md",
    "chars": 32338,
    "preview": "<div align=\"center\">\n    <img alt=\"logo\" src=\"image/banner.png\" style=\"height: 80px\">\n</div>\n<div align=\"center\">\n    <h"
  },
  {
    "path": "index.html",
    "chars": 18469,
    "preview": "<table align=\"center\">\r\n    <tr align=\"center\">\r\n        <th>标题</th>\r\n        <th>地址</th>\r\n        <th>难度级别</th>\r\n      "
  },
  {
    "path": "pom.xml",
    "chars": 2234,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2"
  },
  {
    "path": "spring-annotation/pom.xml",
    "chars": 1159,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n         xmlns:xsi=\"http://www"
  },
  {
    "path": "spring-annotation/spring-annotation-autowired/README.md",
    "chars": 26758,
    "preview": "## @Autowired\r\n\r\n- [@Autowired](#autowired)\r\n  - [一、基本信息](#一基本信息)\r\n  - [二、注解描述](#二注解描述)\r\n  - [三、接口源码](#三接口源码)\r\n  - [四、主要"
  },
  {
    "path": "spring-annotation/spring-annotation-autowired/pom.xml",
    "chars": 684,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n         xmlns:xsi=\"http://www"
  },
  {
    "path": "spring-annotation/spring-annotation-autowired/src/main/java/com/xcs/spring/AutowiredApplication.java",
    "chars": 564,
    "preview": "package com.xcs.spring;\n\nimport com.xcs.spring.config.MyConfiguration;\nimport com.xcs.spring.controller.MyController;\nim"
  },
  {
    "path": "spring-annotation/spring-annotation-autowired/src/main/java/com/xcs/spring/config/MyConfiguration.java",
    "chars": 247,
    "preview": "package com.xcs.spring.config;\r\n\r\nimport org.springframework.context.annotation.ComponentScan;\r\nimport org.springframewo"
  },
  {
    "path": "spring-annotation/spring-annotation-autowired/src/main/java/com/xcs/spring/controller/MyController.java",
    "chars": 392,
    "preview": "package com.xcs.spring.controller;\r\n\r\nimport com.xcs.spring.service.MyService;\r\nimport org.springframework.beans.factory"
  },
  {
    "path": "spring-annotation/spring-annotation-autowired/src/main/java/com/xcs/spring/service/MyService.java",
    "chars": 124,
    "preview": "package com.xcs.spring.service;\r\n\r\nimport org.springframework.stereotype.Service;\r\n\r\n@Service\r\npublic class MyService {\r"
  },
  {
    "path": "spring-annotation/spring-annotation-bean/README.md",
    "chars": 43743,
    "preview": "## @Bean\n\n- [@Bean](#bean)\n  - [一、基本信息](#一基本信息)\n  - [二、注解描述](#二注解描述)\n  - [三、注解源码](#三注解源码)\n  - [四、主要功能](#四主要功能)\n  - [五、最佳"
  },
  {
    "path": "spring-annotation/spring-annotation-bean/pom.xml",
    "chars": 527,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n         xmlns:xsi=\"http://www"
  },
  {
    "path": "spring-annotation/spring-annotation-bean/src/main/java/com/xcs/spring/BeanApplication.java",
    "chars": 526,
    "preview": "package com.xcs.spring;\n\nimport com.xcs.spring.bean.MyBean;\nimport com.xcs.spring.config.MyConfiguration;\nimport org.spr"
  },
  {
    "path": "spring-annotation/spring-annotation-bean/src/main/java/com/xcs/spring/bean/MyBean.java",
    "chars": 260,
    "preview": "package com.xcs.spring.bean;\n\n/**\n * @author xcs\n * @date 2023年08月25日 10时22分\n **/\npublic class MyBean {\n\n    public void"
  },
  {
    "path": "spring-annotation/spring-annotation-bean/src/main/java/com/xcs/spring/config/MyConfiguration.java",
    "chars": 401,
    "preview": "package com.xcs.spring.config;\n\nimport com.xcs.spring.bean.MyBean;\nimport org.springframework.context.annotation.Bean;\ni"
  },
  {
    "path": "spring-annotation/spring-annotation-componentScan/README.md",
    "chars": 37104,
    "preview": "## @ComponentScan\n\n- [@ComponentScan](#componentscan)\n  - [一、基本信息](#一基本信息)\n  - [二、注解描述](#二注解描述)\n  - [三、注解源码](#三注解源码)\n  -"
  },
  {
    "path": "spring-annotation/spring-annotation-componentScan/pom.xml",
    "chars": 537,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n         xmlns:xsi=\"http://www"
  },
  {
    "path": "spring-annotation/spring-annotation-componentScan/src/main/java/com/xcs/spring/ComponentScanApplication.java",
    "chars": 571,
    "preview": "package com.xcs.spring;\n\nimport com.xcs.spring.config.MyConfiguration;\nimport org.springframework.context.annotation.Ann"
  },
  {
    "path": "spring-annotation/spring-annotation-componentScan/src/main/java/com/xcs/spring/config/MyConfiguration.java",
    "chars": 694,
    "preview": "package com.xcs.spring.config;\n\nimport com.xcs.spring.service.AdminService;\nimport com.xcs.spring.special.SpecialCompone"
  },
  {
    "path": "spring-annotation/spring-annotation-componentScan/src/main/java/com/xcs/spring/repository/UserRepository.java",
    "chars": 184,
    "preview": "package com.xcs.spring.repository;\n\nimport org.springframework.stereotype.Repository;\n\n/**\n * @author xcs\n * @date 2023年"
  },
  {
    "path": "spring-annotation/spring-annotation-componentScan/src/main/java/com/xcs/spring/service/AdminService.java",
    "chars": 173,
    "preview": "package com.xcs.spring.service;\n\nimport org.springframework.stereotype.Service;\n\n/**\n * @author xcs\n * @date 2023年10月07日"
  },
  {
    "path": "spring-annotation/spring-annotation-componentScan/src/main/java/com/xcs/spring/service/UserService.java",
    "chars": 172,
    "preview": "package com.xcs.spring.service;\n\nimport org.springframework.stereotype.Service;\n\n/**\n * @author xcs\n * @date 2023年10月07日"
  },
  {
    "path": "spring-annotation/spring-annotation-componentScan/src/main/java/com/xcs/spring/special/SpecialComponent.java",
    "chars": 119,
    "preview": "package com.xcs.spring.special;\n\n/**\n * @author xcs\n * @date 2023年10月07日 11时52分\n **/\npublic class SpecialComponent {\n}\n"
  },
  {
    "path": "spring-annotation/spring-annotation-conditional/README.md",
    "chars": 19370,
    "preview": "## @Conditional\n\n- [@Conditional](#conditional)\n  - [一、基本信息](#一基本信息)\n  - [二、注解描述](#二注解描述)\n  - [三、注解源码](#三注解源码)\n  - [四、主要"
  },
  {
    "path": "spring-annotation/spring-annotation-conditional/pom.xml",
    "chars": 534,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n         xmlns:xsi=\"http://www"
  },
  {
    "path": "spring-annotation/spring-annotation-conditional/src/main/java/com/xcs/spring/bean/ConditionBeanApplication.java",
    "chars": 650,
    "preview": "package com.xcs.spring.bean;\n\nimport com.xcs.spring.bean.config.MyBeanConfiguration;\nimport org.springframework.context."
  },
  {
    "path": "spring-annotation/spring-annotation-conditional/src/main/java/com/xcs/spring/bean/condition/BeanPropertyCondition.java",
    "chars": 484,
    "preview": "package com.xcs.spring.bean.condition;\r\n\r\nimport org.springframework.context.annotation.Condition;\r\nimport org.springfra"
  },
  {
    "path": "spring-annotation/spring-annotation-conditional/src/main/java/com/xcs/spring/bean/config/MyBeanConfiguration.java",
    "chars": 617,
    "preview": "package com.xcs.spring.bean.config;\r\n\r\nimport com.xcs.spring.bean.condition.BeanPropertyCondition;\r\nimport com.xcs.sprin"
  },
  {
    "path": "spring-annotation/spring-annotation-conditional/src/main/java/com/xcs/spring/bean/entity/User1.java",
    "chars": 66,
    "preview": "package com.xcs.spring.bean.entity;\r\n\r\npublic class User1 {\r\n\r\n}\r\n"
  },
  {
    "path": "spring-annotation/spring-annotation-conditional/src/main/java/com/xcs/spring/bean/entity/User2.java",
    "chars": 66,
    "preview": "package com.xcs.spring.bean.entity;\r\n\r\npublic class User2 {\r\n\r\n}\r\n"
  },
  {
    "path": "spring-annotation/spring-annotation-conditional/src/main/java/com/xcs/spring/configuration/ConditionConfigurationApplication.java",
    "chars": 683,
    "preview": "package com.xcs.spring.configuration;\n\nimport com.xcs.spring.configuration.config.MyConfigConfiguration;\nimport org.spri"
  },
  {
    "path": "spring-annotation/spring-annotation-conditional/src/main/java/com/xcs/spring/configuration/condition/ConfigPropertyCondition.java",
    "chars": 479,
    "preview": "package com.xcs.spring.configuration.condition;\r\n\r\nimport org.springframework.context.annotation.Condition;\r\nimport org."
  },
  {
    "path": "spring-annotation/spring-annotation-conditional/src/main/java/com/xcs/spring/configuration/config/MyConfigConfiguration.java",
    "chars": 655,
    "preview": "package com.xcs.spring.configuration.config;\r\n\r\nimport com.xcs.spring.configuration.condition.ConfigPropertyCondition;\r\n"
  },
  {
    "path": "spring-annotation/spring-annotation-conditional/src/main/java/com/xcs/spring/configuration/entity/User3.java",
    "chars": 73,
    "preview": "package com.xcs.spring.configuration.entity;\r\n\r\npublic class User3 {\r\n}\r\n"
  },
  {
    "path": "spring-annotation/spring-annotation-conditional/src/main/java/com/xcs/spring/configuration/entity/User4.java",
    "chars": 73,
    "preview": "package com.xcs.spring.configuration.entity;\r\n\r\npublic class User4 {\r\n}\r\n"
  },
  {
    "path": "spring-annotation/spring-annotation-conditional/src/main/java/com/xcs/spring/custom/ConditionCustomApplication.java",
    "chars": 662,
    "preview": "package com.xcs.spring.custom;\n\nimport com.xcs.spring.custom.config.MyCustomConfiguration;\nimport org.springframework.co"
  },
  {
    "path": "spring-annotation/spring-annotation-conditional/src/main/java/com/xcs/spring/custom/annotation/ConditionalOnCustomActive.java",
    "chars": 518,
    "preview": "package com.xcs.spring.custom.annotation;\r\n\r\nimport com.xcs.spring.custom.condition.CustomActiveCondition;\r\nimport org.s"
  },
  {
    "path": "spring-annotation/spring-annotation-conditional/src/main/java/com/xcs/spring/custom/condition/CustomActiveCondition.java",
    "chars": 468,
    "preview": "package com.xcs.spring.custom.condition;\r\n\r\nimport org.springframework.context.annotation.Condition;\r\nimport org.springf"
  },
  {
    "path": "spring-annotation/spring-annotation-conditional/src/main/java/com/xcs/spring/custom/config/MyCustomConfiguration.java",
    "chars": 553,
    "preview": "package com.xcs.spring.custom.config;\r\n\r\nimport com.xcs.spring.custom.annotation.ConditionalOnCustomActive;\r\nimport com."
  },
  {
    "path": "spring-annotation/spring-annotation-conditional/src/main/java/com/xcs/spring/custom/entity/User5.java",
    "chars": 66,
    "preview": "package com.xcs.spring.custom.entity;\r\n\r\npublic class User5 {\r\n}\r\n"
  },
  {
    "path": "spring-annotation/spring-annotation-conditional/src/main/java/com/xcs/spring/custom/entity/User6.java",
    "chars": 66,
    "preview": "package com.xcs.spring.custom.entity;\r\n\r\npublic class User6 {\r\n}\r\n"
  },
  {
    "path": "spring-annotation/spring-annotation-configuration/README.md",
    "chars": 29780,
    "preview": "## @Configuration\n\n- [@Configuration](#configuration)\n  - [一、基本信息](#一基本信息)\n  - [二、注解描述](#二注解描述)\n  - [三、注解源码](#三注解源码)\n  -"
  },
  {
    "path": "spring-annotation/spring-annotation-configuration/pom.xml",
    "chars": 536,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n         xmlns:xsi=\"http://www"
  },
  {
    "path": "spring-annotation/spring-annotation-configuration/src/main/java/com/xcs/spring/ConfigurationApplication.java",
    "chars": 601,
    "preview": "package com.xcs.spring;\n\nimport com.xcs.spring.config.MyConfiguration;\nimport org.springframework.context.annotation.Ann"
  },
  {
    "path": "spring-annotation/spring-annotation-configuration/src/main/java/com/xcs/spring/bean/MyBean.java",
    "chars": 107,
    "preview": "package com.xcs.spring.bean;\n\n/**\n * @author xcs\n * @date 2023年08月07日 16时26分\n **/\npublic class MyBean {\n\n}\n"
  },
  {
    "path": "spring-annotation/spring-annotation-configuration/src/main/java/com/xcs/spring/config/MyConfiguration.java",
    "chars": 355,
    "preview": "package com.xcs.spring.config;\n\nimport com.xcs.spring.bean.MyBean;\nimport org.springframework.context.annotation.Bean;\ni"
  },
  {
    "path": "spring-annotation/spring-annotation-dependsOn/README.md",
    "chars": 24065,
    "preview": "## @DependsOn\r\n\r\n- [@DependsOn](#dependson)\r\n  - [一、基本信息](#一基本信息)\r\n  - [二、注解描述](#二注解描述)\r\n  - [三、注解源码](#三注解源码)\r\n  - [四、主要"
  },
  {
    "path": "spring-annotation/spring-annotation-dependsOn/pom.xml",
    "chars": 532,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n         xmlns:xsi=\"http://www"
  },
  {
    "path": "spring-annotation/spring-annotation-dependsOn/src/main/java/com/xcs/spring/DependsOnApplication.java",
    "chars": 437,
    "preview": "package com.xcs.spring;\n\nimport com.xcs.spring.config.MyConfiguration;\nimport org.springframework.context.annotation.Ann"
  },
  {
    "path": "spring-annotation/spring-annotation-dependsOn/src/main/java/com/xcs/spring/bean/BeanA.java",
    "chars": 379,
    "preview": "package com.xcs.spring.bean;\n\nimport org.springframework.beans.factory.DisposableBean;\n\n/**\n * @author xcs\n * @date 2023"
  },
  {
    "path": "spring-annotation/spring-annotation-dependsOn/src/main/java/com/xcs/spring/bean/BeanB.java",
    "chars": 379,
    "preview": "package com.xcs.spring.bean;\n\nimport org.springframework.beans.factory.DisposableBean;\n\n/**\n * @author xcs\n * @date 2023"
  },
  {
    "path": "spring-annotation/spring-annotation-dependsOn/src/main/java/com/xcs/spring/bean/BeanC.java",
    "chars": 379,
    "preview": "package com.xcs.spring.bean;\n\nimport org.springframework.beans.factory.DisposableBean;\n\n/**\n * @author xcs\n * @date 2023"
  },
  {
    "path": "spring-annotation/spring-annotation-dependsOn/src/main/java/com/xcs/spring/config/MyConfiguration.java",
    "chars": 668,
    "preview": "package com.xcs.spring.config;\n\nimport com.xcs.spring.bean.BeanA;\nimport com.xcs.spring.bean.BeanB;\nimport com.xcs.sprin"
  },
  {
    "path": "spring-annotation/spring-annotation-import/README.md",
    "chars": 33994,
    "preview": "## @Import\n\n- [@Import](#import)\n  - [一、基本信息](#一基本信息)\n  - [二、注解描述](#二注解描述)\n  - [三、注解源码](#三注解源码)\n  - [四、主要功能](#四主要功能)\n  -"
  },
  {
    "path": "spring-annotation/spring-annotation-import/pom.xml",
    "chars": 529,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n         xmlns:xsi=\"http://www"
  },
  {
    "path": "spring-annotation/spring-annotation-import/src/main/java/com/xcs/spring/ImportApplication.java",
    "chars": 564,
    "preview": "package com.xcs.spring;\n\nimport com.xcs.spring.config.MyConfiguration;\nimport org.springframework.context.annotation.Ann"
  },
  {
    "path": "spring-annotation/spring-annotation-import/src/main/java/com/xcs/spring/bean/MyBean.java",
    "chars": 107,
    "preview": "package com.xcs.spring.bean;\n\n/**\n * @author xcs\n * @date 2023年09月11日 11时13分\n **/\npublic class MyBean {\n\n}\n"
  },
  {
    "path": "spring-annotation/spring-annotation-import/src/main/java/com/xcs/spring/bean/MyBeanA.java",
    "chars": 107,
    "preview": "package com.xcs.spring.bean;\n\n/**\n * @author xcs\n * @date 2023年08月28日 11时13分\n **/\npublic class MyBeanA {\n}\n"
  },
  {
    "path": "spring-annotation/spring-annotation-import/src/main/java/com/xcs/spring/bean/MyBeanB.java",
    "chars": 107,
    "preview": "package com.xcs.spring.bean;\n\n/**\n * @author xcs\n * @date 2023年08月28日 11时13分\n **/\npublic class MyBeanB {\n}\n"
  },
  {
    "path": "spring-annotation/spring-annotation-import/src/main/java/com/xcs/spring/bean/MyBeanC.java",
    "chars": 107,
    "preview": "package com.xcs.spring.bean;\n\n/**\n * @author xcs\n * @date 2023年08月28日 11时13分\n **/\npublic class MyBeanC {\n}\n"
  },
  {
    "path": "spring-annotation/spring-annotation-import/src/main/java/com/xcs/spring/config/MyConfiguration.java",
    "chars": 402,
    "preview": "package com.xcs.spring.config;\n\nimport com.xcs.spring.bean.MyBean;\nimport org.springframework.context.annotation.Configu"
  },
  {
    "path": "spring-annotation/spring-annotation-import/src/main/java/com/xcs/spring/config/MyDeferredImportSelector.java",
    "chars": 478,
    "preview": "package com.xcs.spring.config;\n\nimport com.xcs.spring.bean.MyBeanB;\nimport org.springframework.context.annotation.Deferr"
  },
  {
    "path": "spring-annotation/spring-annotation-import/src/main/java/com/xcs/spring/config/MyImportBeanDefinitionRegistrar.java",
    "chars": 790,
    "preview": "package com.xcs.spring.config;\n\nimport com.xcs.spring.bean.MyBeanC;\nimport org.springframework.beans.factory.support.Bea"
  },
  {
    "path": "spring-annotation/spring-annotation-import/src/main/java/com/xcs/spring/config/MyImportSelector.java",
    "chars": 453,
    "preview": "package com.xcs.spring.config;\n\nimport com.xcs.spring.bean.MyBeanA;\nimport org.springframework.context.annotation.Import"
  },
  {
    "path": "spring-annotation/spring-annotation-lazy/README.md",
    "chars": 27308,
    "preview": "## @Lazy\n\n- [@Lazy](#lazy)\n  - [一、基本信息](#一基本信息)\n  - [二、注解描述](#二注解描述)\n  - [三、注解源码](#三注解源码)\n  - [四、主要功能](#四主要功能)\n  - [五、最佳"
  },
  {
    "path": "spring-annotation/spring-annotation-lazy/pom.xml",
    "chars": 527,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n         xmlns:xsi=\"http://www"
  },
  {
    "path": "spring-annotation/spring-annotation-lazy/src/main/java/com/xcs/spring/LazyApplication.java",
    "chars": 757,
    "preview": "package com.xcs.spring;\n\nimport com.xcs.spring.config.MyConfiguration;\nimport com.xcs.spring.service.MyService;\nimport o"
  },
  {
    "path": "spring-annotation/spring-annotation-lazy/src/main/java/com/xcs/spring/bean/MyBean.java",
    "chars": 220,
    "preview": "package com.xcs.spring.bean;\r\n\r\npublic class MyBean {\r\n\r\n    public MyBean() {\r\n        System.out.println(\"MyBean 的构造函数"
  },
  {
    "path": "spring-annotation/spring-annotation-lazy/src/main/java/com/xcs/spring/config/MyConfiguration.java",
    "chars": 556,
    "preview": "package com.xcs.spring.config;\r\n\r\nimport com.xcs.spring.bean.MyBean;\r\nimport com.xcs.spring.service.MyService;\r\nimport o"
  },
  {
    "path": "spring-annotation/spring-annotation-lazy/src/main/java/com/xcs/spring/service/MyService.java",
    "chars": 404,
    "preview": "package com.xcs.spring.service;\r\n\r\nimport com.xcs.spring.bean.MyBean;\r\nimport org.springframework.beans.factory.annotati"
  },
  {
    "path": "spring-annotation/spring-annotation-profile/README.md",
    "chars": 7,
    "preview": "## TODO"
  },
  {
    "path": "spring-annotation/spring-annotation-profile/pom.xml",
    "chars": 682,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n         xmlns:xsi=\"http://www"
  },
  {
    "path": "spring-annotation/spring-annotation-propertySource/README.md",
    "chars": 20785,
    "preview": "## @PropertySource\n\n- [@PropertySource](#propertysource)\n  - [一、基本信息](#一基本信息)\n  - [二、注解描述](#二注解描述)\n  - [三、注解源码](#三注解源码)\n"
  },
  {
    "path": "spring-annotation/spring-annotation-propertySource/pom.xml",
    "chars": 537,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n         xmlns:xsi=\"http://www"
  },
  {
    "path": "spring-annotation/spring-annotation-propertySource/src/main/java/com/xcs/spring/PropertySourceApplication.java",
    "chars": 601,
    "preview": "package com.xcs.spring;\n\nimport com.xcs.spring.config.MyConfiguration;\nimport org.springframework.context.annotation.Ann"
  },
  {
    "path": "spring-annotation/spring-annotation-propertySource/src/main/java/com/xcs/spring/config/MyConfiguration.java",
    "chars": 304,
    "preview": "package com.xcs.spring.config;\n\nimport org.springframework.context.annotation.Configuration;\nimport org.springframework."
  },
  {
    "path": "spring-annotation/spring-annotation-propertySource/src/main/resources/my-application.yml",
    "chars": 30,
    "preview": "apiVersion: v1\nkind: ConfigMap"
  },
  {
    "path": "spring-annotation/spring-annotation-value/README.md",
    "chars": 35269,
    "preview": "## @Value\n\n- [@Value](#value)\n  - [一、基本信息](#一基本信息)\n  - [二、注解描述](#二注解描述)\n  - [三、注解源码](#三注解源码)\n  - [四、主要功能](#四主要功能)\n  - [五"
  },
  {
    "path": "spring-annotation/spring-annotation-value/pom.xml",
    "chars": 680,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n         xmlns:xsi=\"http://www"
  },
  {
    "path": "spring-annotation/spring-annotation-value/src/main/java/com/xcs/spring/ValueApplication.java",
    "chars": 408,
    "preview": "package com.xcs.spring;\n\nimport com.xcs.spring.config.MyConfiguration;\nimport org.springframework.context.annotation.Ann"
  },
  {
    "path": "spring-annotation/spring-annotation-value/src/main/java/com/xcs/spring/config/MyConfiguration.java",
    "chars": 484,
    "preview": "package com.xcs.spring.config;\n\nimport com.xcs.spring.service.MyService;\nimport org.springframework.context.annotation.B"
  },
  {
    "path": "spring-annotation/spring-annotation-value/src/main/java/com/xcs/spring/service/MyService.java",
    "chars": 1262,
    "preview": "package com.xcs.spring.service;\n\nimport org.springframework.beans.factory.InitializingBean;\nimport org.springframework.b"
  },
  {
    "path": "spring-annotation/spring-annotation-value/src/main/resources/application.properties",
    "chars": 154,
    "preview": "app.name=My Spring Application\napp.servers=server1,server2,server3\napp.val1=10\napp.val2=20\n\nmyapp.names[0]=Alice\nmyapp.n"
  },
  {
    "path": "spring-aop/pom.xml",
    "chars": 2353,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n         xmlns:xsi=\"http://www"
  },
  {
    "path": "spring-aop/spring-aop-advice/README.md",
    "chars": 2654,
    "preview": "## Advice\n\n- [Advice](#advice)\n  - [一、基本信息](#一基本信息)\n  - [二、基本描述](#二基本描述)\n  - [三、主要功能](#三主要功能)\n  - [四、接口源码](#四接口源码)\n  - ["
  },
  {
    "path": "spring-aop/spring-aop-advice/pom.xml",
    "chars": 515,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n         xmlns:xsi=\"http://www"
  },
  {
    "path": "spring-aop/spring-aop-advice-afterReturningAdvice/README.md",
    "chars": 3335,
    "preview": "## AfterReturningAdvice\n\n- [AfterReturningAdvice](#afterreturningadvice)\n  - [一、基本信息](#一基本信息)\n  - [二、基本描述](#二基本描述)\n  - ["
  },
  {
    "path": "spring-aop/spring-aop-advice-afterReturningAdvice/pom.xml",
    "chars": 536,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n         xmlns:xsi=\"http://www"
  },
  {
    "path": "spring-aop/spring-aop-advice-afterReturningAdvice/src/main/java/com/xcs/spring/AfterReturningAdviceDemo.java",
    "chars": 472,
    "preview": "package com.xcs.spring;\n\nimport org.springframework.aop.framework.ProxyFactory;\n\npublic class AfterReturningAdviceDemo {"
  },
  {
    "path": "spring-aop/spring-aop-advice-afterReturningAdvice/src/main/java/com/xcs/spring/MyAfterReturningAdvice.java",
    "chars": 384,
    "preview": "package com.xcs.spring;\n\nimport org.springframework.aop.AfterReturningAdvice;\n\nimport java.lang.reflect.Method;\n\npublic "
  },
  {
    "path": "spring-aop/spring-aop-advice-afterReturningAdvice/src/main/java/com/xcs/spring/MyService.java",
    "chars": 121,
    "preview": "package com.xcs.spring;\n\npublic class MyService {\n\n    public void foo() {\n        System.out.println(\"foo...\");\n    }\n}"
  },
  {
    "path": "spring-aop/spring-aop-advice-introductionInterceptor/README.md",
    "chars": 5079,
    "preview": "## IntroductionInterceptor\n\n- [IntroductionInterceptor](#introductioninterceptor)\n  - [一、基本信息](#一基本信息)\n  - [二、基本描述](#二基本"
  },
  {
    "path": "spring-aop/spring-aop-advice-introductionInterceptor/pom.xml",
    "chars": 539,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n         xmlns:xsi=\"http://www"
  },
  {
    "path": "spring-aop/spring-aop-advice-introductionInterceptor/src/main/java/com/xcs/spring/IntroductionInterceptorDemo.java",
    "chars": 797,
    "preview": "package com.xcs.spring;\n\nimport org.springframework.aop.framework.ProxyFactory;\nimport org.springframework.aop.support.D"
  },
  {
    "path": "spring-aop/spring-aop-advice-introductionInterceptor/src/main/java/com/xcs/spring/MyMonitoringCapable.java",
    "chars": 95,
    "preview": "package com.xcs.spring;\n\npublic interface MyMonitoringCapable {\n    void toggleMonitoring();\n}\n"
  },
  {
    "path": "spring-aop/spring-aop-advice-introductionInterceptor/src/main/java/com/xcs/spring/MyMonitoringIntroductionAdvice.java",
    "chars": 1048,
    "preview": "package com.xcs.spring;\n\nimport org.aopalliance.intercept.MethodInvocation;\nimport org.springframework.aop.support.Deleg"
  },
  {
    "path": "spring-aop/spring-aop-advice-introductionInterceptor/src/main/java/com/xcs/spring/MyService.java",
    "chars": 263,
    "preview": "package com.xcs.spring;\n\npublic class MyService {\n\n    public void foo() {\n        System.out.println(\"foo...\");\n       "
  },
  {
    "path": "spring-aop/spring-aop-advice-methodBeforeAdvice/README.md",
    "chars": 3085,
    "preview": "## MethodBeforeAdvice\n\n- [MethodBeforeAdvice](#methodbeforeadvice)\n  - [一、基本信息](#一基本信息)\n  - [二、基本描述](#二基本描述)\n  - [三、主要功能"
  },
  {
    "path": "spring-aop/spring-aop-advice-methodBeforeAdvice/pom.xml",
    "chars": 534,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n         xmlns:xsi=\"http://www"
  },
  {
    "path": "spring-aop/spring-aop-advice-methodBeforeAdvice/src/main/java/com/xcs/spring/MethodBeforeAdviceDemo.java",
    "chars": 468,
    "preview": "package com.xcs.spring;\n\nimport org.springframework.aop.framework.ProxyFactory;\n\npublic class MethodBeforeAdviceDemo {\n\n"
  },
  {
    "path": "spring-aop/spring-aop-advice-methodBeforeAdvice/src/main/java/com/xcs/spring/MyMethodBeforeAdvice.java",
    "chars": 351,
    "preview": "package com.xcs.spring;\n\nimport org.springframework.aop.MethodBeforeAdvice;\n\nimport java.lang.reflect.Method;\n\npublic cl"
  },
  {
    "path": "spring-aop/spring-aop-advice-methodBeforeAdvice/src/main/java/com/xcs/spring/MyService.java",
    "chars": 121,
    "preview": "package com.xcs.spring;\n\npublic class MyService {\n\n    public void foo() {\n        System.out.println(\"foo...\");\n    }\n}"
  },
  {
    "path": "spring-aop/spring-aop-advice-methodInterceptor/README.md",
    "chars": 4738,
    "preview": "## MethodInterceptor\n\n- [MethodInterceptor](#methodinterceptor)\n  - [一、基本信息](#一基本信息)\n  - [二、基本描述](#二基本描述)\n  - [三、主要功能](#"
  },
  {
    "path": "spring-aop/spring-aop-advice-methodInterceptor/pom.xml",
    "chars": 533,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n         xmlns:xsi=\"http://www"
  },
  {
    "path": "spring-aop/spring-aop-advice-methodInterceptor/src/main/java/com/xcs/spring/MethodInterceptorDemo.java",
    "chars": 466,
    "preview": "package com.xcs.spring;\n\nimport org.springframework.aop.framework.ProxyFactory;\n\npublic class MethodInterceptorDemo {\n\n "
  },
  {
    "path": "spring-aop/spring-aop-advice-methodInterceptor/src/main/java/com/xcs/spring/MyMethodInterceptor.java",
    "chars": 584,
    "preview": "package com.xcs.spring;\n\nimport org.aopalliance.intercept.MethodInterceptor;\nimport org.aopalliance.intercept.MethodInvo"
  },
  {
    "path": "spring-aop/spring-aop-advice-methodInterceptor/src/main/java/com/xcs/spring/MyService.java",
    "chars": 121,
    "preview": "package com.xcs.spring;\n\npublic class MyService {\n\n    public void foo() {\n        System.out.println(\"foo...\");\n    }\n}"
  },
  {
    "path": "spring-aop/spring-aop-advice-throwsAdvice/README.md",
    "chars": 4722,
    "preview": "## ThrowsAdvice\n\n- [ThrowsAdvice](#throwsadvice)\n  - [一、基本信息](#一基本信息)\n  - [二、基本描述](#二基本描述)\n  - [三、主要功能](#三主要功能)\n  - [四、接"
  },
  {
    "path": "spring-aop/spring-aop-advice-throwsAdvice/pom.xml",
    "chars": 528,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n         xmlns:xsi=\"http://www"
  },
  {
    "path": "spring-aop/spring-aop-advice-throwsAdvice/src/main/java/com/xcs/spring/MyService.java",
    "chars": 144,
    "preview": "package com.xcs.spring;\n\npublic class MyService {\n\n    public void foo() {\n        System.out.println(\"foo...\");\n       "
  },
  {
    "path": "spring-aop/spring-aop-advice-throwsAdvice/src/main/java/com/xcs/spring/MyThrowsAdvice.java",
    "chars": 264,
    "preview": "package com.xcs.spring;\n\nimport org.springframework.aop.ThrowsAdvice;\n\npublic class MyThrowsAdvice implements ThrowsAdvi"
  },
  {
    "path": "spring-aop/spring-aop-advice-throwsAdvice/src/main/java/com/xcs/spring/ThrowsAdviceDemo.java",
    "chars": 456,
    "preview": "package com.xcs.spring;\n\nimport org.springframework.aop.framework.ProxyFactory;\n\npublic class ThrowsAdviceDemo {\n\n    pu"
  },
  {
    "path": "spring-aop/spring-aop-advised/README.md",
    "chars": 7865,
    "preview": "## Advised\n\n- [Advised](#advised)\n\t- [一、基本信息](#一基本信息)\n\t- [二、基本描述](#二基本描述)\n\t- [三、主要功能](#三主要功能)\n\t- [四、接口源码](#四接口源码)\n\t- [五、"
  },
  {
    "path": "spring-aop/spring-aop-advised/pom.xml",
    "chars": 516,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n         xmlns:xsi=\"http://www"
  },
  {
    "path": "spring-aop/spring-aop-advised/src/main/java/com/xcs/spring/AdvisedDemo.java",
    "chars": 949,
    "preview": "package com.xcs.spring;\n\nimport org.aopalliance.aop.Advice;\nimport org.springframework.aop.framework.AdvisedSupport;\nimp"
  },
  {
    "path": "spring-aop/spring-aop-advised/src/main/java/com/xcs/spring/MyService.java",
    "chars": 72,
    "preview": "package com.xcs.spring;\n\npublic interface MyService {\n    void foo();\n}\n"
  },
  {
    "path": "spring-aop/spring-aop-advised/src/main/java/com/xcs/spring/MyServiceImpl.java",
    "chars": 160,
    "preview": "package com.xcs.spring;\n\npublic class MyServiceImpl implements MyService {\n\n    @Override\n    public void foo() {\n      "
  },
  {
    "path": "spring-aop/spring-aop-advisor/README.md",
    "chars": 5777,
    "preview": "## Advisor\n\n- [Advisor](#advisor)\n  - [一、基本信息](#一基本信息)\n  - [二、基本描述](#二基本描述)\n  - [三、主要功能](#三主要功能)\n  - [四、接口源码](#四接口源码)\n  "
  },
  {
    "path": "spring-aop/spring-aop-advisor/pom.xml",
    "chars": 516,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n         xmlns:xsi=\"http://www"
  },
  {
    "path": "spring-aop/spring-aop-advisor/src/main/java/com/xcs/spring/AdvisorDemo.java",
    "chars": 446,
    "preview": "package com.xcs.spring;\n\nimport org.springframework.aop.framework.ProxyFactory;\n\npublic class AdvisorDemo {\n\n    public "
  },
  {
    "path": "spring-aop/spring-aop-advisor/src/main/java/com/xcs/spring/MyAdvice.java",
    "chars": 574,
    "preview": "package com.xcs.spring;\n\nimport org.aopalliance.intercept.MethodInterceptor;\nimport org.aopalliance.intercept.MethodInvo"
  },
  {
    "path": "spring-aop/spring-aop-advisor/src/main/java/com/xcs/spring/MyCustomAdvisor.java",
    "chars": 791,
    "preview": "package com.xcs.spring;\n\nimport org.aopalliance.aop.Advice;\nimport org.springframework.aop.Pointcut;\nimport org.springfr"
  },
  {
    "path": "spring-aop/spring-aop-advisor/src/main/java/com/xcs/spring/MyCustomAnnotation.java",
    "chars": 309,
    "preview": "package com.xcs.spring;\n\nimport java.lang.annotation.ElementType;\nimport java.lang.annotation.Retention;\nimport java.lan"
  },
  {
    "path": "spring-aop/spring-aop-advisor/src/main/java/com/xcs/spring/MyService.java",
    "chars": 145,
    "preview": "package com.xcs.spring;\n\npublic class MyService {\n\n    @MyCustomAnnotation\n    public void foo() {\n        System.out.pr"
  },
  {
    "path": "spring-aop/spring-aop-advisorAdapter/README.md",
    "chars": 13121,
    "preview": "## AdvisorAdapter\n\n- [AdvisorAdapter](#advisoradapter)\n  - [一、基本信息](#一基本信息)\n  - [二、基本描述](#二基本描述)\n  - [三、主要功能](#三主要功能)\n  "
  },
  {
    "path": "spring-aop/spring-aop-advisorAdapter/pom.xml",
    "chars": 523,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n         xmlns:xsi=\"http://www"
  },
  {
    "path": "spring-aop/spring-aop-advisorAdapter/src/main/java/com/xcs/spring/AdvisorAdapterDemo.java",
    "chars": 874,
    "preview": "package com.xcs.spring;\n\nimport org.springframework.aop.framework.ProxyFactory;\nimport org.springframework.aop.framework"
  },
  {
    "path": "spring-aop/spring-aop-advisorAdapter/src/main/java/com/xcs/spring/MyNullReturningAdvice.java",
    "chars": 287,
    "preview": "package com.xcs.spring;\n\nimport java.lang.reflect.Method;\n\npublic class MyNullReturningAdvice implements NullReturningAd"
  },
  {
    "path": "spring-aop/spring-aop-advisorAdapter/src/main/java/com/xcs/spring/MyService.java",
    "chars": 247,
    "preview": "package com.xcs.spring;\n\npublic class MyService {\n\n    public String foo() {\n        System.out.println(\"foo...\");\n     "
  },
  {
    "path": "spring-aop/spring-aop-advisorAdapter/src/main/java/com/xcs/spring/NullReturningAdvice.java",
    "chars": 537,
    "preview": "package com.xcs.spring;\n\nimport org.springframework.aop.AfterAdvice;\nimport org.springframework.lang.Nullable;\n\nimport j"
  },
  {
    "path": "spring-aop/spring-aop-advisorAdapter/src/main/java/com/xcs/spring/NullReturningAdviceAdapter.java",
    "chars": 997,
    "preview": "package com.xcs.spring;\n\nimport org.aopalliance.aop.Advice;\nimport org.aopalliance.intercept.MethodInterceptor;\nimport o"
  },
  {
    "path": "spring-aop/spring-aop-advisorAdapter/src/main/java/com/xcs/spring/NullReturningAdviceInterceptor.java",
    "chars": 1171,
    "preview": "package com.xcs.spring;\n\nimport org.aopalliance.intercept.MethodInterceptor;\nimport org.aopalliance.intercept.MethodInvo"
  },
  {
    "path": "spring-aop/spring-aop-advisorAdapterRegistry/README.md",
    "chars": 7752,
    "preview": "## AdvisorAdapterRegistry\n\n- [AdvisorAdapterRegistry](#advisoradapterregistry)\n    - [一、基本信息](#一基本信息)\n    - [二、基本描述](#二基"
  },
  {
    "path": "spring-aop/spring-aop-advisorAdapterRegistry/pom.xml",
    "chars": 531,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n         xmlns:xsi=\"http://www"
  },
  {
    "path": "spring-aop/spring-aop-advisorAdapterRegistry/src/main/java/com/xcs/spring/AdvisorAdapterRegistryDemo.java",
    "chars": 787,
    "preview": "package com.xcs.spring;\n\nimport org.aopalliance.intercept.MethodInterceptor;\nimport org.springframework.aop.Advisor;\nimp"
  },
  {
    "path": "spring-aop/spring-aop-advisorAdapterRegistry/src/main/java/com/xcs/spring/MyMethodBeforeAdvice.java",
    "chars": 352,
    "preview": "package com.xcs.spring;\n\nimport org.springframework.aop.MethodBeforeAdvice;\n\nimport java.lang.reflect.Method;\n\npublic cl"
  },
  {
    "path": "spring-aop/spring-aop-advisorChainFactory/README.md",
    "chars": 6866,
    "preview": "## AdvisorChainFactory\n\n- [AdvisorChainFactory](#advisorchainfactory)\n    - [一、基本信息](#一基本信息)\n    - [二、基本描述](#二基本描述)\n    "
  },
  {
    "path": "spring-aop/spring-aop-advisorChainFactory/pom.xml",
    "chars": 528,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n         xmlns:xsi=\"http://www"
  },
  {
    "path": "spring-aop/spring-aop-advisorChainFactory/src/main/java/com/xcs/spring/AdvisorChainFactoryDemo.java",
    "chars": 1030,
    "preview": "package com.xcs.spring;\n\nimport org.springframework.aop.framework.AdvisedSupport;\nimport org.springframework.aop.framewo"
  },
  {
    "path": "spring-aop/spring-aop-advisorChainFactory/src/main/java/com/xcs/spring/MyAfterReturningAdvice.java",
    "chars": 385,
    "preview": "package com.xcs.spring;\n\nimport org.springframework.aop.AfterReturningAdvice;\n\nimport java.lang.reflect.Method;\n\npublic "
  },
  {
    "path": "spring-aop/spring-aop-advisorChainFactory/src/main/java/com/xcs/spring/MyMethodBeforeAdvice.java",
    "chars": 352,
    "preview": "package com.xcs.spring;\n\nimport org.springframework.aop.MethodBeforeAdvice;\n\nimport java.lang.reflect.Method;\n\npublic cl"
  },
  {
    "path": "spring-aop/spring-aop-advisorChainFactory/src/main/java/com/xcs/spring/MyService.java",
    "chars": 121,
    "preview": "package com.xcs.spring;\n\npublic class MyService {\n\n    public void foo() {\n        System.out.println(\"foo...\");\n    }\n}"
  },
  {
    "path": "spring-aop/spring-aop-annotationAwareAspectJAutoProxyCreator/README.md",
    "chars": 20986,
    "preview": "## AnnotationAwareAspectJAutoProxyCreator\n\n- [AnnotationAwareAspectJAutoProxyCreator](#annotationawareaspectjautoproxycr"
  },
  {
    "path": "spring-aop/spring-aop-annotationAwareAspectJAutoProxyCreator/pom.xml",
    "chars": 547,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n         xmlns:xsi=\"http://www"
  },
  {
    "path": "spring-aop/spring-aop-annotationAwareAspectJAutoProxyCreator/src/main/java/com/xcs/spring/AnnotationAwareAspectJAutoProxyCreatorDemo.java",
    "chars": 504,
    "preview": "package com.xcs.spring;\n\nimport org.springframework.context.annotation.AnnotationConfigApplicationContext;\n\npublic class"
  },
  {
    "path": "spring-aop/spring-aop-annotationAwareAspectJAutoProxyCreator/src/main/java/com/xcs/spring/AppConfig.java",
    "chars": 300,
    "preview": "package com.xcs.spring;\n\nimport org.springframework.context.annotation.ComponentScan;\nimport org.springframework.context"
  },
  {
    "path": "spring-aop/spring-aop-annotationAwareAspectJAutoProxyCreator/src/main/java/com/xcs/spring/MyAspect.java",
    "chars": 355,
    "preview": "package com.xcs.spring;\n\nimport org.aspectj.lang.annotation.Aspect;\nimport org.aspectj.lang.annotation.Before;\nimport or"
  },
  {
    "path": "spring-aop/spring-aop-annotationAwareAspectJAutoProxyCreator/src/main/java/com/xcs/spring/MyService.java",
    "chars": 178,
    "preview": "package com.xcs.spring;\n\nimport org.springframework.stereotype.Service;\n\n@Service\npublic class MyService {\n\n    public v"
  },
  {
    "path": "spring-aop/spring-aop-aopContext/README.md",
    "chars": 7100,
    "preview": "## AopContext\n\n- [AopContext](#aopcontext)\n  - [一、基本信息](#一基本信息)\n  - [二、基本描述](#二基本描述)\n  - [三、主要功能](#三主要功能)\n  - [四、类源码](#四"
  },
  {
    "path": "spring-aop/spring-aop-aopContext/pom.xml",
    "chars": 519,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n         xmlns:xsi=\"http://www"
  },
  {
    "path": "spring-aop/spring-aop-aopContext/src/main/java/com/xcs/spring/AopContextDemo.java",
    "chars": 744,
    "preview": "package com.xcs.spring;\n\nimport org.springframework.aop.framework.ProxyFactory;\nimport org.springframework.aop.support.D"
  },
  {
    "path": "spring-aop/spring-aop-aopContext/src/main/java/com/xcs/spring/MyAnnotation.java",
    "chars": 301,
    "preview": "package com.xcs.spring;\n\nimport java.lang.annotation.ElementType;\nimport java.lang.annotation.Retention;\nimport java.lan"
  },
  {
    "path": "spring-aop/spring-aop-aopContext/src/main/java/com/xcs/spring/MyMethodBeforeAdvice.java",
    "chars": 367,
    "preview": "package com.xcs.spring;\n\nimport org.springframework.aop.MethodBeforeAdvice;\n\nimport java.lang.reflect.Method;\n\npublic cl"
  },
  {
    "path": "spring-aop/spring-aop-aopContext/src/main/java/com/xcs/spring/MyService.java",
    "chars": 386,
    "preview": "package com.xcs.spring;\n\nimport org.springframework.aop.framework.AopContext;\n\n@MyAnnotation\npublic class MyService {\n\n "
  },
  {
    "path": "spring-aop/spring-aop-aopProxy/README.md",
    "chars": 20246,
    "preview": "## AopProxy\n\n- [AopProxy](#aopproxy)\n  - [一、基本信息](#一基本信息)\n  - [二、基本描述](#二基本描述)\n  - [三、主要功能](#三主要功能)\n  - [四、接口源码](#四接口源码)"
  },
  {
    "path": "spring-aop/spring-aop-aopProxy/pom.xml",
    "chars": 517,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n         xmlns:xsi=\"http://www"
  },
  {
    "path": "spring-aop/spring-aop-aopProxy/src/main/java/com/xcs/spring/AopProxyDemo.java",
    "chars": 2440,
    "preview": "package com.xcs.spring;\n\nimport org.springframework.aop.framework.AdvisedSupport;\nimport org.springframework.aop.framewo"
  },
  {
    "path": "spring-aop/spring-aop-aopProxy/src/main/java/com/xcs/spring/MyMethodInterceptor.java",
    "chars": 570,
    "preview": "package com.xcs.spring;\n\nimport org.aopalliance.intercept.MethodInterceptor;\nimport org.aopalliance.intercept.MethodInvo"
  },
  {
    "path": "spring-aop/spring-aop-aopProxy/src/main/java/com/xcs/spring/MyService.java",
    "chars": 72,
    "preview": "package com.xcs.spring;\n\npublic interface MyService {\n    void foo();\n}\n"
  },
  {
    "path": "spring-aop/spring-aop-aopProxy/src/main/java/com/xcs/spring/MyServiceImpl.java",
    "chars": 160,
    "preview": "package com.xcs.spring;\n\npublic class MyServiceImpl implements MyService {\n\n    @Override\n    public void foo() {\n      "
  },
  {
    "path": "spring-aop/spring-aop-aopProxyFactory/README.md",
    "chars": 6652,
    "preview": "## AopProxyFactory\n- [AopProxyFactory](#aopproxyfactory)\n    - [一、基本信息](#一基本信息)\n    - [二、基本描述](#二基本描述)\n    - [三、主要功能](#三"
  },
  {
    "path": "spring-aop/spring-aop-aopProxyFactory/pom.xml",
    "chars": 524,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n         xmlns:xsi=\"http://www"
  },
  {
    "path": "spring-aop/spring-aop-aopProxyFactory/src/main/java/com/xcs/spring/AopProxyFactoryDemo.java",
    "chars": 1616,
    "preview": "package com.xcs.spring;\n\nimport org.springframework.aop.framework.AdvisedSupport;\nimport org.springframework.aop.framewo"
  },
  {
    "path": "spring-aop/spring-aop-aopProxyFactory/src/main/java/com/xcs/spring/MyService.java",
    "chars": 84,
    "preview": "package com.xcs.spring;\n\npublic interface MyService {\n\n    String doSomething();\n\n}\n"
  },
  {
    "path": "spring-aop/spring-aop-aopProxyFactory/src/main/java/com/xcs/spring/MyServiceImpl.java",
    "chars": 162,
    "preview": "package com.xcs.spring;\n\npublic class MyServiceImpl implements MyService {\n\n    @Override\n    public String doSomething("
  },
  {
    "path": "spring-aop/spring-aop-aspectInstanceFactory/README.md",
    "chars": 12491,
    "preview": "## AspectInstanceFactory\n\n- [AspectInstanceFactory](#aspectinstancefactory)\n  - [一、基本信息](#一基本信息)\n  - [二、基本描述](#二基本描述)\n  "
  },
  {
    "path": "spring-aop/spring-aop-aspectInstanceFactory/pom.xml",
    "chars": 530,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n         xmlns:xsi=\"http://www"
  },
  {
    "path": "spring-aop/spring-aop-aspectInstanceFactory/src/main/java/com/xcs/spring/AspectInstanceFactoryDemo.java",
    "chars": 2491,
    "preview": "package com.xcs.spring;\n\nimport org.springframework.aop.aspectj.SimpleAspectInstanceFactory;\nimport org.springframework."
  },
  {
    "path": "spring-aop/spring-aop-aspectInstanceFactory/src/main/java/com/xcs/spring/MyAspect.java",
    "chars": 97,
    "preview": "package com.xcs.spring;\n\nimport org.aspectj.lang.annotation.Aspect;\n\n@Aspect\nclass MyAspect {\n\n}\n"
  },
  {
    "path": "spring-aop/spring-aop-aspectJAdvisorFactory/README.md",
    "chars": 19515,
    "preview": "## AspectJAdvisorFactory\n\n- [AspectJAdvisorFactory](#aspectjadvisorfactory)\n    - [一、基本信息](#一基本信息)\n    - [二、基本描述](#二基本描述"
  },
  {
    "path": "spring-aop/spring-aop-aspectJAdvisorFactory/pom.xml",
    "chars": 530,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n         xmlns:xsi=\"http://www"
  },
  {
    "path": "spring-aop/spring-aop-aspectJAdvisorFactory/src/main/java/com/xcs/spring/AspectJAdvisorFactoryDemo.java",
    "chars": 1269,
    "preview": "package com.xcs.spring;\n\nimport org.springframework.aop.Advisor;\nimport org.springframework.aop.aspectj.annotation.BeanF"
  },
  {
    "path": "spring-aop/spring-aop-aspectJAdvisorFactory/src/main/java/com/xcs/spring/MyAspect.java",
    "chars": 494,
    "preview": "package com.xcs.spring;\n\nimport org.aspectj.lang.annotation.After;\nimport org.aspectj.lang.annotation.Aspect;\nimport org"
  },
  {
    "path": "spring-aop/spring-aop-aspectJAdvisorFactory/src/main/java/com/xcs/spring/MyService.java",
    "chars": 120,
    "preview": "package com.xcs.spring;\n\npublic class MyService {\n    public void foo() {\n        System.out.println(\"foo...\");\n    }\n}\n"
  },
  {
    "path": "spring-aop/spring-aop-beanFactoryAdvisorRetrievalHelper/README.md",
    "chars": 7191,
    "preview": "## BeanFactoryAdvisorRetrievalHelper\n\n- [BeanFactoryAdvisorRetrievalHelper](#beanfactoryadvisorretrievalhelper)\n  - [一、基"
  },
  {
    "path": "spring-aop/spring-aop-beanFactoryAdvisorRetrievalHelper/pom.xml",
    "chars": 542,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n         xmlns:xsi=\"http://www"
  },
  {
    "path": "spring-aop/spring-aop-beanFactoryAdvisorRetrievalHelper/src/main/java/com/xcs/spring/AppConfig.java",
    "chars": 300,
    "preview": "package com.xcs.spring;\n\nimport org.springframework.context.annotation.ComponentScan;\nimport org.springframework.context"
  },
  {
    "path": "spring-aop/spring-aop-beanFactoryAdvisorRetrievalHelper/src/main/java/com/xcs/spring/BeanFactoryAdvisorRetrievalHelperDemo.java",
    "chars": 499,
    "preview": "package com.xcs.spring;\n\nimport org.springframework.context.annotation.AnnotationConfigApplicationContext;\n\npublic class"
  },
  {
    "path": "spring-aop/spring-aop-beanFactoryAdvisorRetrievalHelper/src/main/java/com/xcs/spring/MyAdvice.java",
    "chars": 329,
    "preview": "package com.xcs.spring;\n\nimport org.springframework.aop.MethodBeforeAdvice;\n\nimport java.lang.reflect.Method;\n\npublic cl"
  },
  {
    "path": "spring-aop/spring-aop-beanFactoryAdvisorRetrievalHelper/src/main/java/com/xcs/spring/MyAdvisor.java",
    "chars": 456,
    "preview": "package com.xcs.spring;\n\nimport org.aopalliance.aop.Advice;\nimport org.springframework.aop.Pointcut;\nimport org.springfr"
  },
  {
    "path": "spring-aop/spring-aop-beanFactoryAdvisorRetrievalHelper/src/main/java/com/xcs/spring/MyService.java",
    "chars": 178,
    "preview": "package com.xcs.spring;\n\nimport org.springframework.stereotype.Service;\n\n@Service\npublic class MyService {\n\n    public v"
  },
  {
    "path": "spring-aop/spring-aop-beanFactoryAspectJAdvisorsBuilder/README.md",
    "chars": 9373,
    "preview": "## BeanFactoryAspectJAdvisorsBuilder\n\n- [BeanFactoryAspectJAdvisorsBuilder](#beanfactoryaspectjadvisorsbuilder)\n  - [一、基"
  },
  {
    "path": "spring-aop/spring-aop-beanFactoryAspectJAdvisorsBuilder/pom.xml",
    "chars": 769,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n         xmlns:xsi=\"http://www"
  },
  {
    "path": "spring-aop/spring-aop-beanFactoryAspectJAdvisorsBuilder/src/main/java/com/xcs/spring/AppConfig.java",
    "chars": 300,
    "preview": "package com.xcs.spring;\n\nimport org.springframework.context.annotation.ComponentScan;\nimport org.springframework.context"
  },
  {
    "path": "spring-aop/spring-aop-beanFactoryAspectJAdvisorsBuilder/src/main/java/com/xcs/spring/BeanFactoryAspectJAdvisorsBuilderDemo.java",
    "chars": 499,
    "preview": "package com.xcs.spring;\n\nimport org.springframework.context.annotation.AnnotationConfigApplicationContext;\n\npublic class"
  },
  {
    "path": "spring-aop/spring-aop-beanFactoryAspectJAdvisorsBuilder/src/main/java/com/xcs/spring/MyAspect.java",
    "chars": 349,
    "preview": "package com.xcs.spring;\n\nimport org.aspectj.lang.annotation.Aspect;\nimport org.aspectj.lang.annotation.Before;\nimport or"
  },
  {
    "path": "spring-aop/spring-aop-beanFactoryAspectJAdvisorsBuilder/src/main/java/com/xcs/spring/MyService.java",
    "chars": 177,
    "preview": "package com.xcs.spring;\n\nimport org.springframework.stereotype.Service;\n\n@Service\npublic class MyService {\n    public vo"
  },
  {
    "path": "spring-aop/spring-aop-cglibProxy/README.md",
    "chars": 6940,
    "preview": "## Cglib动态代理\n\n- [Cglib动态代理](#cglib动态代理)\n  - [一、基本信息](#一基本信息)\n  - [二、基本描述](#二基本描述)\n  - [三、主要功能](#三主要功能)\n  - [四、最佳实践](#四最佳"
  },
  {
    "path": "spring-aop/spring-aop-cglibProxy/pom.xml",
    "chars": 519,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n         xmlns:xsi=\"http://www"
  },
  {
    "path": "spring-aop/spring-aop-cglibProxy/src/main/java/com/xcs/spring/CglibProxyDemo.java",
    "chars": 616,
    "preview": "package com.xcs.spring;\n\nimport org.springframework.cglib.proxy.Enhancer;\n\npublic class CglibProxyDemo {\n\n    public sta"
  },
  {
    "path": "spring-aop/spring-aop-cglibProxy/src/main/java/com/xcs/spring/MyMethodInterceptor.java",
    "chars": 602,
    "preview": "package com.xcs.spring;\n\nimport org.springframework.cglib.proxy.MethodInterceptor;\nimport org.springframework.cglib.prox"
  },
  {
    "path": "spring-aop/spring-aop-cglibProxy/src/main/java/com/xcs/spring/MyService.java",
    "chars": 80,
    "preview": "package com.xcs.spring;\n\npublic interface MyService {\n    void doSomething();\n}\n"
  },
  {
    "path": "spring-aop/spring-aop-cglibProxy/src/main/java/com/xcs/spring/MyServiceImpl.java",
    "chars": 173,
    "preview": "package com.xcs.spring;\n\npublic class MyServiceImpl implements MyService {\n\n    @Override\n    public void doSomething() "
  },
  {
    "path": "spring-aop/spring-aop-classFilter/README.md",
    "chars": 3983,
    "preview": "## ClassFilter\n\n- [ClassFilter](#classfilter)\n  - [一、基本信息](#一基本信息)\n  - [二、基本描述](#二基本描述)\n  - [三、主要功能](#三主要功能)\n  - [四、接口源码"
  },
  {
    "path": "spring-aop/spring-aop-classFilter/pom.xml",
    "chars": 520,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n         xmlns:xsi=\"http://www"
  },
  {
    "path": "spring-aop/spring-aop-classFilter/src/main/java/com/xcs/spring/ClassFilterDemo.java",
    "chars": 1547,
    "preview": "package com.xcs.spring;\n\nimport org.springframework.aop.ClassFilter;\nimport org.springframework.aop.aspectj.AspectJExpre"
  },
  {
    "path": "spring-aop/spring-aop-classFilter/src/main/java/com/xcs/spring/MyClassAnnotation.java",
    "chars": 289,
    "preview": "package com.xcs.spring;\n\nimport java.lang.annotation.ElementType;\nimport java.lang.annotation.Retention;\nimport java.lan"
  },
  {
    "path": "spring-aop/spring-aop-classFilter/src/main/java/com/xcs/spring/MyService.java",
    "chars": 71,
    "preview": "package com.xcs.spring;\n\n@MyClassAnnotation\npublic class MyService {\n}\n"
  }
]

// ... and 574 more files (download for full content)

About this extraction

This page contains the full source code of the xuchengsheng/spring-reading GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 774 files (2.3 MB), approximately 645.7k tokens, and a symbol index with 968 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!