当前位置: 首页 > news >正文

济南市住房和城乡建设局网站专业网站设计 网络服务

济南市住房和城乡建设局网站,专业网站设计 网络服务,做策划 都上什么网站,怎么搭建个人网站Spring ioc主要职责为依赖进行处理#xff08;依赖注入、依赖查找#xff09;、容器以及托管的(java bean、资源配置、事件)资源声明周期管理#xff1b;在ioc容器启动对元信息进行读取#xff08;比如xml bean注解等#xff09;、事件管理、国际化等处理#xff1b;首先…Spring ioc主要职责为依赖进行处理依赖注入、依赖查找、容器以及托管的(java bean、资源配置、事件)资源声明周期管理在ioc容器启动对元信息进行读取比如xml bean注解等、事件管理、国际化等处理首先spring中定义的元信息为BeanDefinitionSpring BeanDefinition解析与注册不同的资源有不同的实现 XML资源 XmlBeanDefinitionReaderProperties资源 PropertiesBeanDefinitionReaderJAVA注解 AnnotationBeanDefinitionReader 在实际工作中注解用的偏多接下来使用AnnotationConfigApplicationContext来实例化我们spring ioc容器。并进行源码分析。 Component public class Demo {public static void main(String[] args) {AnnotationConfigApplicationContext annotationConfigApplicationContext new AnnotationConfigApplicationContext();annotationConfigApplicationContext.register(Demo.class);annotationConfigApplicationContext.refresh();Person person annotationConfigApplicationContext.getBean(Person.class);System.out.println(person);annotationConfigApplicationContext.close();}Componentpublic static class Test {Beanpublic Person createUser() {Person person new Person();person.setName(UUID.randomUUID().toString());return person;}}public static class Person {private String name;// toString get set 省略} }输出结果 Person{name36874349-794b-4adf-b877-2666f54b8287}我们仅仅注册了Demo类AnnotationConfigApplicationContext如何进行Bean和Component注解进行查找呢 前面我们提到了注解类用到AnnotationBeanDefinitionReader类进行BeanDefinition的解析与注册在我们初始化代码的是也可以看到创建了AnnotationBeanDefinitionReader对象并在AnnotationBeanDefinitionReader构建方法中调用AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);进行注解BeanDefinition的默认后置处理。 ...省略 if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {RootBeanDefinition def new RootBeanDefinition(ConfigurationClassPostProcessor.class);def.setSource(source);beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)); } ...省略ConfigurationClassPostProcessor.class类为重点关注类 然后调用注册我们的Demo.clss 解析我们该类生成 AnnotatedGenericBeanDefinition abd new AnnotatedGenericBeanDefinition(beanClass); 最后通过调用BeanDefinitionReaderUtils#registerBeanDefinition()方法进行注册BeanDefinition。 Spring context#refresh()方法 public void refresh() throws BeansException, IllegalStateException {synchronized (this.startupShutdownMonitor) {StartupStep contextRefresh this.applicationStartup.start(spring.context.refresh);// Prepare this context for refreshing.//准备刷新上下文prepareRefresh();// Tell the subclass to refresh the internal bean factory.//告诉子类刷新内部bean工厂ConfigurableListableBeanFactory beanFactory obtainFreshBeanFactory();// Prepare the bean factory for use in this context.//将该BeanFactory应用于上下文默认BeanFactory实现为DefaultListableBeanFactory。查看源码得知道context也是基础BeanFactory但进行依赖查找的时候会调用getBeanFactory().getBean(xx)进行处理可理解为context对象与BeanFactory是一种特殊的组合也可以理解为context对象是对BeanFactory的一种封装。prepareBeanFactory(beanFactory);try {// Allows post-processing of the bean factory in context subclasses.//允许在上下文子类中对bean工厂进行后置处理postProcessBeanFactory(beanFactory);StartupStep beanPostProcess this.applicationStartup.start(spring.context.beans.post-process);// Invoke factory processors registered as beans in the context.// 调用上下文中注册为bean的工厂处理器 完成对BeanDefinitionRegistryPostProcessor和BeanFactoryPostProcessor的后置处理器调用invokeBeanFactoryPostProcessors(beanFactory);// Register bean processors that intercept bean creation.registerBeanPostProcessors(beanFactory);//注册拦截器bean创建的bean处理器beanPostProcess.end();// Initialize message source for this context.//初始化此上下文的消息源,列如如国际化initMessageSource();// Initialize event multicaster for this context.//为此上下文初始化事件多播initApplicationEventMulticaster();// Initialize other special beans in specific context subclasses.// 初始化特定上下文子类中的其他特殊beanonRefresh();// Check for listener beans and register them.//检查监听器bean并注册registerListeners();// Instantiate all remaining (non-lazy-init) singletons.//实例化非懒加载的单例 实例化beanfinishBeanFactoryInitialization(beanFactory);// Last step: publish corresponding event.//完成事件发布finishRefresh();}catch (BeansException ex) {if (logger.isWarnEnabled()) {logger.warn(Exception encountered during context initialization - cancelling refresh attempt: ex);}// Destroy already created singletons to avoid dangling resources.destroyBeans();// Reset active flag.cancelRefresh(ex);// Propagate exception to caller.throw ex;}finally {// Reset common introspection caches in Springs core, since we// might not ever need metadata for singleton beans anymore...resetCommonCaches();contextRefresh.end();}}} 先入为主我们看到invokeBeanFactoryPostProcessors 方法为完成对BeanDefinitionRegistryPostProcessor和BeanFactoryPostProcessor的后置处理器调用,那我们直接跟踪源码 进入到 PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors(beanfactorybranfactoryPostProcessors)方法。跟踪代码找相应的的bean 元信息注册的处理器。 特别注意改方法可以分为两部分进行理解第一次部分是对BeanDefinitionRegistryPostProcessor进行处理第二部分是对BeanFactoryPostProcessor进行处理 首先按照类型BeanDefinitionRegistryPostProcessor.class查找后置处理器的名字,在我们初始spring上线下文中注入了ConfigurationClassPostProcessor类并行该类实现了BeanDefinitionRegistryPostProcessor.class。如下uml图 ConfigurationClassPostProcessor#postProcessBeanDefinitionRegistry(registry) BeanDefinition解析与注册 顺利的拿到了ConfigurationClassPostProcessor类接下来进行排序执行PostProcessorRegistrationDelegate#invokeBeanDefinitionRegistryPostProcessors()方法。 /*** Invoke the given BeanDefinitionRegistryPostProcessor beans.*/ 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();} } 此时对应的BeanDefinitionRegistryPostProcessor类型的processor是ConfigurationClassPostProcessor,调用ConfigurationClassPostProcessor#postProcessBeanDefinitionRegistry(registry) /*** Derive further bean definitions from the configuration classes in the registry.*/ Override public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {int registryId System.identityHashCode(registry);if (this.registriesPostProcessed.contains(registryId)) {throw new IllegalStateException(postProcessBeanDefinitionRegistry already called on this post-processor against registry);}if (this.factoriesPostProcessed.contains(registryId)) {throw new IllegalStateException(postProcessBeanFactory already called on this post-processor against registry);}this.registriesPostProcessed.add(registryId);processConfigBeanDefinitions(registry); } 接下来我们进入processConfigBeanDefinitions(registry)方法 /*** Build and validate a configuration model based on the registry of* {link Configuration} classes.*/ public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {ListBeanDefinitionHolder configCandidates new ArrayList();String[] candidateNames registry.getBeanDefinitionNames();// 循环注入的BeanDefinition前面我们demo已经注册了Demo类的 BeanDefinition。for (String beanName : candidateNames) {BeanDefinition beanDef registry.getBeanDefinition(beanName);if (beanDef.getAttribute(ConfigurationClassUtils.CONFIGURATION_CLASS_ATTRIBUTE) ! null) {if (logger.isDebugEnabled()) {logger.debug(Bean definition has already been processed as a configuration class: beanDef);}}//是否是配置类是否包涵Component、ComponentScan、Import、ImportResource注解以及最后检查是否带有Bean的方法。最后打上标记else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));}} ...省略do {StartupStep processConfig this.applicationStartup.start(spring.context.config-classes.parse);//进行配置类扫描扫描成员类以及带有ComponentScans.class、PropertySources.classComponentScans.class、 ImportResource.classparser.parse(candidates);parser.validate();SetConfigurationClass configClasses new LinkedHashSet(parser.getConfigurationClasses());configClasses.removeAll(alreadyParsed);// Read the model and create bean definitions based on its contentif (this.reader null) {this.reader new ConfigurationClassBeanDefinitionReader(registry, this.sourceExtractor, this.resourceLoader, this.environment,this.importBeanNameGenerator, parser.getImportRegistry());}//开始注册我们解析到的配置类读取配置类生成BeanDefinition并注入到当前容器中this.reader.loadBeanDefinitions(configClasses);alreadyParsed.addAll(configClasses);processConfig.tag(classCount, () - String.valueOf(configClasses.size())).end();candidates.clear();if (registry.getBeanDefinitionCount() candidateNames.length) {String[] newCandidateNames registry.getBeanDefinitionNames();SetString oldCandidateNames new HashSet(Arrays.asList(candidateNames));SetString alreadyParsedClasses new HashSet();for (ConfigurationClass configurationClass : alreadyParsed) {alreadyParsedClasses.add(configurationClass.getMetadata().getClassName());}//对比新生成的BeanDefinition执行ConfigurationClassUtils.checkConfigurationClassCandidate。进行标记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;}}...省略 ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory) MapString, Object config metadata.getAnnotationAttributes(Configuration.class.getName()); if (config ! null !Boolean.FALSE.equals(config.get(proxyBeanMethods))) {beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_FULL); } else if (config ! null || isConfigurationCandidate(metadata)) {beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_LITE); } else {return false; }....public static boolean isConfigurationCandidate(AnnotationMetadata metadata) {// Do not consider an interface or an annotation...if (metadata.isInterface()) {return false;}// Any of the typical annotations found?//是否匹配Component.class、ComponentScan.class、Import.class、ImportResource.class注解for (String indicator : candidateIndicators) {if (metadata.isAnnotated(indicator)) {return true;}}// Finally, lets look for Bean methods...//查找是否含有注解bean的方法。return hasBeanMethods(metadata); }该方法解析注册BeanDefinition中是否包涵Configuration注解以及是否包含配置的选项并进行如果BeanDefinition元信息中包涵Configuration.class注解并且proxyBeanMethods配置不为false设置BeanDefinition的configurationClass属性为full否则判断是否包涵配置候选bean 将该BeanDefinition的configurationClass属性为lite。 该方法是用来判断一个是否是一个配置类并为BeanDefinition设置属性为lite或者full。如果加了Configuration并且对应Configuration注解的proxyBeanMethods配置不为false那么对应的BeanDefinition为full如果加了BeanComponentComponentScanImportImportResource这些注解和Configuration的proxyBeanMethods配置为false则为lite。lite和full均表示这个BeanDefinition对应的类是一个配置类。 初次标记完后然后继续跟踪到配置类的解析通过ConfigurationClassParser.parse(candidates)解析每一个配置类。对注入不同的BeanDefinition分别处理我们优先看Component注解类型的AnnotatedBeanDefinition 开始对我们注册的BeanDefinition进行元信息进行解析ConfigurationClassParser#parse最终到processConfigurationClass#processConfigurationClass(configClassfilter) protected void processConfigurationClass(ConfigurationClass configClass, PredicateString filter) throws IOException {if (this.conditionEvaluator.shouldSkip(configClass.getMetadata(), ConfigurationPhase.PARSE_CONFIGURATION)) {return;}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 import.// Lets 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, filter);do {//开始解析配置类 读取注解、成员和方法应用处理并构建完整的配置类新解析到的配置类 进行递归解析。sourceClass doProcessConfigurationClass(configClass, sourceClass, filter);}while (sourceClass ! null);this.configurationClasses.put(configClass, configClass);}来到我们解析成员类 /*** Register member (nested) classes that happen to be configuration classes themselves.*/private void processMemberClasses(ConfigurationClass configClass, SourceClass sourceClass,PredicateString filter) throws IOException {CollectionSourceClass memberClasses sourceClass.getMemberClasses();if (!memberClasses.isEmpty()) {ListSourceClass candidates new ArrayList(memberClasses.size());for (SourceClass memberClass : memberClasses) {//排除非配置类和防止重复引用的类if (ConfigurationClassUtils.isConfigurationCandidate(memberClass.getMetadata()) !memberClass.getMetadata().getClassName().equals(configClass.getMetadata().getClassName())) {candidates.add(memberClass);}}OrderComparator.sort(candidates);for (SourceClass candidate : candidates) {if (this.importStack.contains(configClass)) {this.problemReporter.error(new CircularImportProblem(configClass, this.importStack));}else {this.importStack.push(configClass);try {//将SourceClass转换为ConfigurationClass类此处标记该成员类的所属类processConfigurationClass(candidatenfigClass(configClass), filter);}finally {this.importStack.pop();}}}}}跟踪到ConfigurationClassParser#doProcessConfigurationClass(configClass,sourceClass, filter)方法首先是判断是否包涵Component注解然后开始解析成员类。然后继续递处理配置类。 回到processConfigBeanDefinitions方法中调用ConfigurationClassBeanDefinitionReader#loadBeanDefinitions(configClasses);加载解析注册BeanDefinition public void loadBeanDefinitions(SetConfigurationClass configurationModel) {TrackedConditionEvaluator trackedConditionEvaluator new TrackedConditionEvaluator();for (ConfigurationClass configClass : configurationModel) {loadBeanDefinitionsForConfigurationClass(configClass, trackedConditionEvaluator);}}/*** Read a particular {link ConfigurationClass}, registering bean definitions* for the class itself and all of its {link Bean} methods.*/private void loadBeanDefinitionsForConfigurationClass(ConfigurationClass configClass, TrackedConditionEvaluator trackedConditionEvaluator) {if (trackedConditionEvaluator.shouldSkip(configClass)) {String beanName configClass.getBeanName();if (StringUtils.hasLength(beanName) this.registry.containsBeanDefinition(beanName)) {this.registry.removeBeanDefinition(beanName);}this.importRegistry.removeImportingClass(configClass.getMetadata().getClassName());return;}//解析到的类是否是导入进来的所依赖进来的示例代码中Test配置类是Demo的成员类if (configClass.isImported()) {//注册BeanDefinitionregisterBeanDefinitionForImportedConfigurationClass(configClass);}for (BeanMethod beanMethod : configClass.getBeanMethods()) {//加载带有Bean方法的注解方法并注册BeanDefinitionloadBeanDefinitionsForBeanMethod(beanMethod);}// 判断是否被导入进来的资源配置groovy以及xmlloadBeanDefinitionsFromImportedResources(configClass.getImportedResources());//方便扩展取出实现了ImportBeanDefinitionRegistrar接口的类执行其registerBeanDefinitions方法。读取自定义实现的Registrar 注入到容器中。可以参考dubbo的DubboComponentScanRegistrar 实现loadBeanDefinitionsFromRegistrars(configClass.getImportBeanDefinitionRegistrars());} 回到processConfigBeanDefinitions方法中最后将新的注册的BeanDefinition进行属性标记。 最终完成了我们BeanDefinition解析与注册。
http://www.tj-hxxt.cn/news/138102.html

相关文章:

  • 深圳网站开发技术中国外协加工网最新加工订单
  • 做推广什么网站便宜wordpress简约
  • wordpress建设的是模板网站吗物流网站建设合同范本
  • 青岛网站推广怎么做好seo快速优化排名
  • 做app网站有哪些功能软件网站建设基本流程
  • 软件正版化情况及网站建设情况点石家装全包价格最新
  • 多种网站模板网站备案费用
  • 微信小程序制作免费轻站平台黄骅港招聘
  • 那种网站2021调查问卷网站建设
  • 网站建设优化400报价国内最新新闻10条
  • 可信的免费网站建设263企业邮箱自动回复
  • 廊坊网站建设推广普像工业设计网站
  • 网站被加黑链怎么找货源开网店
  • 专业网站建设公司推荐wamp网站开发视频教程
  • 网络推广有哪些网站企业网站管理系统c
  • 中国建设银行官网首页 网站滕滕州网站建设
  • 陕西陕煤建设集团有限公司网站wordpress短信宝
  • 网站贸易表格怎么做网站开发代码规范
  • 中国建设网官方网站硅灰青海玉树网站建设
  • iss服务器网站建设网站开发近期市场
  • 做网站详情的图片公众号排版编辑器app
  • 山东省住房城乡建设厅网站做布料的著名网站
  • 青海建设厅网站特种作业做网站赚不到钱了
  • 企业门户网站案例企业名录搜索软件带名字
  • 有公网ip 如何做一网站中国建设银行网站首页joy
  • 淘宝网站开发的意义google企业网站seo
  • 做商演任务的网站安徽万振建设集团网站
  • 羽贝网站建设googleplay官方下载
  • 招商加盟的网站应该怎么做网站开发struts
  • 平面设计的网站有哪些成都vi设计十强