前言
对于AbstractApplicationContex#refresh()方法逻辑,可所谓是贯通spring框架核心逻辑,溪源在debug过程中,理解起来也是懵懵懂懂,自己也买了《Spring源码深度解析》书籍学习其思想和实现逻辑,经过不断的整理学习总结,最终诞生这篇文章,方便后面自己忘记了查看和理解。
下面开始正式踏入refresh方法的整体概览浅析。
概览
refresh
该方法是 Spring Bean 加载的核心,它是 ClassPathXmlApplicationContext 的父类 AbstractApplicationContext 的一个方法 , 顾名思义,用于刷新整个Spring 上下文信息,定义了整个 Spring 上下文加载的流程。
先看下refresh()方法总体:
@Override public void refresh() throws BeansException, IllegalStateException { synchronized (this.startupShutdownMonitor) { // 准备预处理:记录容器的启动时间startupDate, 标记容器为激活,初始化上下文环境如文件路径信息,验证必填属性是否填写 this.prepareRefresh(); // **告诉子类去刷新bean工厂,此方法解析配置文件并将bean信息存储到beanDefinition中,注册到BeanFactory(但是未被初始化,仅将信息写到了beanDefination的map中)**重点方法,下面的操作都基于这个beanFactory进行的 ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory(); // 设置beanFactory的基本属性:类加载器,添加多个beanPostProcesser this.prepareBeanFactory(beanFactory); try { // 空实现:允许子类上下文中对beanFactory做后期处理 this.postProcessBeanFactory(beanFactory); /**************************以上是BeanFactory的创建及预准备工作 ****************/ // 调用BeanFactoryPostProcessor各个实现类的方法 this.invokeBeanFactoryPostProcessors(beanFactory); // 注册 BeanPostProcessor 的实现类,注意看和 BeanFactoryPostProcessor 的区别 // 此接口两个方法: postProcessBeforeInitialization 和 postProcessAfterInitialization // 两个方法分别在 Bean 初始化之前和初始化之后得到执行。注意,到这里 Bean 还没初始化 this.registerBeanPostProcessors(beanFactory); //初始化ApplicationContext的MessageSource组件(资源文件),如国际化文件,消息解析,绑定等 this.initMessageSource(); //初始化ApplicationContext事件广播器 this.initApplicationEventMulticaster(); // 初始化子类特殊bean(钩子方法) this.onRefresh(); // 获取所有的事件监听器,并将监听器注册到事件广播器 this.registerListeners(); //** 初始化所有singleton bean;**重点方法 this.finishBeanFactoryInitialization(beanFactory); // 广播事件:ApplicationContext初始化完成 this.finishRefresh(); } catch (BeansException ex) { if (logger.isWarnEnabled()) { logger.warn("Exception encountered during context initialization - " + "cancelling refresh attempt: " + ex); } // 销毁bean this.destroyBeans(); // 重置 'active' 标志. this.cancelRefresh(ex); throw ex; } }
明细
本篇文章,不会仔细往下探讨源码实现逻辑,先总结refresh()方法具体逻辑:
1.prepareRefresh
准备预处理:记录spring容器的启动时间startupDate, 标记容器为激活,初始化上下文环境如文件路径信息,验证必填属性是否填写。
//刷新前的预处理; protected void prepareRefresh() { this.startupDate = System.currentTimeMillis(); this.closed.set(false); this.active.set(true); if (logger.isInfoEnabled()) { logger.info("Refreshing " + this); } // 初始化一些属性设置;子类自定义个性化的属性设置方法; initPropertySources(); // 校验配置文件的属性,合法性 getEnvironment().validateRequiredProperties(); //保存容器中的一些事件 this.earlyApplicationEvents = new LinkedHashSet<ApplicationEvent>(); }
2.obtainFreshBeanFactory
获取BeanFactory,解析配置文件,生成beanDefinition;
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() { refreshBeanFactory(); //创建了一个this.beanFactory = new DefaultListableBeanFactory();设置了序列化的ID //返回刚才创建的DefaultListableBeanFactory ConfigurableListableBeanFactory beanFactory = getBeanFactory(); if (logger.isDebugEnabled()) { logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory); } return beanFactory; }
3.prepareBeanFactory
该方法主要负责对BeanFactory的预准备工作,配置beanFactory的基础属性,比如ClassLoader和一些PostProcessor等。
这个方法主要是给BeanFactory设置一些基本的属性,比如类加载器、表达式解析器、属性编辑器,注册几个单例、添加一些不用注入的接口、添加解析依赖项等。
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) { // Tell the internal bean factory to use the context's class loader etc. //设置类加载器 beanFactory.setBeanClassLoader(getClassLoader()); //设置bean表达式解析器,详解见下文 beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver()); //资源编辑注册器 beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment())); //添加一个BeanPostProcessor:ApplicationContextAwareProcessor,用于向实现类ApplitionContextAware中,调用setApplicationContext方法,并将ApplicationContext作为参数。 beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this)); //添加忽略自动装配的接口 beanFactory.ignoreDependencyInterface(EnvironmentAware.class); beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class); beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class); beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class); beanFactory.ignoreDependencyInterface(MessageSourceAware.class); beanFactory.ignoreDependencyInterface(ApplicationContextAware.class); // 注册几个解析依赖项,意思是,当一个Bean需要注入对应的类时,使用下面注册的这些类 //比如,如果@Autowire 一个BeanFactory,那么这个BeanFactory实际就是在此处注册的一个对象 //这几项分别是:BeanFactory、ResourceLoader、ApplicationEventPublisher、ApplicationContext beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory); beanFactory.registerResolvableDependency(ResourceLoader.class, this); beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this); beanFactory.registerResolvableDependency(ApplicationContext.class, this); // Detect a LoadTimeWeaver and prepare for weaving, if found. //检查是否由LoadTimeWeaver,如果有loadTimeWeaver的bean,就放入一个BeanPostProcessor:LoadTimeWeaverAwareProcessor 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())); } // 注册environment,注册成单例 if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) { beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment()); } //注册systemProperties 成单例 if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) { beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties()); } //注册 systemEnvironment 成单例 if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) { beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment()); } }
4.postProcessBeanFactory
主要负责在BeanFactory准备工作完成之后,beanFactory的后置处理工作;
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) { }
5. invokeBeanFactoryPostProcessors
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) { // Invoke BeanDefinitionRegistryPostProcessors first, if any. //用于存放已处理过的Bean Set<String> processedBeans = new HashSet<String>(); //如果IOC容器是一个BeanDefinitionRegistry,有了注册BeanDefinition的能力,就可以执行BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry方法 if (beanFactory instanceof BeanDefinitionRegistry) { BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory; //regularPostProcessors用于存放普通的BeanFactoryPostProcessor List<BeanFactoryPostProcessor> regularPostProcessors = new LinkedList<BeanFactoryPostProcessor>(); //registryPostProcessors用于存放 BeanDefinitionRegistryPostProcessor List<BeanDefinitionRegistryPostProcessor> registryPostProcessors = new LinkedList<BeanDefinitionRegistryPostProcessor>(); //查询通过addBeanFactoryPostProcessor等方法设置进来的的BeanFactoryPostProcessor(不是注册到IOC容器的中) for (BeanFactoryPostProcessor postProcessor : getBeanFactoryPostProcessors()) { //如果是 BeanDefinitionRegistryPostProcessor , //就先执行它的postProcessBeanDefinitionRegistry,用于向IOC中注册一些BeanDefinition, //然后添加到registryPostProcessors队列中 if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) { BeanDefinitionRegistryPostProcessor registryPostProcessor = (BeanDefinitionRegistryPostProcessor) postProcessor; registryPostProcessor.postProcessBeanDefinitionRegistry(registry); registryPostProcessors.add(registryPostProcessor); } else { //如果是普通的BeanFactoryPostProcessor,就添加到regularPostProcessors队列中 regularPostProcessors.add(postProcessor); } } //获取IOC容器中注册的BeanDefinitionRegistryPostProcessor, //放入到registryPostProcessorBeans中, //并按照Order排序 Map<String, BeanDefinitionRegistryPostProcessor> beanMap = beanFactory.getBeansOfType(BeanDefinitionRegistryPostProcessor.class, true, false); List<BeanDefinitionRegistryPostProcessor> registryPostProcessorBeans = new ArrayList<BeanDefinitionRegistryPostProcessor>(beanMap.values()); OrderComparator.sort(registryPostProcessorBeans); //先调用registryPostProcessorBeans中的所有postProcessBeanDefinitionRegistry方法 for (BeanDefinitionRegistryPostProcessor postProcessor : registryPostProcessorBeans) { postProcessor.postProcessBeanDefinitionRegistry(registry); } //先调用 registryPostProcessors中的postProcessBeanFactory方法 //再调用 registryPostProcessorBeans中的postProcessBeanFactory方法 //最后调用 regularPostProcessors中的postProcessBeanFactory方法 invokeBeanFactoryPostProcessors(registryPostProcessors, beanFactory); invokeBeanFactoryPostProcessors(registryPostProcessorBeans, beanFactory); invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory); //对于IOC容器中注册的BeanDefinitionRegistryPostProcessor来说,还要放置到processedBeans中,放置重复调用 processedBeans.addAll(beanMap.keySet()); } else { //如果IOC就是一个普通的BeanFacotry,就直接从context中取出所有的BeanFactoryPostProcessor,并调用他们的postProcessBeanFactory方法 // Invoke factory processors registered with the context instance. invokeBeanFactoryPostProcessors(getBeanFactoryPostProcessors(), beanFactory); } // Do not initialize FactoryBeans here: We need to leave all regular beans // 查询IOC容器中所有的BeanFactoryPostProcessor,有可能上面的BeanDefinitionRegistryPostProcessor刚刚向IOC容器中注册了一些BeanFactoryPostProcessor,所以要在此处全部查出来。 String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false); // 按照 这些BeanFactoryPostProcessor实现的排序接口( PriorityOrdered 和 Ordered)分成3组 //第一组 实现了PriorityOrdered --- priorityOrderedPostProcessors //第二组 实现了Ordered --- orderedPostProcessorNames //第三组 没有实现排序接口 --- nonOrderedPostProcessorNames List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>(); List<String> orderedPostProcessorNames = new ArrayList<String>(); List<String> nonOrderedPostProcessorNames = new ArrayList<String>(); for (String ppName : postProcessorNames) { //如果已经处理了,就跳过 if (processedBeans.contains(ppName)) { // skip - already processed in first phase above } //实现PriorityOrdered 接口的 else if (isTypeMatch(ppName, PriorityOrdered.class)) { priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class)); } // 实现Ordered 接口的 else if (isTypeMatch(ppName, Ordered.class)) { orderedPostProcessorNames.add(ppName); } //普通的 else { nonOrderedPostProcessorNames.add(ppName); } } //然后先执行priorityOrderedPostProcessors中的,再执行orderedPostProcessorNames的,最后执行nonOrderedPostProcessorNames //排序并执行priorityOrderedPostProcessors的 OrderComparator.sort(priorityOrderedPostProcessors); invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory); // 排序并执行orderedPostProcessors的 List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>(); for (String postProcessorName : orderedPostProcessorNames) { orderedPostProcessors.add(getBean(postProcessorName, BeanFactoryPostProcessor.class)); } OrderComparator.sort(orderedPostProcessors); invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory); // 最后执行普通的BeanFactoryPostProcessor的 List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>(); for (String postProcessorName : nonOrderedPostProcessorNames) { nonOrderedPostProcessors.add(getBean(postProcessorName, BeanFactoryPostProcessor.class)); } invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory); }
6.registerBeanPostProcessors
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) { // 获取IOC中注册的 BeanPostProcessor String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false); // BeanPostProcessorChecker 也是一个 BeanPostProcessor,用于检查一个Bean应该经过的BeanPostProcessor和 int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length; beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount)); //按照排序接口分类。 //这里需要注意的是,priorityOrderedPostProcessors里面装的是BeanPostProcessor //而orderedPostProcessorNames和nonOrderedPostProcessorNames里面装的是BeanPostProcessor的name //原因是:实例化BeanPostProcessor实现类的时候,也需要调用IOC中已有的BeanPostProcessor,所以Spring这里没有提前实例化Orderd接口和普通的BeanPostProcessor。 //因此,这里有一个有趣的现象,示例化Orderd接口的BeanProcessor的时候,会使用PriorityOrdered的BeanPostProcessor进行处理 //实例化普通的BeanProcessor时,会先后经过PriorityOrdered和Orderd接口的BeanPostProcessor的处理 List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanPostProcessor>(); List<BeanPostProcessor> internalPostProcessors = new ArrayList<BeanPostProcessor>(); List<String> orderedPostProcessorNames = new ArrayList<String>(); List<String> nonOrderedPostProcessorNames = new ArrayList<String>(); //分类 for (String ppName : postProcessorNames) { //PriorityOrdered接口的,先行实例化,并把MergedBeanDefinitionPostProcessor放入到internalPostProcessors中 if (isTypeMatch(ppName, PriorityOrdered.class)) { BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class); priorityOrderedPostProcessors.add(pp); // if (pp instanceof MergedBeanDefinitionPostProcessor) { internalPostProcessors.add(pp); } } //Ordered接口的,这里只是把name记录下来。 else if (isTypeMatch(ppName, Ordered.class)) { // orderedPostProcessorNames.add(ppName); } //普通的,这里只是把name记录下来。 else { nonOrderedPostProcessorNames.add(ppName); } } //排序并注册PriorityOrdered接口的BeanPostProcessor OrderComparator.sort(priorityOrderedPostProcessors); registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors); //排序并注册Ordered接口的BeanPostProcessor List<BeanPostProcessor> orderedPostProcessors = new ArrayList<BeanPostProcessor>(); for (String ppName : orderedPostProcessorNames) { //这里才进行实例化,所以会使用实现了PriorityOrdered接口的BeanPostProcessor进行处理 BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class); orderedPostProcessors.add(pp); //把MergedBeanDefinitionPostProcessor放入到internalPostProcessors中 if (pp instanceof MergedBeanDefinitionPostProcessor) { internalPostProcessors.add(pp); } } OrderComparator.sort(orderedPostProcessors); registerBeanPostProcessors(beanFactory, orderedPostProcessors); // 注册普通的BeanPostProcessor List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanPostProcessor>(); for (String ppName : nonOrderedPostProcessorNames) { //这里才进行实例化,所以会使用实现了PriorityOrdered接口或Orderd的BeanPostProcessor进行处理 BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class); nonOrderedPostProcessors.add(pp); //把 MergedBeanDefinitionPostProcessor 放入到internalPostProcessors中 //同时注意到,即使在internalPostProcessors中 //BeanPostProcessor的顺序也是按照 PriorityOrderd > Orderd > 普通 的顺序进入的。 if (pp instanceof MergedBeanDefinitionPostProcessor) { internalPostProcessors.add(pp); } } registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors); //注册所有的MergedBeanDefinitionPostProcessor OrderComparator.sort(internalPostProcessors); registerBeanPostProcessors(beanFactory, internalPostProcessors); //最后,在末尾添加一个ApplicationListenerDetector beanFactory.addBeanPostProcessor(new ApplicationListenerDetector()); }
7.initMessageSource
初始化MessageSource组件(做国际化功能;消息绑定,消息解析);
protected void initMessageSource() { ConfigurableListableBeanFactory beanFactory = getBeanFactory(); if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) { this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class); // Make MessageSource aware of parent MessageSource. //如果已经注册了 messageSource && messageSource是HierarchicalMessageSource && messageSource没有parent && 此IOC有parent if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) { HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource; if (hms.getParentMessageSource() == null) { // Only set parent context as parent MessageSource if no parent MessageSource // registered already. hms.setParentMessageSource(getInternalParentMessageSource()); } } if (logger.isDebugEnabled()) { logger.debug("Using MessageSource [" + this.messageSource + "]"); } } //如果没有注册messageSource,就创建一个DelegatingMessageSource,并注册到IOC中 else { // Use empty MessageSource to be able to accept getMessage calls. DelegatingMessageSource dms = new DelegatingMessageSource(); dms.setParentMessageSource(getInternalParentMessageSource()); this.messageSource = dms; beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource); if (logger.isDebugEnabled()) { logger.debug("Unable to locate MessageSource with name '" + MESSAGE_SOURCE_BEAN_NAME + "': using default [" + this.messageSource + "]"); } } }
8.initApplicationEventMulticaster
protected void initApplicationEventMulticaster() { ConfigurableListableBeanFactory beanFactory = getBeanFactory(); //如果有开发自定的applicationEventMulticaster实例bean,则设置IOC的事件广播器为该实例 if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) { this.applicationEventMulticaster = beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class); if (logger.isDebugEnabled()) { logger.debug("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]"); } } //如果没有applicationEventMulticaster,就设置一个SimpleApplicationEventMulticaster else { this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory); beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster); if (logger.isDebugEnabled()) { logger.debug("Unable to locate ApplicationEventMulticaster with name '" + APPLICATION_EVENT_MULTICASTER_BEAN_NAME + "': using default [" + this.applicationEventMulticaster + "]"); } } }
9.onRefresh
模板设计模式;该方法属于钩子方法;子类重写该方法并在容器刷新的时候自定义逻辑;
protected void onRefresh() throws BeansException { // For subclasses: do nothing by default. }
10.registerListeners
注册监听器分为两部分:
protected void registerListeners() { // 查出所有通过addApplicationListener方法添加的ApplicationListener,然后注册到事件广播器上 for (ApplicationListener<?> listener : getApplicationListeners()) { getApplicationEventMulticaster().addApplicationListener(listener); } // 查出ioc容器中的所有ApplicationListener,只把他们注册到事件分发器的ApplicationListenerBean上, // 待使用时再进行实例化 String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false); for (String listenerBeanName : listenerBeanNames) { getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName); } }
11.finishBeanFactoryInitialization
finishBeanFactoryInitialization主要是负责初始化单实例的bean;该方法是重点方法,bean的生命周期基本调用getBean()方法完成。
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) { //如果IOC中有conversionService的话,就实例化并设置到IOC中 //conversionService用于类型转换 if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) && beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) { beanFactory.setConversionService( beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)); } // 如果有LoadTimeWeaverAware,就实例化 String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false); for (String weaverAwareName : weaverAwareNames) { getBean(weaverAwareName); } // 清理临时的classLoader beanFactory.setTempClassLoader(null); // 缓存所有beanDefinition的name,以备不时之需 beanFactory.freezeConfiguration(); // 实例化所有非non-lazy-init的单例 beanFactory.preInstantiateSingletons(); }
12.finishRefresh
完成bean创建和初始化过程,通知生命周期处理器 lifecycleProcessor 刷新过程,同时发出 ContextRefreshEvent 通知。
protected void finishRefresh() { // 实例化或初始化lifecycleProcessor initLifecycleProcessor(); // 调用lifecycleProcessor的刷新方法 getLifecycleProcessor().onRefresh(); //发布一个ContextRefreshedEvent事件 publishEvent(new ContextRefreshedEvent(this)); // 注册MBean,用于JMX管理 LiveBeansView.registerApplicationContext(this); }
参考资料:
总结
到此这篇关于Spring教程之refresh()执行逻辑的文章就介绍到这了,更多相关Spring refresh()执行逻辑内容请搜索小牛知识库以前的文章或继续浏览下面的相关文章希望大家以后多多支持小牛知识库!
我怎么能在最后运行一些逻辑,而不是收集。 我可以像 我如何在过滤后运行最后的逻辑。 谢谢,拉维
主要内容:一、逻辑架构分析,1.连接层,2.服务层,3.引擎层,4.存储层,二、SQL的执行流程,三、查看执行流程一、逻辑架构分析 MySQL大致分为四层:连接层、服务层、引擎层、存储层。大致如下: MySQL逻辑架构 1.连接层 客户端访问 MySQL 服务器前,做的第一件事就是建立 TCP 连接。 连接层对应图中的Connection Pool。是MySQL服务器提供给外部客户端的一个连接接口,客户端可以通过不同的方式进行连接,如JDBC、ODBC和原生方式API等(其本质还是建立TCP连接
本文向大家介绍浅析.NET逻辑分层架构,包括了浅析.NET逻辑分层架构的使用技巧和注意事项,需要的朋友参考一下 一.基础知识准备: 1.层的原则: (1)每一层以接口方式供上层调用。 (2)上层只能调用下层。 (3)依赖分为松散交互和严格交互两种。 2.业务逻辑分类: (1)应用逻辑。 (2)领域逻辑。 3.采用的层: (1)表示层(用户接口层):领域无关。
上面的代码给出了列表中以X,Y,Z开头的元素的计数,但是在上面的例子中,我要在列表中迭代三次以获得数据的。这可以通过使用简单的for循环迭代列表一次来完成。有没有可能在单个流中完成所有这些条件[只迭代一次]而不是使用多个流? 非常感谢任何帮助。
本文向大家介绍JSP教程之使用JavaBean完成业务逻辑的方法,包括了JSP教程之使用JavaBean完成业务逻辑的方法的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了JSP教程之使用JavaBean完成业务逻辑的方法。分享给大家供大家参考。具体如下: 一、目标: ① 掌握什么是JavaBean; ② 掌握如何编写JavaBean; ③ 掌握如何在JSP中访问JavaBean; ④ 理解
问题内容: 我想在两次调用getter和setter之后编写我的业务逻辑,因为我在业务逻辑中使用了它们的对象值。但是,在吸气剂之前调用了Construct,Post构造,actionevents..。 那么,如果我不想在内部获取业务逻辑,该如何使用它们的值呢? 问题答案: 我想导航到该站点并从显示在outputText中的数据库中获取数据。 在bean的(后)构造函数中执行该工作。 与 当我更改(