首页 > 正文

Spring源码领会(扫描bean)尝试用例代码块//AppConfig.java类@ComponentScan({"com.llsydn"})@Configurationpublic class AppConfig { @Bean public ConfigDao1 configDao1(){ //本人写一个configDao1类即可 return new ConfigDao1(); } @Bean public ConfigDao2 configDao2(){ //本人写一个configDao2类即可 configDao1(); return new ConfigDao2(); }}//IndexDao.java类@Componentpublic class IndexDao { public void query(){ System.out.println("query"); }}//Test.java类public static void main(String[] args) { AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(); ac.register(AppConfig.class); ac.refresh(); IndexDao indexDao = ac.getBean(IndexDao.class); System.out.println(indexDao); indexDao.query();}这边我是径直用AnnotationConfigApplicationContext类初始化spring的情况,这个类是鉴于证明摆设运用左右文(即是用证明的办法初始化一个spring容器)Spring顶用来证明Bean设置的类有两个:AnnotationConfigApplicationContext和AnnotationConfigWebApplicationContex。AnnotationConfigWebApplicationContext是AnnotationConfigApplicationContext的web本子两者的用法以及对证明的处置办法简直没有什么分辨经过领会这个类咱们领会备案一个bean到spring容器有两种方法:一、径直将证明Bean备案到容器中:(参考)public void register(Class<?>… annotatedClasses)然而径直把一个证明的bean备案到容器傍边也分为两种本领1、在初始化容器时备案而且领会2、也不妨在容器创造之背工动挪用备案本领向容器备案,而后经过手动革新容器,使得容器对备案的证明Bean举行处置。二、经过扫描指定的包及其子包下的一切类扫描本来同上,也是两种本领,初始化的功夫扫描,和初始化之后再扫描底下加入spring容器初始化源码领会(1) AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext();public class AnnotationConfigApplicationContext extends GenericApplicationContext/*** 这个类望文生义是一个reader,一个读取器 * 读取什么呢?仍旧望文生义AnnotatedBeanDefinition道理是读取一个被加了证明的bean * 这个类在结构本领中范例化的 */private final AnnotatedBeanDefinitionReader reader;/** * 承诺望文生义,这是一个扫描器,扫描一切加了证明的bean * 同样是在结构本领中被范例化的 */private final ClassPathBeanDefinitionScanner scanner;/** * 初始化一个bean的读取和扫描器 * 何谓读取器和扫描器参考上头的属性解释 * 默许结构因变量,即使径直挪用这个默许结构本领,须要在稍后经过挪用其register() * 去备案摆设类(javaconfig),并挪用refresh()本领革新容器, * 触发容器对证明Bean的载入、领会和备案进程 */public AnnotationConfigApplicationContext() { /** * 父类的结构本领 * 创造一个读取证明的Bean设置读取器 * 什么是bean设置?BeanDefinition */ this.reader = new AnnotatedBeanDefinitionReader(this); //不妨用来扫描包大概类,既而变换成bd //然而本质上咱们扫描包处事不是scanner这个东西来实行的 //是spring本人new的一个ClassPathBeanDefinitionScanner //这边的scanner只是是为了步调员不妨在外部挪用AnnotationConfigApplicationContext东西的scan本领 this.scanner = new ClassPathBeanDefinitionScanner(this);}这边创造一个AnnotationConfigApplicationContext东西,主假如做了3个重要的操纵。 1.创造一个new DefaultListableBeanFactory() 是一个Bean工场容器 2.创造一个new AnnotatedBeanDefinitionReader(this),是Bean的读取器 3.创造一个new ClassPathBeanDefinitionScanner(this),是Bean的扫描器

干什么这边会创造一个DefaultListableBeanFactory()范例的beanFactory? 1.这个beanFactory主假如用来寄存Spring处置的Bean东西,一个Bean寄存的工场。 2.如何会挪用了这步new DefaultListableBeanFactory()?

由于AnnotationConfigApplicationContext接受了GenericApplicationContext,即在创造AnnotationConfigApplicationContext东西,会先实行父类GenericApplicationContext的结构本领。以是这边是在父类的结构本领中,实行了new DefaultListableBeanFactory()创造了一个beanFactory东西。 public GenericApplicationContext() { this.beanFactory = new DefaultListableBeanFactory(); }

AnnotationConfigApplicationContext 接受了GenericApplicationContext GenericApplicationContext 实行了 BeanDefinitionRegistry

即有:AnnotationConfigApplicationContext 也实行了BeanDefinitionRegistry,AnnotationConfigApplicationContext 也是一个registry类。这个registry比拟要害,registry有registerBeanDefinition(备案一个bean设置到bean工场)、getBeanDefinition(从bean工场获得一个Bean设置)等功效。以是AnnotationConfigApplicationContext 也是有不妨往bean工场中备案bean的本领。

//创造一个bean读取器进程领会:this.reader = new AnnotatedBeanDefinitionReader(this);public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) { this(registry, getOrCreateEnvironment(registry));}public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) { this.registry = registry; //将registry赋值 this.conditionEvaluator = new ConditionEvaluator(registry, environment, null); AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);}public static void registerAnnotationConfigProcessors(BeanDefinitionRegistry registry) { //重要本领 registerAnnotationConfigProcessors(registry, null);}public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(BeanDefinitionRegistry registry, @Nullable Object source) { //获得到刚创造完的DefaultListableBeanFactory东西,而后给这个东西的某些属性赋值。 DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry); if (beanFactory != null) { if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) { //AnnotationAwareOrderComparator重要能领会@Order证明和@Priority beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE); } if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) { //ContextAnnotationAutowireCandidateResolver供给处置推迟加载的功效 beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver()); } } //给Spring容器增添Spring里面的特出Bean东西(7个) //1.往BeanDefinitionMap备案一个ConfigurationClassPostProcessor Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8); //BeanDefinitio的备案,这边很要害,须要领会备案每个bean的典型 if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) { //须要提防的是ConfigurationClassPostProcessor的典型是BeanDefinitionRegistryPostProcessor //而 BeanDefinitionRegistryPostProcessor 最后实行BeanFactoryPostProcessor这个接口 RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class); def.setSource(source); beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)); } //2.往BeanDefinitionMap备案一个AutowiredAnnotationBeanPostProcessor if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) { //AutowiredAnnotationBeanPostProcessor 实行了 MergedBeanDefinitionPostProcessor //MergedBeanDefinitionPostProcessor 最后实行了 BeanPostProcessor RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class); def.setSource(source); beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)); } //3.往BeanDefinitionMap备案一个RequiredAnnotationBeanPostProcessor if (!registry.containsBeanDefinition(REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) { RootBeanDefinition def = new RootBeanDefinition(RequiredAnnotationBeanPostProcessor.class); def.setSource(source); beanDefs.add(registerPostProcessor(registry, def, REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME)); } //4.往BeanDefinitionMap备案一个CommonAnnotationBeanPostProcessor // Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor. if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) { RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class); def.setSource(source); beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)); } //5.往BeanDefinitionMap备案一个PersistenceAnnotationBeanPostProcessor // Check for JPA support, and if present add the PersistenceAnnotationBeanPostProcessor. if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) { RootBeanDefinition def = new RootBeanDefinition(); try { def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, AnnotationConfigUtils.class.getClassLoader())); } catch (ClassNotFoundException ex) { throw new IllegalStateException( "Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex); } def.setSource(source); beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)); } //6.往BeanDefinitionMap备案一个EventListenerMethodProcessor if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) { RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class); def.setSource(source); beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME)); } //7.往BeanDefinitionMap备案一个DefaultEventListenerFactory if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) { RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class); def.setSource(source); beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME)); } return beanDefs;}//将**Processor典型的东西,备案到bean工场中private static BeanDefinitionHolder registerPostProcessor(BeanDefinitionRegistry registry, RootBeanDefinition definition, String beanName) { definition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); //这边重要的代码,将bean设置备案到bean工场傍边 registry.registerBeanDefinition(beanName, definition); return new BeanDefinitionHolder(definition, beanName);}复制代码这边创造一个AnnotatedBeanDefinitionReader东西,主假如做了2个重要的操纵: 1.给在GenericApplicationContext()刚创造的beanFactory东西的某些属性赋值:

beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);(重要能领会@Order证明和@Priority) beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());(供给处置推迟加载的功效)

2.往bean工场中备案6个spring里面东西,主假如**BeanPostProcessor典型的东西。(Spring的扩充点之一)

这边更加要害的类是ConfigurationClassPostProcessor,这个类实行bean的扫描。

(2)ac.register(AppConfig.class);/** * 备案单个bean给容器 * 比方有新加的类不妨用这个本领 * 然而备案之后须要手动挪用refresh本领去触发容器领会证明 * * 有两个道理: * 他不妨备案一个摆设类 * 他还不妨独立备案一个bean */public void register(Class<?>… annotatedClasses) { this.reader.register(annotatedClasses);}public void register(Class<?>… annotatedClasses) { for (Class<?> annotatedClass : annotatedClasses) { registerBean(annotatedClass); }}public void registerBean(Class<?> annotatedClass) { //真实的备案bean的本领 doRegisterBean(annotatedClass, null, null, null);}<T> void doRegisterBean(Class<T> annotatedClass, @Nullable Supplier<T> instanceSupplier, @Nullable String name, @Nullable Class<? extends Annotation>[] qualifiers, BeanDefinitionCustomizer… definitionCustomizers) { /** * 按照指定的bean创造一个AnnotatedGenericBeanDefinition * 这个AnnotatedGenericBeanDefinition不妨领会为一个数据构造 * AnnotatedGenericBeanDefinition包括了类的其余消息,比方少许元消息:scope,lazy之类 */ AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(annotatedClass); /** * 确定这个类能否须要跳过领会 * 经过代码不妨领会spring确定能否跳过领会,重要确定类有没有加证明 */ if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) { return; } //不领会 abd.setInstanceSupplier(instanceSupplier); /** * 获得类的效率域 */ ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd); /** * 把类的效率域增添到数据构造构造中 */ abd.setScope(scopeMetadata.getScopeName()); /** * 天生类的名字经过beanNameGenerator */ String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry)); /** * 处置类傍边的通用证明 * 领会源码不妨领会他重要处置 * Lazy DependsOn Primary Role之类证明 * 处置实行之后processCommonDefinitionAnnotations中仍旧是把他增添到数据构造傍边 */ AnnotationConfigUtils.processCommonDefinitionAnnotations(abd); /** * 即使在向容器备案证明Bean设置时,运用了特殊的控制符证明则领会 * 对于Qualifier和Primary前方的课傍边讲过,重要波及到spring的机动安装 * 这边须要提防的 * byName和qualifiers这个变量是Annotation典型的数组,内里存不只仅是Qualifier证明 * 表面上内里内里存的是十足证明,以是不妨看到底下的代码spring去轮回了这个数组 * 而后顺序确定了证明傍边能否包括了Primary,能否包括了Lazyd */ if (qualifiers != null) { for (Class<? extends Annotation> qualifier : qualifiers) { ////即使摆设了@Primary证明,即使加了则动作首要选择 if (Primary.class == qualifier) { abd.setPrimary(true); } //懒加载,前方加过 else if (Lazy.class == qualifier) { abd.setLazyInit(true); } else { //即使运用了除@Primary和@Lazy除外的其余证明,则为该Bean增添一个按照名字机动安装的控制符 //这边难以领会,反面会精细引见 abd.addQualifier(new AutowireCandidateQualifier(qualifier)); } } } for (BeanDefinitionCustomizer customizer : definitionCustomizers) { customizer.customize(abd); } /** * 这个BeanDefinitionHolder也是一个数据构造(beanName,beanDefinition,aliases[]) */ BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName); /** * ScopedProxyMode 这个常识点比拟搀杂,须要贯串web去领会 */ definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry); /** * 把上述的这个数据构造备案给registry * registy即是AnnotatonConfigApplicationContext * AnnotatonConfigApplicationContext在初始化的時候经过挪用父类的结构本领 * 范例化了一个DefaultListableBeanFactory * *registerBeanDefinition内里即是把definitionHolder这个数据构造包括的消息备案到 * DefaultListableBeanFactory这个工场 */ BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);}//将beanDefinition备案到bean工场中public static void registerBeanDefinition(BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)throws BeanDefinitionStoreException{ String beanName = definitionHolder.getBeanName(); registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition()); String[] aliases = definitionHolder.getAliases(); if (aliases != null) { for (String alias : aliases) { registry.registerAlias(beanName, alias); } }}//DefaultListableBeanFactorypublic void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) throws BeanDefinitionStoreException { //重要代码: this.beanDefinitionMap.put(beanName, beanDefinition); this.beanDefinitionNames.add(beanName); this.manualSingletonNames.remove(beanName);}复制代码ac.register(AppConfig.class);的重要效率是将AppConfig类备案到bean工场中。 即是到暂时为止,bean工场中仍旧有了7个beanDefinition。

demo

(3)ac.refresh(); 这边最要害的一步,实行bean的扫描和初始化阶段public void refresh() throws BeansException, IllegalStateException { synchronized (this.startupShutdownMonitor) { //筹备处事囊括树立启用功夫,能否激活标识位, // 初始化属性源(property source)摆设 prepareRefresh(); //归来一个factory 干什么须要归来一个工场 //由于要对工场举行初始化 ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); //筹备工场 prepareBeanFactory(beanFactory); try { //这个本领在暂时本子的spring是没用任何代码的 //大概spring憧憬在反面的本子中去扩充吧 postProcessBeanFactory(beanFactory); //在spring的情况中去实行仍旧被备案的 factoryBean processors //树立实行自设置的ProcessBeanFactory 和spring里面本人设置的 (要害,实行bean的扫描等) invokeBeanFactoryPostProcessors(beanFactory); //备案beanPostProcessor registerBeanPostProcessors(beanFactory); initMessageSource(); //初始化运用事变播送器 initApplicationEventMulticaster(); // Initialize other special beans in specific context subclasses. onRefresh(); // Check for listener beans and register them. registerListeners(); //范例化单列的bean东西(要害) finishBeanFactoryInitialization(beanFactory); // Last step: publish corresponding event. finishRefresh(); } catch (BeansException ex) { throw ex; } }}复制代码prepareRefreshprotected void prepareRefresh() { this.startupDate = System.currentTimeMillis(); this.closed.set(false); this.active.set(true); if (logger.isInfoEnabled()) { logger.info("Refreshing " + this); } // Initialize any placeholder property sources in the context environment //这个本领暂时没有子类去实行 //估量spring是憧憬反面的本子有子类去实行吧 initPropertySources(); // Validate that all properties marked as required are resolvable // see ConfigurablePropertyResolver#setRequiredProperties getEnvironment().validateRequiredProperties(); // Allow for the collection of early ApplicationEvents, // to be published once the multicaster is available… this.earlyApplicationEvents = new LinkedHashSet<>();}复制代码obtainFreshBeanFactoryprotected ConfigurableListableBeanFactory obtainFreshBeanFactory() { refreshBeanFactory(); ConfigurableListableBeanFactory beanFactory = getBeanFactory(); if (logger.isDebugEnabled()) { logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory); } return beanFactory;}//GenericApplicationContext@Overridepublic final ConfigurableListableBeanFactory getBeanFactory() { return this.beanFactory;}复制代码prepareBeanFactory/** * 摆设其规范的特性,比方左右文的加载器ClassLoader和post-processors回调 * 此处的beanFactory参数即是DefaultListableFactory */protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) { // Tell the internal bean factory to use the context's class loader etc. beanFactory.setBeanClassLoader(getClassLoader()); //bean表白式证明器,不妨获得bean傍边的属性在前台页面 beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader())); //东西与string典型的变换 <property red="dao"> beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment())); //增添一个后置处置器 //ApplicationContextAwareProcessor 不妨在bean中获获得百般*Aware(*Aware都有其效率) beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this)); //道理即是:使得ApplicationContextAware接话柄现类在机动安装时不许被注入applicationContext东西的依附。 //(不许运用xml的set本领或结构办法注入,然而不妨用@Autowired注入) beanFactory.ignoreDependencyInterface(EnvironmentAware.class); beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class); beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class); beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class); beanFactory.ignoreDependencyInterface(MessageSourceAware.class); beanFactory.ignoreDependencyInterface(ApplicationContextAware.class); // BeanFactory interface not registered as resolvable type in a plain factory. // MessageSource registered (and found for autowiring) as a bean. beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory); beanFactory.registerResolvableDependency(ResourceLoader.class, this); beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this); beanFactory.registerResolvableDependency(ApplicationContext.class, this); // Register early post-processor for detecting inner beans as ApplicationListeners. beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this)); // Detect a LoadTimeWeaver and prepare for weaving, if found. if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) { beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory)); // Set a temporary ClassLoader for type matching. beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader())); } //道理是即使自设置的Bean中没驰名为"systemProperties"和"systemEnvironment"的Bean, // 则备案两个Bena,Key为"systemProperties"和"systemEnvironment",Value为Map, // 这两个Bean即是少许体例摆设和体例情况消息 if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) { //径直往beanFactory工场中增添bean东西(该东西仍旧被new出来的) beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment()); } if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) { beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties()); } if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) { beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment()); }}public void registerSingleton(String beanName, Object singletonObject) throws IllegalStateException { synchronized (this.singletonObjects) { Object oldObject = this.singletonObjects.get(beanName); if (oldObject != null) { throw new IllegalStateException(); } addSingleton(beanName, singletonObject); }}//往singletonObjects东西中增添bean范例protected void addSingleton(String beanName, Object singletonObject) { synchronized (this.singletonObjects) { this.singletonObjects.put(beanName, singletonObject); this.singletonFactories.remove(beanName); this.earlySingletonObjects.remove(beanName); this.registeredSingletons.add(beanName); }}复制代码prepareBeanFactory本领的重要效率: 1.给beanFactory的某些属性赋值。 2.给beanFactory增添BeanPostProcessor:ApplicationContextAwareProcessor(不妨干涉bean的初始化,扩充点之一) 3.给beanFactory增添体例摆设和体例情况消息等范例。

invokeBeanFactoryPostProcessorsprotected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) { //这个场合须要提防getBeanFactoryPostProcessors()是获得手动给spring的BeanFactoryPostProcessor //自设置并不只仅是步调员本人写的 //本人写的不妨加companent也不妨不加 //即使加了getBeanFactoryPostProcessors()这个场合得不得,是spring本人扫描的 //干什么得不到getBeanFactoryPostProcessors()这个本领是径直获得一个list, //这个list是在AnnotationConfigApplicationContext被设置 //所谓的自设置的即是你手动挪用AnnotationConfigApplicationContext.addBeanFactoryPostProcesor(); PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());}public static void invokeBeanFactoryPostProcessors( ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) { Set<String> processedBeans = new HashSet<>(); if (beanFactory instanceof BeanDefinitionRegistry) { BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory; //设置了两个list寄存 List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>(); List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>(); //自设置的beanFactoryPostProcessors for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) { if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) { BeanDefinitionRegistryPostProcessor registryProcessor = (BeanDefinitionRegistryPostProcessor) postProcessor; registryProcessor.postProcessBeanDefinitionRegistry(registry); registryProcessors.add(registryProcessor); }else { regularPostProcessors.add(postProcessor); } } //这个currentRegistryProcessors 放的是spring里面本人实行了BeanDefinitionRegistryPostProcessor接口的东西 List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>(); //BeanDefinitionRegistryPostProcessor 即是 BeanFactoryPostProcessor //getBeanNamesForType 按照bean的典型获得bean的名字ConfigurationClassPostProcessor String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false); //这个场合不妨获得一个BeanFactoryPostProcessor,由于是spring默许在最发端本人备案的 //干什么要在最发端备案这个呢? //由于spring的工场须要许领会去扫描之类功效 //而那些功效都是须要在spring工场初始化实行之前实行 //要么在工场最发端的功夫、要么在工场初始化之中,归正不许再之后 //由于即使在之后就没有意旨,由于谁人功夫仍旧须要运用工场了 //以是这边spring'在一发端就备案了一个BeanFactoryPostProcessor,用来干涉springfactory的范例化进程 //在这个场合断点不妨领会这个类叫作ConfigurationClassPostProcessor //ConfigurationClassPostProcessor那么这个类才干嘛呢?不妨参考源码 //底下咱们对这个牛逼哄哄的类(他能干涉spring工场的范例化进程还不牛逼吗?)中心证明 for (String ppName : postProcessorNames) { if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) { currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class)); processedBeans.add(ppName); } } //排序不要害,而且currentRegistryProcessors这边也惟有一个数据 sortPostProcessors(currentRegistryProcessors, beanFactory); //兼并list,不要害(干什么要兼并,由于再有本人的) registryProcessors.addAll(currentRegistryProcessors); //最要害。提防这边是本领挪用 //实行一切BeanDefinitionRegistryPostProcessor(发端实行扫描包) invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry); //实行实行了一切BeanDefinitionRegistryPostProcessor //这个list不过一个偶尔变量,故而要废除 currentRegistryProcessors.clear(); postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false); for (String ppName : postProcessorNames) { if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) { currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class)); processedBeans.add(ppName); } } sortPostProcessors(currentRegistryProcessors, beanFactory); registryProcessors.addAll(currentRegistryProcessors); invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry); currentRegistryProcessors.clear(); // Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear. boolean reiterate = true; while (reiterate) { reiterate = false; postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false); for (String ppName : postProcessorNames) { if (!processedBeans.contains(ppName)) { currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class)); processedBeans.add(ppName); reiterate = true; } } sortPostProcessors(currentRegistryProcessors, beanFactory); registryProcessors.addAll(currentRegistryProcessors); invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry); currentRegistryProcessors.clear(); } // Now, invoke the postProcessBeanFactory callback of all processors handled so far. //实行BeanFactoryPostProcessor的回调,前方不是吗? //前方实行的BeanFactoryPostProcessor的子类BeanDefinitionRegistryPostProcessor的回调 //这是实行的是BeanFactoryPostProcessor postProcessBeanFactory //ConfuguratuonClassPpostProcssor invokeBeanFactoryPostProcessors(registryProcessors, beanFactory); //自设置BeanFactoryPostProcessor invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory); } else { // Invoke factory processors registered with the context instance. invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory); } // 这边干什么要再反复实行一遍? // 由于过程上头的ConfuguratuonClassPpostProcssor对bean的扫描,扫描到的bean东西有大概是实行了BeanFactoryPostProcessor接口的,以是要这那些扫描处置的bena举行再一步处置 // Do not initialize FactoryBeans here: We need to leave all regular beans // uninitialized to let the bean factory post-processors apply to them! //ConfigurationClassPostProcessor String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false); // Separate between BeanFactoryPostProcessors that implement PriorityOrdered, // Ordered, and the rest. List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>(); List<String> orderedPostProcessorNames = new ArrayList<>(); List<String> nonOrderedPostProcessorNames = new ArrayList<>(); for (String ppName : postProcessorNames) { if (processedBeans.contains(ppName)) { // skip – already processed in first phase above } else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) { priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class)); } else if (beanFactory.isTypeMatch(ppName, Ordered.class)) { orderedPostProcessorNames.add(ppName); } else { nonOrderedPostProcessorNames.add(ppName); } } // First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered. sortPostProcessors(priorityOrderedPostProcessors, beanFactory); invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory); // Next, invoke the BeanFactoryPostProcessors that implement Ordered. List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(); for (String postProcessorName : orderedPostProcessorNames) { orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class)); } sortPostProcessors(orderedPostProcessors, beanFactory); invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory); // Finally, invoke all other BeanFactoryPostProcessors. List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(); for (String postProcessorName : nonOrderedPostProcessorNames) { nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class)); } invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory); // Clear cached merged bean definitions since the post-processors might have // modified the original metadata, e.g. replacing placeholders in values… beanFactory.clearMetadataCache();}private static void invokeBeanDefinitionRegistryPostProcessors( Collection<? extends BeanDefinitionRegistryPostProcessor> postProcessors, BeanDefinitionRegistry registry) { //由于惟有一条数据:ConfigurationClassPostProcessor for (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) { postProcessor.postProcessBeanDefinitionRegistry(registry); }}//ConfigurationClassPostProcessor@Overridepublic void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) { int registryId = System.identityHashCode(registry); if (this.registriesPostProcessed.contains(registryId)) { throw new IllegalStateException(); } if (this.factoriesPostProcessed.contains(registryId)) { throw new IllegalStateException(); } this.registriesPostProcessed.add(registryId); //实行 processConfigBeanDefinitions(registry);}public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) { //设置一个list寄存app 供给的bd(名目傍边供给了@Compent) List<BeanDefinitionHolder> configCandidates = new ArrayList<>(); //获得容器中备案的一切bd名字 //7个 String[] candidateNames = registry.getBeanDefinitionNames(); /** * Full , Lite */ for (String beanName : candidateNames) { BeanDefinition beanDef = registry.getBeanDefinition(beanName); if (ConfigurationClassUtils.isFullConfigurationClass(beanDef) || ConfigurationClassUtils.isLiteConfigurationClass(beanDef)) { //果BeanDefinition中的configurationClass属性为full大概lite,则表示着仍旧处置过了,径直跳过 //这边须要贯串底下的代码本领领会 if (logger.isDebugEnabled()) { logger.debug("Bean definition has already been processed as a configuration class: " + beanDef); } } //确定能否是Configuration类,即使加了Configuration底下的这几个证明就不复确定了 // 再有 add(Component.class.getName()); // candidateIndicators.add(ComponentScan.class.getName()); // candidateIndicators.add(Import.class.getName()); // candidateIndicators.add(ImportResource.class.getName()); //beanDef == appconfig else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) { //BeanDefinitionHolder 也不妨看成一个数据构造 configCandidates.add(new BeanDefinitionHolder(beanDef, beanName)); } } // 排序,按照order,不要害 // Sort by previously determined @Order value, if applicable configCandidates.sort((bd1, bd2) -> { int i1 = ConfigurationClassUtils.getOrder(bd1.getBeanDefinition()); int i2 = ConfigurationClassUtils.getOrder(bd2.getBeanDefinition()); return Integer.compare(i1, i2); }); SingletonBeanRegistry sbr = null; //即使BeanDefinitionRegistry是SingletonBeanRegistry子类的话, // 因为咱们暂时传入的是DefaultListableBeanFactory,是SingletonBeanRegistry 的子类 // 所以会将registry强转为SingletonBeanRegistry if (registry instanceof SingletonBeanRegistry) { sbr = (SingletonBeanRegistry) registry; if (!this.localBeanNameGeneratorSet) { //能否有自设置的 BeanNameGenerator generator = (BeanNameGenerator) sbr.getSingleton(CONFIGURATION_BEAN_NAME_GENERATOR); //SingletonBeanRegistry中有id为 org.springframework.context.annotation.internalConfigurationBeanNameGenerator //即使有则运用他的,要不则是spring默许的 if (generator != null) { this.componentScanBeanNameGenerator = generator; this.importBeanNameGenerator = generator; } } } //范例化ConfigurationClassParser 为领会析各个摆设类 ConfigurationClassParser parser = new ConfigurationClassParser( this.metadataReaderFactory, this.problemReporter, this.environment, this.resourceLoader, this.componentScanBeanNameGenerator, registry); //范例化2个set,candidates用来将之前介入的configCandidates举行去重 //由于大概有多个摆设类反复了 //alreadyParsed用来确定能否处置过 Set<BeanDefinitionHolder> candidates = new LinkedHashSet<>(configCandidates); Set<ConfigurationClass> alreadyParsed = new HashSet<>(configCandidates.size()); do { //很要害(扫描bean) parser.parse(candidates); parser.validate(); //map.keyset Set<ConfigurationClass> configClasses = new LinkedHashSet<>(parser.getConfigurationClasses()); configClasses.removeAll(alreadyParsed); // Read the model and create bean definitions based on its content if (this.reader == null) { this.reader = new ConfigurationClassBeanDefinitionReader( registry, this.sourceExtractor, this.resourceLoader, this.environment, this.importBeanNameGenerator, parser.getImportRegistry()); } /** * 这边犯得着提防的是扫描出来的bean傍边大概包括了特出类 * 比方ImportBeanDefinitionRegistrar那么也在这个本领内里处置 * 然而并不是包括在configClasses傍边 * configClasses傍边重要包括的是importSelector * 由于ImportBeanDefinitionRegistrar在扫描出来的功夫仍旧被增添到一个list傍边去了 */ //bd 到 map 除却普遍 (将import的bean备案到bean工场)(要害) this.reader.loadBeanDefinitions(configClasses); alreadyParsed.addAll(configClasses); candidates.clear(); //因为咱们这边举行了扫描,把扫描出来的BeanDefinition备案给了factory if (registry.getBeanDefinitionCount() > candidateNames.length) { String[] newCandidateNames = registry.getBeanDefinitionNames(); Set<String> oldCandidateNames = new HashSet<>(Arrays.asList(candidateNames)); Set<String> alreadyParsedClasses = new HashSet<>(); for (ConfigurationClass configurationClass : alreadyParsed) { alreadyParsedClasses.add(configurationClass.getMetadata().getClassName()); } for (String candidateName : newCandidateNames) { if (!oldCandidateNames.contains(candidateName)) { BeanDefinition bd = registry.getBeanDefinition(candidateName); if (ConfigurationClassUtils.checkConfigurationClassCandidate(bd, this.metadataReaderFactory) && !alreadyParsedClasses.contains(bd.getBeanClassName())) { candidates.add(new BeanDefinitionHolder(bd, candidateName)); } } } candidateNames = newCandidateNames; } }}//ConfigurationClassParserpublic void parse(Set<BeanDefinitionHolder> configCandidates) { this.deferredImportSelectors = new LinkedList<>(); //按照BeanDefinition 的典型 做各别的处置,普遍城市挪用ConfigurationClassParser#parse 举行领会 for (BeanDefinitionHolder holder : configCandidates) { BeanDefinition bd = holder.getBeanDefinition(); try { if (bd instanceof AnnotatedBeanDefinition) { //领会证明东西,而且把领会出来的bd放到map,然而这边的bd指的是普遍的 //何谓不普遍的呢?比方@Bean 和百般beanFactoryPostProcessor获得的bean不在这边put //然而是这边领会,不过不put罢了 parse(((AnnotatedBeanDefinition) bd).getMetadata(), holder.getBeanName()); } else if (bd instanceof AbstractBeanDefinition && ((AbstractBeanDefinition) bd).hasBeanClass()) { parse(((AbstractBeanDefinition) bd).getBeanClass(), holder.getBeanName()); } else { parse(bd.getBeanClassName(), holder.getBeanName()); } } } //处置推迟加载的importSelect?干什么要推迟加载,估量即是为了推迟吧 processDeferredImportSelectors();}protected final void parse(AnnotationMetadata metadata, String beanName) throws IOException { processConfigurationClass(new ConfigurationClass(metadata, beanName));}protected void processConfigurationClass(ConfigurationClass configClass) throws IOException { if (this.conditionEvaluator.shouldSkip(configClass.getMetadata(), ConfigurationPhase.PARSE_CONFIGURATION)) { return; } // 处置Imported 的情景 // 即是暂时这个证明类有没有被其余类import ConfigurationClass existingClass = this.configurationClasses.get(configClass); if (existingClass != null) { if (configClass.isImported()) { if (existingClass.isImported()) { existingClass.mergeImportedBy(configClass); } // Otherwise ignore new imported config class; existing non-imported class overrides it. return; } else { // Explicit bean definition found, probably replacing an imports. // Let's remove the old one and go with the new one. this.configurationClasses.remove(configClass); this.knownSuperclasses.values().removeIf(configClass::equals); } } // Recursively process the configuration class and its superclass hierarchy. SourceClass sourceClass = asSourceClass(configClass); do { //简直的实行(要害) sourceClass = doProcessConfigurationClass(configClass, sourceClass); } while (sourceClass != null); //一个map,用来寄存扫描出来的bean(提防这边的bean不是东西,只是bean的消息,由于还没到范例化这一步) this.configurationClasses.put(configClass, configClass);}protected final SourceClass doProcessConfigurationClass(ConfigurationClass configClass, SourceClass sourceClass) throws IOException { // 处置里面类 processMemberClasses(configClass, sourceClass); // 处置@PropertySource证明 for (AnnotationAttributes propertySource : AnnotationConfigUtils.attributesForRepeatable( sourceClass.getMetadata(), PropertySources.class, org.springframework.context.annotation.PropertySource.class)) { if (this.environment instanceof ConfigurableEnvironment) { processPropertySource(propertySource); } } // 处置@ComponentScan证明 Set<AnnotationAttributes> componentScans = AnnotationConfigUtils.attributesForRepeatable( sourceClass.getMetadata(), ComponentScans.class, ComponentScan.class); if (!componentScans.isEmpty() && !this.conditionEvaluator.shouldSkip(sourceClass.getMetadata(), ConfigurationPhase.REGISTER_BEAN)) { for (AnnotationAttributes componentScan : componentScans) { //扫描普遍类=componentScan=com.llsydn //这边扫描出来一切@Component //而且把扫描的出来的普遍bean放到map傍边 Set<BeanDefinitionHolder> scannedBeanDefinitions = this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName()); //查看扫描出来的类傍边能否再有configuration for (BeanDefinitionHolder holder : scannedBeanDefinitions) { BeanDefinition bdCand = holder.getBeanDefinition().getOriginatingBeanDefinition(); if (bdCand == null) { bdCand = holder.getBeanDefinition(); } //查看到有的,再实行一次parse本领 if (ConfigurationClassUtils.checkConfigurationClassCandidate(bdCand, this.metadataReaderFactory)) { parse(bdCand.getBeanClassName(), holder.getBeanName()); } } } } /** * 上头的代码即是扫描普遍类—-@Component * 而且放到了map傍边 */ // Process any @Import annotations //处置@Import imports 3种情景 //ImportSelector //普遍类 //ImportBeanDefinitionRegistrar //这边和里面地柜挪用功夫的情景各别 /** * 这边处置的import是须要确定咱们的类傍边功夫有@Import证明 * 即使有这把@Import傍边的值拿出来,是一个类 * 比方@Import(xxxxx.class),那么这边便把xxxxx传进去举行领会 * 在领会的进程中即使察觉是一个importSelector那么就回调selector的本领 * 归来一个字符串(类名),经过这个字符串获得一个类 * 既而在递归挪用本本领来处置这个类 * * 确定一组类是否imports(3种import) */ processImports(configClass, sourceClass, getImports(sourceClass), true); // Process any @ImportResource annotations AnnotationAttributes importResource = AnnotationConfigUtils.attributesFor(sourceClass.getMetadata(), ImportResource.class); if (importResource != null) { String[] resources = importResource.getStringArray("locations"); Class<? extends BeanDefinitionReader> readerClass = importResource.getClass("reader"); for (String resource : resources) { String resolvedResource = this.environment.resolveRequiredPlaceholders(resource); configClass.addImportedResource(resolvedResource, readerClass); } } // 处置@Bean本领 Set<MethodMetadata> beanMethods = retrieveBeanMethodMetadata(sourceClass); for (MethodMetadata methodMetadata : beanMethods) { configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass)); } // Process default methods on interfaces processInterfaces(configClass, sourceClass); // Process superclass, if any if (sourceClass.getMetadata().hasSuperClass()) { String superclass = sourceClass.getMetadata().getSuperClassName(); if (superclass != null && !superclass.startsWith("java") && !this.knownSuperclasses.containsKey(superclass)) { this.knownSuperclasses.put(superclass, configClass); // Superclass found, return its annotation metadata and recurse return sourceClass.getSuperClass(); } } // No superclass -> processing is complete return null;}//ComponentScanAnnotationParser,扫描普遍的@componentpublic Set<BeanDefinitionHolder> parse(AnnotationAttributes componentScan, final String declaringClass) { ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(this.registry, componentScan.getBoolean("useDefaultFilters"), this.environment, this.resourceLoader); //扫描包(中心) return scanner.doScan(StringUtils.toStringArray(basePackages));}//ClassPathBeanDefinitionScannerprotected Set<BeanDefinitionHolder> doScan(String… basePackages) { Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet<>(); for (String basePackage : basePackages) { //扫描basePackage路途下的java文献 //适合前提的并把它转成BeanDefinition典型 Set<BeanDefinition> candidates = findCandidateComponents(basePackage); for (BeanDefinition candidate : candidates) { //领会scope属性 ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate); candidate.setScope(scopeMetadata.getScopeName()); String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry); if (candidate instanceof AbstractBeanDefinition) { //即使这个类是AbstractBeanDefinition的子类 //则为他树立默许值,比方lazy,init destory postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName); } if (candidate instanceof AnnotatedBeanDefinition) { //查看而且处置常用的证明 //这边的处置主假如指把常用证明的值树立到AnnotatedBeanDefinition傍边 //暂时基础是这个类必需是AnnotatedBeanDefinition典型的,道白了即是加了证明的类 AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate); } if (checkCandidate(beanName, candidate)) { BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName); definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry); beanDefinitions.add(definitionHolder); //将bean设置备案到bean工场中 registerBeanDefinition(definitionHolder, this.registry); } } } return beanDefinitions;}//扫描包,将class转成beanDefinitionpublic Set<BeanDefinition> findCandidateComponents(String basePackage) { if (this.componentsIndex != null && indexSupportsIncludeFilters()) { return addCandidateComponentsFromIndex(this.componentsIndex, basePackage); } else { return scanCandidateComponents(basePackage); }}//运用asm本领读取class文献,并将class文献转成beanDefinitionprivate Set<BeanDefinition> scanCandidateComponents(String basePackage) { Set<BeanDefinition> candidates = new LinkedHashSet<>(); try { String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX + resolveBasePackage(basePackage) + '/' + this.resourcePattern; //asm 读取class文献 Resource[] resources = getResourcePatternResolver().getResources(packageSearchPath); boolean traceEnabled = logger.isTraceEnabled(); boolean debugEnabled = logger.isDebugEnabled(); for (Resource resource : resources) { if (resource.isReadable()) { try { MetadataReader metadataReader = getMetadataReaderFactory().getMetadataReader(resource); if (isCandidateComponent(metadataReader)) { ScannedGenericBeanDefinition sbd = new ScannedGenericBeanDefinition(metadataReader); sbd.setResource(resource); sbd.setSource(resource); if (isCandidateComponent(sbd)) { candidates.add(sbd); } } } } } } return candidates;}invokeBeanFactoryPostProcessors的重要效率: 1.实行spring里面的**BeanFactoryPostProcessor的本领。(ConfigurationClassPostProcessor)

ConfigurationClassPostProcessor重要的效率即是实行bean的扫描,并实行将beanDefinition备案到bean工场中

BeanFactoryPostProcessor spring的扩充点之一: 1.实行该接口,不妨在spring的bean创造之前窜改bean的设置属性。 2.spring承诺BeanFactoryPostProcessor在容器范例化任何其它bean之前读取摆设元数据, 3.并不妨按照须要举行窜改,比方不妨把bean的scope从singleton改为prototype,也不妨把property的值给窜改掉。 4.不妨同声摆设多个BeanFactoryPostProcessor,并经过树立'order'属性来遏制各个BeanFactoryPostProcessor的实行步骤。 5.BeanFactoryPostProcessor是在spring容器加载了bean的设置文献之后,在bean范例化之前实行的。

BeanDefinitionRegistryPostProcessor实行了BeanFactoryPostProcessor 。是对BeanFactoryPostProcessor 的扩充,新增了postProcessBeanDefinitionRegistry本领,不妨往Bean工场中,备案一个BeanDefinition东西。

demo

猜你喜欢
发表评论

电子邮件地址不会被公开。 必填项已用*标注

评论信息