中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當前位置: 首頁 > news >正文

有什么網(wǎng)站可以做初中試題sem是什么崗位

有什么網(wǎng)站可以做初中試題,sem是什么崗位,蘇州品牌網(wǎng)站設(shè)計開發(fā),網(wǎng)站建設(shè)個人工作總結(jié)目錄 如何實現(xiàn)一個IOC容器? 說說你對Spring 的理解? 你覺得Spring的核心是什么? 說一下使用spring的優(yōu)勢? Spring是如何簡化開發(fā)的? IOC 運行時序 prepareRefresh() 初始化上下文環(huán)境 obtainFreshBeanFactory() 創(chuàng)建并…

目錄

如何實現(xiàn)一個IOC容器?

說說你對Spring 的理解?

你覺得Spring的核心是什么?

說一下使用spring的優(yōu)勢?

Spring是如何簡化開發(fā)的?

IOC 運行時序

prepareRefresh()??初始化上下文環(huán)境

obtainFreshBeanFactory()? ?創(chuàng)建并初始化 BeanFactory

prepareBeanFactory(beanFactory)??填充 BeanFactory 功能

postProcessBeanFactory()??提供子類覆蓋的額外處理

invokeBeanFactoryPostProcessors()? ? 激活各種BeanFactory處理器

registerBeanPostProcessors

initMessageSource

initApplicationEventMulticaster

onRefresh

registerListeners

finishBeanFactoryInitialization

finishRefresh

Spring的AOP的底層實現(xiàn)原理

說說你對Aop的理解?

說說你對IOC的理解?

依賴注入DI 的概念

談一下spring IOC的底層實現(xiàn)

BeanFactory和ApplicationContext有什么區(qū)別

簡述spring bean的生命周期?

spring支持的bean作用域有哪些?

Spring框架中的單例Bean是線程安全的么?

spring框架中使用了哪些設(shè)計模式及應(yīng)用場景

spring事務(wù)的實現(xiàn)方式原理是什么?

Transaction失效

spring事務(wù)的隔離級別有哪些?

spring的事務(wù)傳播機制是什么?

spring事務(wù)什么時候會失效?

什么的是bean的自動裝配,它有哪些方式?

spring是如何解決循環(huán)依賴的

不能解決的幾種循環(huán)依賴

pring中常見的幾種注解

spring、springmvc、springboot的區(qū)別是什么?

springmvc工作流程是什么?

springmvc的九大組件有哪些?

Spring框架中有哪些不同類型的事件


如何實現(xiàn)一個IOC容器?

要實現(xiàn)一個簡單的Spring框架IOC容器,您可以遵循以下步驟:

  1. 定義Bean注解: 創(chuàng)建一個自定義的注解,例如@MyBean,用于標識需要被IOC容器管理的Bean類。

  2. 掃描并解析Bean定義:(BeanDefinition) 創(chuàng)建一個Bean解析器,用于掃描應(yīng)用程序中的所有類,解析帶有@MyBean注解的類,并存儲Bean的定義信息,如類名、屬性等。

  3. 創(chuàng)建Bean實例: 根據(jù)Bean定義信息,使用反射機制實例化Bean,并進行依賴注入。遍歷所有的Bean定義,根據(jù)類名使用反射創(chuàng)建Bean實例,并解析其屬性依賴關(guān)系,將相應(yīng)的依賴注入到實例中。

  4. 實現(xiàn)依賴注入: 當創(chuàng)建Bean實例時,解析Bean的屬性依賴關(guān)系,并根據(jù)依賴注入的方式,通過反射或者setter方法將需要的依賴注入到Bean實例中。

  5. 管理Bean的生命周期: 可以在Bean中定義初始化和銷毀方法,并在容器中調(diào)用這些方法來管理Bean的生命周期。可以使用@PostConstruct注解標注初始化方法,使用@PreDestroy注解標注銷毀方法。

  6. 提供獲取Bean的方法: 在IOC容器中提供一個方法,根據(jù)Bean的名稱獲取對應(yīng)的實例??梢允褂肕ap來存儲Bean實例,key為Bean的名稱,value為實例對象。

  7. 實現(xiàn)配置文件加載: 可以實現(xiàn)一個簡單的配置文件加載機制,從配置文件中讀取需要注入的屬性值,例如使用properties文件或者XML文件。

以上是一個簡單的實現(xiàn)Spring框架IOC容器的步驟。在實際的Spring框架中,還有更多復(fù)雜的功能和特性,如AOP、循環(huán)依賴處理、Bean的作用域、配置文件的自動裝配等。這些是更高級的功能,需要更復(fù)雜的設(shè)計和實現(xiàn)。但通過上述步驟,您可以實現(xiàn)一個簡單的IOC容器,理解IOC的基本概念和實現(xiàn)原理。

說說你對Spring 的理解?

官網(wǎng)地址:Spring Framework

壓縮包下載地址:JFrog

源碼地址:GitHub - spring-projects/spring-framework: Spring Framework

Spring makes it easy to create Java enterprise applications. It provides everything you need to embrace the Java language in an enterprise environment, with support for Groovy and Kotlin as alternative languages on the JVM, and with the flexibility to create many kinds of architectures depending on an application’s needs. As of Spring Framework 5.1, Spring requires JDK 8+ (Java SE 8+) and provides out-of-the-box support for JDK 11 LTS. Java SE 8 update 60 is suggested as the minimum patch release for Java 8, but it is generally recommended to use a recent patch release.
?
Spring supports a wide range of application scenarios. In a large enterprise, applications often exist for a long time and have to run on a JDK and application server whose upgrade cycle is beyond developer control. Others may run as a single jar with the server embedded, possibly in a cloud environment. Yet others may be standalone applications (such as batch or integration workloads) that do not need a server.
?
Spring is open source. It has a large and active community that provides continuous feedback based on a diverse range of real-world use cases. This has helped Spring to successfully evolve over a very long time.
?
Spring 是一個開源的輕量級企業(yè)應(yīng)用開發(fā)框架,它提供了廣泛的基礎(chǔ)設(shè)施支持和生命周期管理,用于幫助開發(fā)人員構(gòu)建企業(yè)級應(yīng)用程序。以下是我對 Spring 的理解:1. IoC(Inverse of Control,控制反轉(zhuǎn))容器: Spring 使用 IoC 容器管理應(yīng)用程序中的對象依賴關(guān)系,通過將對象的創(chuàng)建、配置和組裝過程由開發(fā)者轉(zhuǎn)移到 Spring 容器,降低了組件之間的耦合度。2. AOP(Aspect-Oriented Programming,面向切面編程)支持: Spring 提供了 AOP 配置和支持,可以將橫切關(guān)注點(cross-cutting concerns)從核心業(yè)務(wù)邏輯中分離出來,實現(xiàn)了橫切關(guān)注點的重用和集中管理。3. **聲明式事務(wù)管理:** Spring 提供了強大的事務(wù)管理支持,可以通過聲明式的方式管理事務(wù),簡化了事務(wù)管理的實現(xiàn),同時提供了靈活性和可定制性。4. 模塊化設(shè)計: Spring 框架被設(shè)計為多個模塊組成,每個模塊都提供了特定的功能,開發(fā)者可以根據(jù)需求選擇使用相應(yīng)模塊,從而減少了不必要的資源浪費。5. 簡化企業(yè)級開發(fā): Spring 提供了大量的企業(yè)級功能的封裝和支持,如數(shù)據(jù)訪問、事務(wù)管理、安全性、消息傳遞等,大大簡化了開發(fā)人員構(gòu)建企業(yè)級應(yīng)用程序的工作量。6. 持續(xù)演進和創(chuàng)新: Spring 框架不斷進行演進和創(chuàng)新,持續(xù)引入新的功能和特性,以適應(yīng)不斷變化的開發(fā)需求和技術(shù)趨勢。總的來說,Spring 框架提供了一套全面且靈活的解決方案,幫助開發(fā)人員簡化企業(yè)級應(yīng)用程序的開發(fā)和維護工作,提高了代碼的可維護性、可測試性和整體質(zhì)量。通過合理使用 Spring 框架,開發(fā)人員可以專注于業(yè)務(wù)邏輯的實現(xiàn),而不必過多關(guān)注底層技術(shù)細節(jié)。

你覺得Spring的核心是什么?

Spring是一個開源的Java框架,用于構(gòu)建企業(yè)級的應(yīng)用程序。它提供了一個容器,用于管理應(yīng)用程序中的對象(如依賴注入)并提供了許多常用的功能和擴展,使開發(fā)人員能夠更加專注于業(yè)務(wù)邏輯的實現(xiàn)而不必關(guān)注太多的底層細節(jié)。

Spring的核心特性包括:

  1. 控制反轉(zhuǎn)(IoC):Spring使用控制反轉(zhuǎn)來實現(xiàn)依賴注入。控制反轉(zhuǎn)意味著對于對象的創(chuàng)建和依賴關(guān)系的管理由容器來完成,而不是由開發(fā)人員手動處理。這種方式可以降低組件之間的耦合度,并且使得代碼更加靈活和易于擴展。

  2. 面向切面編程(AOP):Spring提供了面向切面編程的支持,可以通過AOP將橫切關(guān)注點(如日志、事務(wù)管理)從業(yè)務(wù)邏輯中分離出來,使得代碼更具可維護性和可讀性。

  3. 集成框架:Spring可以與各種其他框架和技術(shù)進行集成,如持久化框架(Hibernate、MyBatis)、消息隊列(ActiveMQ、RabbitMQ)、Web框架(Spring MVC)等,以便于開發(fā)人員在項目中使用更多的功能和工具。

總之,Spring框架提供了一種靈活、高效的開發(fā)方式,可以幫助開發(fā)人員構(gòu)建可擴展、可維護的企業(yè)級應(yīng)用程序。它的特性和擴展使得它在Java開發(fā)社區(qū)中非常流行和廣泛使用。

說一下使用spring的優(yōu)勢?

使用Spring框架具有許多優(yōu)勢,它是一個強大的企業(yè)級應(yīng)用程序開發(fā)框架,提供了廣泛的功能和特性。下面是一些使用Spring框架的優(yōu)勢:

  1. 面向切面編程(AOP):Spring支持AOP,使你能夠以聲明性的方式處理跨多個模塊的關(guān)注點(例如事務(wù)管理、安全性、日志記錄等),提高了代碼的模塊化和可維護性。

  2. 依賴注入(DI):Spring的核心功能是依賴注入,它將組件之間的依賴關(guān)系轉(zhuǎn)移給容器來管理。這種松耦合的設(shè)計使得代碼更靈活、可測試性更強,并降低了代碼的耦合度。

  3. 面向接口編程:Spring鼓勵使用面向接口的編程風(fēng)格,通過接口定義了各種組件之間的契約,使得代碼更易于擴展和修改,并提供了解耦的效果。

  4. 組件化開發(fā):Spring鼓勵使用組件化開發(fā)的思想,將應(yīng)用程序拆分為功能模塊化的組件,每個組件負責特定的功能。這種模塊化的設(shè)計使得應(yīng)用程序更容易理解、擴展和維護。

  5. 輕量級和可擴展性:Spring框架本身非常輕量級,不需要很大的資源開銷。同時,Spring提供了許多可選的模塊和擴展,可以根據(jù)需求進行選擇和集成,實現(xiàn)高度可定制的應(yīng)用程序開發(fā)。

  6. 寬松的集成:Spring集成了許多其他流行的開源框架和技術(shù),例如Hibernate、JPA、MyBatis、Spring MVC、Spring Boot等。這種寬松的集成能力使得開發(fā)人員可以根據(jù)自己的需求選擇不同的技術(shù)和工具。

  7. 安全性:Spring提供了一套全面的安全性功能,包括身份認證、訪問控制和加密等。這些功能可以幫助開發(fā)人員構(gòu)建安全可靠的應(yīng)用程序。

總的來說,Spring框架的優(yōu)勢在于提供了一種靈活、模塊化、可擴展和高度定制的方式來開發(fā)企業(yè)級應(yīng)用程序。它促進了良好的設(shè)計原則和最佳實踐,提高了開發(fā)效率和代碼質(zhì)量。同時,Spring擁有龐大的社區(qū)支持和廣泛的文檔資源,使開發(fā)人員能夠輕松學(xué)習(xí)和解決問題。

Spring是如何簡化開發(fā)的?

Spring框架通過依賴注入、面向切面編程、組件化開發(fā)、技術(shù)整合和豐富的功能模塊,簡化了企業(yè)級應(yīng)用程序的開發(fā)過程。它提供了一種靈活、模塊化、可擴展和高度定制的方式來開發(fā)應(yīng)用程序,提高了開發(fā)效率和代碼質(zhì)量。

IOC 運行時序

當調(diào)用 ApplicationContext 的 refresh() 方法時,Spring 容器將執(zhí)行以下一系列步驟以完成初始化過程:

原文鏈接:【死磕 Spring】----- 深入分析 ApplicationContext 的 refresh()_為什么applicationcontext1.refresh();-CSDN博客

當調(diào)用 ApplicationContext 的 refresh() 方法時,Spring 容器將執(zhí)行以下一系列步驟以完成初始化過程:

@Override
public void refresh() throws BeansException, IllegalStateException {synchronized (this.startupShutdownMonitor) {// 準備刷新上下文環(huán)境prepareRefresh();
?// 創(chuàng)建并初始化 BeanFactoryConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
?// 填充BeanFactory功能prepareBeanFactory(beanFactory);
?try {// 提供子類覆蓋的額外處理,即子類處理自定義的BeanFactoryPostProcesspostProcessBeanFactory(beanFactory);
?// 激活各種BeanFactory處理器invokeBeanFactoryPostProcessors(beanFactory);
?// 注冊攔截Bean創(chuàng)建的Bean處理器,即注冊 BeanPostProcessorregisterBeanPostProcessors(beanFactory);
?// 初始化上下文中的資源文件,如國際化文件的處理等initMessageSource();
?// 初始化上下文事件廣播器initApplicationEventMulticaster();
?// 給子類擴展初始化其他BeanonRefresh();
?// 在所有bean中查找listener bean,然后注冊到廣播器中registerListeners();
?// 初始化剩下的單例Bean(非延遲加載的)finishBeanFactoryInitialization(beanFactory);
?// 完成刷新過程,通知生命周期處理器lifecycleProcessor刷新過程,同時發(fā)出ContextRefreshEvent通知別人finishRefresh();}
?catch (BeansException ex) {if (logger.isWarnEnabled()) {logger.warn("Exception encountered during context initialization - " +"cancelling refresh attempt: " + ex);}
?//  銷毀已經(jīng)創(chuàng)建的BeandestroyBeans();
?// 重置容器激活標簽cancelRefresh(ex);
?// 拋出異常throw ex;}
?finally {// Reset common introspection caches in Spring's core, since we// might not ever need metadata for singleton beans anymore...resetCommonCaches();}}
}

prepareRefresh()??初始化上下文環(huán)境

初始化上下文環(huán)境,對系統(tǒng)的環(huán)境變量或者系統(tǒng)屬性進行準備和校驗,如環(huán)境變量中必須設(shè)置某個值才能運行,否則不能運行,這個時候可以在這里加這個校驗,重寫initPropertySources方法就好了

該方法主要是做一些準備工作,如:

  1. 設(shè)置 context 啟動時間

  2. 設(shè)置 context 的當前狀態(tài)

  3. 初始化 context environment 中占位符

  4. 對屬性進行必要的驗證

obtainFreshBeanFactory()? ?創(chuàng)建并初始化 BeanFactory

創(chuàng)建并初始化 BeanFactory

核心方法就在 refreshBeanFactory() ,該方法的核心任務(wù)就是創(chuàng)建 BeanFactory 并對其就行一番初始化。如下:

protected final void refreshBeanFactory() throws BeansException {if (hasBeanFactory()) {destroyBeans();closeBeanFactory();}try {DefaultListableBeanFactory beanFactory = createBeanFactory();beanFactory.setSerializationId(getId());customizeBeanFactory(beanFactory);loadBeanDefinitions(beanFactory);synchronized (this.beanFactoryMonitor) {this.beanFactory = beanFactory;}}catch (IOException ex) {throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);}
}

判斷當前容器是否存在一個 BeanFactory,如果存在則對其進行銷毀和關(guān)閉 調(diào)用 createBeanFactory() 創(chuàng)建一個 BeanFactory 實例,其實就是 DefaultListableBeanFactory 自定義 BeanFactory 加載 BeanDefinition loadBeanDefinitions() 是定義在 BeanDefinitionReader

將創(chuàng)建好的 bean 工廠的引用交給的 context 來管理

prepareBeanFactory(beanFactory)??填充 BeanFactory 功能

上面獲取獲取的 BeanFactory 除了加載了一些 BeanDefinition 就沒有其他任何東西了,這個時候其實還不能投入生產(chǎn),因為還少配置了一些東西,比如 context的 ClassLoader 和 后置處理器等等。

protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {// 設(shè)置beanFactory的classLoaderbeanFactory.setBeanClassLoader(getClassLoader());// 設(shè)置beanFactory的表達式語言處理器,Spring3開始增加了對語言表達式的支持,默認可以使用#{bean.xxx}的形式來調(diào)用相關(guān)屬性值beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));// 為beanFactory增加一個默認的propertyEditorbeanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));// 添加ApplicationContextAwareProcessorbeanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));// 設(shè)置忽略自動裝配的接口beanFactory.ignoreDependencyInterface(EnvironmentAware.class);beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);beanFactory.ignoreDependencyInterface(MessageSourceAware.class);beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);// 設(shè)置幾個自動裝配的特殊規(guī)則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));// 增加對AspectJ的支持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()));}// 注冊默認的系統(tǒng)環(huán)境beanif (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {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());}

postProcessBeanFactory()??提供子類覆蓋的額外處理

提供子類覆蓋的額外處理,即子類處理自定義的BeanFactoryPostProcess

protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {beanFactory.addBeanPostProcessor(new ServletContextAwareProcessor(this.servletContext, this.servletConfig));beanFactory.ignoreDependencyInterface(ServletContextAware.class);beanFactory.ignoreDependencyInterface(ServletConfigAware.class);
?WebApplicationContextUtils.registerWebApplicationScopes(beanFactory, this.servletContext);WebApplicationContextUtils.registerEnvironmentBeans(beanFactory, this.servletContext, this.servletConfig);
}

添加 ServletContextAwareProcessor 到 BeanFactory 容器中,該 processor 實現(xiàn) BeanPostProcessor 接口,主要用于將ServletContext 傳遞給實現(xiàn)了 ServletContextAware 接口的 bean 忽略 ServletContextAware、ServletConfigAware 注冊 WEB 應(yīng)用特定的域(scope)到 beanFactory 中,以便 WebApplicationContext 可以使用它們。比如 “request” , “session” , “globalSession” , “application” 注冊 WEB 應(yīng)用特定的 Environment bean 到 beanFactory 中,以便WebApplicationContext 可以使用它們。如:“contextParameters”, “contextAttributes”

invokeBeanFactoryPostProcessors()? ? 激活各種BeanFactory處理器

public static void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
?// 定義一個 set 保存所有的 BeanFactoryPostProcessorsSet<String> processedBeans = new HashSet<>();
?// 如果當前 BeanFactory 為 BeanDefinitionRegistryif (beanFactory instanceof BeanDefinitionRegistry) {BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;// BeanFactoryPostProcessor 集合List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();// BeanDefinitionRegistryPostProcessor 集合List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
?// 迭代注冊的 beanFactoryPostProcessorsfor (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {// 如果是 BeanDefinitionRegistryPostProcessor,則調(diào)用 postProcessBeanDefinitionRegistry 進行注冊,// 同時加入到 registryProcessors 集合中if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {BeanDefinitionRegistryPostProcessor registryProcessor =(BeanDefinitionRegistryPostProcessor) postProcessor;registryProcessor.postProcessBeanDefinitionRegistry(registry);registryProcessors.add(registryProcessor);}else {// 否則當做普通的 BeanFactoryPostProcessor 處理// 添加到 regularPostProcessors 集合中即可,便于后面做后續(xù)處理regularPostProcessors.add(postProcessor);}}
?// 用于保存當前處理的 BeanDefinitionRegistryPostProcessorList<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
?// 首先處理實現(xiàn)了 PriorityOrdered (有限排序接口)的 BeanDefinitionRegistryPostProcessorString[] postProcessorNames =beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);for (String ppName : postProcessorNames) {if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));processedBeans.add(ppName);}}
?// 排序sortPostProcessors(currentRegistryProcessors, beanFactory);
?// 加入registryProcessors集合registryProcessors.addAll(currentRegistryProcessors);
?// 調(diào)用所有實現(xiàn)了 PriorityOrdered 的 BeanDefinitionRegistryPostProcessors 的 postProcessBeanDefinitionRegistry()invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
?// 清空,以備下次使用currentRegistryProcessors.clear();
?// 其次,調(diào)用是實現(xiàn)了 Ordered(普通排序接口)的 BeanDefinitionRegistryPostProcessors// 邏輯和 上面一樣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();
?// 最后調(diào)用其他的 BeanDefinitionRegistryPostProcessorsboolean reiterate = true;while (reiterate) {reiterate = false;// 獲取 BeanDefinitionRegistryPostProcessorpostProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);for (String ppName : postProcessorNames) {
?// 沒有包含在 processedBeans 中的(因為包含了的都已經(jīng)處理了)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();}
?// 調(diào)用所有 BeanDefinitionRegistryPostProcessor (包括手動注冊和通過配置文件注冊)// 和 BeanFactoryPostProcessor(只有手動注冊)的回調(diào)函數(shù)(postProcessBeanFactory())invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);}
?else {// 如果不是 BeanDefinitionRegistry 只需要調(diào)用其回調(diào)函數(shù)(postProcessBeanFactory())即可invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);}
?//String[] postProcessorNames =beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
?// 這里同樣需要區(qū)分 PriorityOrdered 、Ordered 和 no OrderedList<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();List<String> orderedPostProcessorNames = new ArrayList<>();List<String> nonOrderedPostProcessorNames = new ArrayList<>();for (String ppName : postProcessorNames) {// 已經(jīng)處理過了的,跳過if (processedBeans.contains(ppName)) {// skip - already processed in first phase above}// PriorityOrderedelse if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));}// Orderedelse if (beanFactory.isTypeMatch(ppName, Ordered.class)) {orderedPostProcessorNames.add(ppName);}// no Orderedelse {nonOrderedPostProcessorNames.add(ppName);}}
?// First, PriorityOrdered 接口sortPostProcessors(priorityOrderedPostProcessors, beanFactory);invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
?// Next, Ordered 接口List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>();for (String postProcessorName : orderedPostProcessorNames) {orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));}sortPostProcessors(orderedPostProcessors, beanFactory);invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
?// Finally, no orderedList<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();
}

上述代碼較長,但是處理邏輯較為單一,就是對所有的 BeanDefinitionRegistryPostProcessors 、手動注冊的 BeanFactoryPostProcessor 以及通過配置文件方式的 BeanFactoryPostProcessor 按照 PriorityOrdered 、 Ordered、no ordered 三種方式分開處理、調(diào)用。

registerBeanPostProcessors

注冊攔截Bean創(chuàng)建的Bean處理器,即注冊 BeanPostProcessor

與 BeanFactoryPostProcessor 一樣,也是委托給 PostProcessorRegistrationDelegate 來實現(xiàn)的。

public static void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
?// 所有的 BeanPostProcessorsString[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
?// 注冊 BeanPostProcessorChecker// 主要用于記錄一些 bean 的信息,這些 bean 不符合所有 BeanPostProcessors 處理的資格時int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
?// 區(qū)分 PriorityOrdered、Ordered 、 no orderedList<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();List<String> orderedPostProcessorNames = new ArrayList<>();List<String> nonOrderedPostProcessorNames = new ArrayList<>();// MergedBeanDefinitionList<BeanPostProcessor> internalPostProcessors = new ArrayList<>();for (String ppName : postProcessorNames) {if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);priorityOrderedPostProcessors.add(pp);if (pp instanceof MergedBeanDefinitionPostProcessor) {internalPostProcessors.add(pp);}}else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {orderedPostProcessorNames.add(ppName);}else {nonOrderedPostProcessorNames.add(ppName);}}
?// First, PriorityOrderedsortPostProcessors(priorityOrderedPostProcessors, beanFactory);registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
?// Next, OrderedList<BeanPostProcessor> orderedPostProcessors = new ArrayList<>();for (String ppName : orderedPostProcessorNames) {BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);orderedPostProcessors.add(pp);if (pp instanceof MergedBeanDefinitionPostProcessor) {internalPostProcessors.add(pp);}}sortPostProcessors(orderedPostProcessors, beanFactory);registerBeanPostProcessors(beanFactory, orderedPostProcessors);
?// onOrderedList<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>();for (String ppName : nonOrderedPostProcessorNames) {BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);nonOrderedPostProcessors.add(pp);if (pp instanceof MergedBeanDefinitionPostProcessor) {internalPostProcessors.add(pp);}}registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);
?// Finally, all internal BeanPostProcessors.sortPostProcessors(internalPostProcessors, beanFactory);registerBeanPostProcessors(beanFactory, internalPostProcessors);
?// 重新注冊用來自動探測內(nèi)部ApplicationListener的post-processor,這樣可以將他們移到處理器鏈條的末尾beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}

initMessageSource

初始化上下文中的資源文件,如國際化文件的處理等

initApplicationEventMulticaster

初始化上下文事件廣播器

onRefresh

給子類擴展初始化其他Bean

預(yù)留給 AbstractApplicationContext 的子類用于初始化其他特殊的 bean,該方法需要在所有單例 bean 初始化之前調(diào)用。

registerListeners

在所有 bean 中查找 listener bean,然后注冊到廣播器中

protected void registerListeners() {// 注冊靜態(tài) 監(jiān)聽器for (ApplicationListener<?> listener : getApplicationListeners()) {getApplicationEventMulticaster().addApplicationListener(listener);}
?String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);for (String listenerBeanName : listenerBeanNames) {getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);}
?// 至此,已經(jīng)完成將監(jiān)聽器注冊到ApplicationEventMulticaster中,下面將發(fā)布前期的事件給監(jiān)聽器。Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;this.earlyApplicationEvents = null;if (earlyEventsToProcess != null) {for (ApplicationEvent earlyEvent : earlyEventsToProcess) {getApplicationEventMulticaster().multicastEvent(earlyEvent);}}
}

finishBeanFactoryInitialization

初始化剩下的單例Bean(非延遲加載的)

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {// 初始化轉(zhuǎn)換器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));}
?// 如果之前沒有注冊 bean 后置處理器(例如PropertyPlaceholderConfigurer),則注冊默認的解析器if (!beanFactory.hasEmbeddedValueResolver()) {beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));}
?// 初始化 Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);for (String weaverAwareName : weaverAwareNames) {getBean(weaverAwareName);}
?// 停止使用臨時的 ClassLoaderbeanFactory.setTempClassLoader(null);
?//beanFactory.freezeConfiguration();
?// 初始化所有剩余的單例(非延遲初始化)beanFactory.preInstantiateSingletons();
}

finishRefresh

完成刷新過程,通知生命周期處理器 lifecycleProcessor 刷新過程,同時發(fā)出 ContextRefreshEvent 通知別人

主要是調(diào)用 LifecycleProcessor#onRefresh() ,并且發(fā)布事件(ContextRefreshedEvent)。

protected void finishRefresh() {// Clear context-level resource caches (such as ASM metadata from scanning).clearResourceCaches();
?// Initialize lifecycle processor for this context.initLifecycleProcessor();
?// Propagate refresh to lifecycle processor first.getLifecycleProcessor().onRefresh();
?// Publish the final event.publishEvent(new ContextRefreshedEvent(this));
?// Participate in LiveBeansView MBean, if active.LiveBeansView.registerApplicationContext(this);
}

Spring的AOP的底層實現(xiàn)原理

bean的創(chuàng)建過程中有一個步驟可以對bean進行擴展實現(xiàn),aop本身就是一個擴展功能,所以在BeanPostProcessor的后置處理方法中來進行實現(xiàn)

不論使用哪種方式,Spring AOP的實現(xiàn)過程都包括以下幾個關(guān)鍵步驟:

  1. 定義切點(Pointcut):切點定義了在何處應(yīng)用切面邏輯的具體位置。通過表達式或注解等方式,確定應(yīng)該被代理的目標方法或目標類。

  2. 編寫切面(Aspect):切面是具體的橫切邏輯實現(xiàn),包括在目標方法執(zhí)行前后執(zhí)行的操作(通知,Advices)。切面可以包括一個或多個通知的定義。

  3. 創(chuàng)建代理對象:Spring根據(jù)切點和切面信息,生成動態(tài)代理或字節(jié)碼增強的代理對象。代理對象在執(zhí)行目標方法時,會根據(jù)切點和切面定義,執(zhí)行相應(yīng)的切面邏輯。

總結(jié)來說,Spring AOP的底層實現(xiàn)原理是通過動態(tài)代理或字節(jié)碼生成,將切面邏輯織入到目標對象或目標類中,實現(xiàn)橫切關(guān)注點的解耦和重用。

3.在執(zhí)行方法調(diào)用的時候,會調(diào)用到生成的字節(jié)碼文件中,直接回找到DynamicAdvisoredInterceptor類中的intercept方法,從此方法開始執(zhí)行

4.根據(jù)之前定義好的通知來生成攔截器

5.從攔截器鏈中依次獲取每一個通知開始進行執(zhí)行,在執(zhí)行過程中,為了方便找到下一個通知是哪個,會有一個CglibMethodInvocation的對象,找的時候是從-1的位置依次開始查找并且執(zhí)行的。

說說你對Aop的理解?

AOP全稱叫做 Aspect Oriented Programming 面向切面編程。它是為解耦而生的,解耦是程序員編碼開發(fā)過程中一直追求的境界,AOP在業(yè)務(wù)類的隔離上,絕對是做到了解耦,在這里面有幾個核心的概念:

  • 切面(Aspect): 指關(guān)注點模塊化,這個關(guān)注點可能會橫切多個對象。事務(wù)管理是企業(yè)級Java應(yīng)用中有關(guān)橫切關(guān)注點的例子。 在Spring AOP中,切面可以使用通用類基于模式的方式(schema-based approach)或者在普通類中以@Aspect注解(@AspectJ 注解方式)來實現(xiàn)。(Aspect作為一個模塊來組織Join point , PointCut來篩選要執(zhí)行的連接點,Advice在切面的某個特定的連接點上執(zhí)行的動作),(一個Aspect對應(yīng)多個join point,一個joinPoint 有多個 advice)

  • 連接點(Join point): 在程序執(zhí)行過程中某個特定的點,例如某個方法調(diào)用的時間點或者處理異常的時間點。在Spring AOP中,一個連接點總是代表一個方法的執(zhí)行。

  • 通知(Advice): 在切面的某個特定的連接點上執(zhí)行的動作。通知有多種類型,包括“around”, “before” and “after”等等。通知的類型將在后面的章節(jié)進行討論。 許多AOP框架,包括Spring在內(nèi),都是以攔截器做通知模型的,并維護著一個以連接點為中心的攔截器鏈。

  • 切點(Pointcut): 匹配連接點的斷言。通知和切點表達式相關(guān)聯(lián),并在滿足這個切點的連接點上運行(例如,當執(zhí)行某個特定名稱的方法時)。切點表達式如何和連接點匹配是AOP的核心:Spring默認使用AspectJ切點語義。

  • 引入(Introduction): 聲明額外的方法或者某個類型的字段。Spring允許引入新的接口(以及一個對應(yīng)的實現(xiàn))到任何被通知的對象上。例如,可以使用引入來使bean實現(xiàn) IsModified接口, 以便簡化緩存機制(在AspectJ社區(qū),引入也被稱為內(nèi)部類型聲明(inter))。

  • 目標對象(Target object): 被一個或者多個切面所通知的對象。也被稱作被通知(advised)對象。既然Spring AOP是通過運行時代理實現(xiàn)的,那么這個對象永遠是一個被代理(proxied)的對象。

  • AOP代理(AOP proxy):AOP框架創(chuàng)建的對象,用來實現(xiàn)切面契約(aspect contract)(包括通知方法執(zhí)行等功能)。在Spring中,AOP代理可以是JDK動態(tài)代理或CGLIB代理。

  • 織入(Weaving): 把切面連接到其它的應(yīng)用程序類型或者對象上,并創(chuàng)建一個被被通知的對象的過程。這個過程可以在編譯時(例如使用AspectJ編譯器)、類加載時或運行時中完成。 Spring和其他純Java AOP框架一樣,是在運行時完成織入的。

    這些概念都太學(xué)術(shù)了,如果更簡單的解釋呢,其實非常簡單:

    任何一個系統(tǒng)都是由不同的組件組成的,每個組件負責一塊特定的功能,當然會存在很多組件是跟業(yè)務(wù)無關(guān)的,例如日志、事務(wù)、權(quán)限等核心服務(wù)組件,這些核心服務(wù)組件經(jīng)常融入到具體的業(yè)務(wù)邏輯中,如果我們?yōu)槊恳粋€具體業(yè)務(wù)邏輯操作都添加這樣的代碼,很明顯代碼冗余太多,因此我們需要將這些公共的代碼邏輯抽象出來變成一個切面,然后注入到目標對象(具體業(yè)務(wù))中去,AOP正是基于這樣的一個思路實現(xiàn)的,通過動態(tài)代理的方式,將需要注入切面的對象進行代理,在進行調(diào)用的時候,將公共的邏輯直接添加進去,而不需要修改原有業(yè)務(wù)的邏輯代碼,只需要在原來的業(yè)務(wù)邏輯基礎(chǔ)之上做一些增強功能即可。

說說你對IOC的理解?

在 Spring 中,IoC 是 Inversion of Control(控制反轉(zhuǎn))的縮寫,是 Spring 框架的一個重要特性。IoC 的本質(zhì)是將對對象的控制權(quán)從應(yīng)用程序本身轉(zhuǎn)移到了框架或容器中,由容器來負責對象的創(chuàng)建、管理和注入依賴對象,從而降低了組件之間的耦合度,提高了代碼的可重用性和可測試性。在 Spring 中,IoC 容器負責管理應(yīng)用程序中的對象及其之間的依賴關(guān)系,開發(fā)人員不再需要手動創(chuàng)建對象和管理對象之間的關(guān)聯(lián)關(guān)系,而是通過配置文件或注解告訴容器如何創(chuàng)建和組裝對象。IoC 容器負責實例化對象、注入依賴、生命周期管理等工作,開發(fā)人員只需要關(guān)注業(yè)務(wù)邏輯的實現(xiàn),將對象的創(chuàng)建和依賴關(guān)系的管理交由容器來完成。在 Spring 中,IoC 容器主要有兩種實現(xiàn)方式:BeanFactory 和 ApplicationContext。1. **BeanFactory:** 是 Spring 框架的基礎(chǔ)容器,提供了基本的 IoC 功能,可以延遲加載(Lazy Loading)和按需注入(On-demand Injection)Bean,適合在資源有限的環(huán)境下使用。2. **ApplicationContext:** 是 BeanFactory 的擴展,提供了更多的企業(yè)級功能和特性,如國際化支持、事件傳播、AOP、聲明式事務(wù)管理等,適合大多數(shù)企業(yè)級應(yīng)用程序使用。通過 IoC 容器,Spring 管理了應(yīng)用程序中的所有對象,并負責解決對象之間的依賴關(guān)系,從而實現(xiàn)了代碼的松耦合、易于維護和測試的優(yōu)勢。開發(fā)人員可以通過配置文件或注解,實現(xiàn)對象之間的依賴注入,讓 IoC 容器來負責對象創(chuàng)建和管理,提高了應(yīng)用程序的靈活性和可擴展性。

依賴注入DI 的概念

DI 是 Dependency Injection(依賴注入)的縮寫,它是面向?qū)ο缶幊讨械囊环N設(shè)計模式,在 Spring 框架中被廣泛應(yīng)用。DI 是 IoC(控制反轉(zhuǎn))的一種實現(xiàn)方式,通過依賴注入的方式來實現(xiàn)對象之間的解耦和管理依賴關(guān)系。

在 DI 中,對象不再負責創(chuàng)建或查找依賴的對象,而是將依賴關(guān)系注入到對象之中。這樣做的好處是提高了代碼的可維護性、可測試性和可擴展性,降低了對象之間的耦合度,使得代碼更加靈活和易于重用。

在 Spring 框架中,依賴注入可以通過構(gòu)造函數(shù)注入、Setter 方法注入或字段注入等方式實現(xiàn)。開發(fā)人員可以通過配置文件(如 XML 配置文件)或注解來指定依賴關(guān)系,讓 Spring IoC 容器來實現(xiàn)依賴注入的過程。

依賴注入的三種主要類型包括:

1. **構(gòu)造函數(shù)注入(Constructor Injection):** 通過在構(gòu)造函數(shù)中注入依賴對象來實現(xiàn)依賴注入。

2. **Setter 方法注入(Setter Injection):** 通過 Setter 方法來設(shè)置依賴對象,實現(xiàn)依賴注入。

3. **字段注入(Field Injection):** 通過字段(屬性)注入的方式來注入依賴對象。

依賴注入能夠讓開發(fā)人員專注于業(yè)務(wù)邏輯的實現(xiàn),而不必擔心對象之間的依賴關(guān)系,提高了代碼的可維護性和可測試性。通過 DI,Spring 框架實現(xiàn)了 IoC 容器的依賴管理功能,讓開發(fā)人員將對象之間的關(guān)系交給容器管理,實現(xiàn)了控制反轉(zhuǎn)的思想。

談一下spring IOC的底層實現(xiàn)

底層實現(xiàn):工作原理,過程,數(shù)據(jù)結(jié)構(gòu),流程,設(shè)計模式,設(shè)計思想

你對他的理解和你了解過的實現(xiàn)過程

反射,工廠,設(shè)計模式,關(guān)鍵的幾個方法

createBeanFactory , getBean ,doGetBean , createBean , doCreateBean,createBeanInstance(getDeclaredConstructor(),newinstance),populateBean

1.先通過createBeanFactory 創(chuàng)建一個Bean工廠(DefaultListableBeanFactory)

2.開始循環(huán)創(chuàng)建對象,因為容器中的bean默認都是單例的,所以優(yōu)先通過getBean,doGetBean從容器中查找,找不到的話,

3.通過createBean,doCreateBean方法,以反射的方式創(chuàng)建對象,一般情況下使用的是無參的構(gòu)造器(getDeclaredConstructor(),newinstance)

4.進行對象的屬性填充populateBean

5.進行其他的初始化操作(initializingBean)

BeanFactory和ApplicationContext有什么區(qū)別

相同:

  • Spring提供了兩種不同的IOC 容器,一個是BeanFactory,另外一個是ApplicationContext,它們都是Java interface,ApplicationContext繼承于BeanFactory(ApplicationContext繼承ListableBeanFactory。

  • 它們都可以用來配置XML屬性,也支持屬性的自動注入。

  • 而ListableBeanFactory繼承BeanFactory),BeanFactory 和 ApplicationContext 都提供了一種方式,使用getBean("bean name")獲取bean。

不同:

BeanFactory和ApplicationContext是Spring框架中的兩個核心接口,它們具有以下區(qū)別:

  1. 功能:

    • BeanFactory是Spring的最基本的接口,提供了IoC容器的基本功能,即管理和獲取Bean。

    • ApplicationContext是對BeanFactory的擴展,提供了更多的功能,如國際化支持、事件發(fā)布、資源加載、AOP等。

  2. 預(yù)加載:

    • BeanFactory是延遲加載的,即在調(diào)用getBean()方法時才會創(chuàng)建和初始化Bean。

    • ApplicationContext可以通過配置進行預(yù)加載,即在容器啟動時就實例化和初始化所有的單例Bean。

  3. 配置元數(shù)據(jù)的處理:

    • BeanFactory使用BeanDefinition來管理和解析配置元數(shù)據(jù),Bean的創(chuàng)建由BeanDefinition中的信息描述。

    • ApplicationContext在BeanFactory的基礎(chǔ)上進一步擴展了對配置元數(shù)據(jù)的處理,提供更高級的功能,如自動掃描、注解驅(qū)動等。

  4. Spring AOP:

    • BeanFactory需要手動將AspectJ代理工廠(AspectJProxyFactory)應(yīng)用于Bean,才能支持Spring AOP。

    • ApplicationContext自動為Bean提供代理,支持Spring AOP。

  5. 國際化支持:

    • ApplicationContext提供了更方便的國際化(i18n)支持,可以基于ResourceBundle實現(xiàn)多語言切換。

總的來說,BeanFactory是更基礎(chǔ)的接口,提供了最基本的IoC容器功能;而ApplicationContext是BeanFactory的擴展,提供了更多的功能和便利性,是在實際應(yīng)用中更常用的接口。如果需要更完整的功能,如AOP、國際化、事件發(fā)布等,那么建議使用ApplicationContext。但是,如果對資源要求較低,且只需要基本的Bean管理功能,可以使用BeanFactory來獲得更輕量級的容器。

簡述spring bean的生命周期?

  1. 實例化(Instantiation):

    • Bean的實例化是通過構(gòu)造函數(shù)或工廠方法創(chuàng)建的。

    • 可以在此階段進行一些前置處理,容器會在初始化Bean之前先調(diào)用BeanPostProcessor的postProcessBeforeInitialization()方法。

  2. 屬性設(shè)置(Population):

    • Spring通過依賴注入(DI)將Bean的屬性進行設(shè)置。

    • 可以在此階段進行一些屬性相關(guān)的操作,如使用@Autowired、@Value等注解進行屬性注入和賦值。

  3. 初始化(Initialization):

    • 在Bean的所有屬性被設(shè)置完后,可以執(zhí)行自定義的初始化邏輯。

    • 可以通過實現(xiàn)InitializingBean接口的afterPropertiesSet方法或使用@PostConstruct注解進行初始化操作。

    • 可以在此階段進行一些初始化相關(guān)的操作,如連接數(shù)據(jù)庫、讀取配置文件等。

    • BeanPostProcessor的后置處理:如果在容器中定義了BeanPostProcessor,容器會在初始化Bean之后調(diào)用BeanPostProcessor的postProcessAfterInitialization()方法。

  4. 使用(In Use):

    • Bean可以在應(yīng)用程序中正常使用,處理業(yè)務(wù)邏輯。

    • Bean會一直處于使用狀態(tài),直到應(yīng)用程序關(guān)閉或Bean被銷毀。

  5. 銷毀(Destruction):

    • 當應(yīng)用程序關(guān)閉或手動銷毀Bean時,會執(zhí)行銷毀階段的邏輯。

    • 可以通過實現(xiàn)DisposableBean接口的destroy方法或使用@PreDestroy注解進行銷毀操作。

    • 可以在此階段進行一些資源釋放、清理工作,如關(guān)閉數(shù)據(jù)庫連接、釋放文件句柄等。

值得注意的是,對于單例作用域的Bean,默認情況下,Spring容器在啟動時會將所有單例Bean進行實例化和初始化,并在容器關(guān)閉時銷毀它們;而對于原型作用域的Bean,Spring容器僅負責實例化和初始化,不負責銷毀,需要由調(diào)用者自行管理。

通過在Bean上實現(xiàn)相應(yīng)的接口或使用注解,可以對Bean的生命周期進行自定義操作,從而滿足應(yīng)用程序的需求。

spring支持的bean作用域有哪些?

  1. Singleton(默認):

    • 單例作用域,每個Spring容器只創(chuàng)建一個實例。

    • 多個Bean引用同一個實例。

    • 適用于無狀態(tài)的Bean和共享資源的情況。

  2. Prototype:

    • 原型作用域,每次從容器中獲取Bean時都會創(chuàng)建一個新的實例。

    • 每個Bean引用不同的實例。

    • 適用于有狀態(tài)的Bean和非共享資源的情況。

  3. Request:

    • 請求作用域,每個HTTP請求都會創(chuàng)建一個新的實例。

    • 每個請求期間的所有Bean引用同一個實例。

    • 適用于Web應(yīng)用程序中需要在每個請求期間共享數(shù)據(jù)的情況。

  4. Session:

    • 會話作用域,每個用戶會話都會創(chuàng)建一個新的實例。

    • 每個用戶會話期間的所有Bean引用同一個實例。

    • 適用于Web應(yīng)用程序中需要在每個用戶會話期間共享數(shù)據(jù)的情況。

  5. Global session(僅適用于Portlet環(huán)境):

    • 全局會話作用域,每個Portlet應(yīng)用程序的全局會話都會創(chuàng)建一個新的實例。

    • 每個全局會話期間的所有Bean引用同一個實例。

  6. WebSocket(僅適用于WebSocket環(huán)境):

    • WebSocket作用域,每個WebSocket會話都會創(chuàng)建一個新的實例。

    • 每個WebSocket會話期間的所有Bean引用同一個實例。

可以通過在Spring的Bean聲明中使用@Scope注解或在XML配置文件中使用<bean>元素的scope屬性來設(shè)置Bean的作用域。例如:

@Component
@Scope("prototype")
public class MyPrototypeBean {// ...
}

或者在XML配置中:

<bean id="myPrototypeBean" class="com.example.MyPrototypeBean" scope="prototype"/>

根據(jù)應(yīng)用程序的需求,選擇適合的作用域可以更好地控制Bean的生命周期和資源管理。

Spring框架中的單例Bean是線程安全的么?

spring只是一中容器,需要看有沒有對bean進行多線程處理

Spring中的Bean對象默認是單例的,框架并沒有對bean進行多線程的封裝處理

如果Bean是有狀態(tài)的

無狀態(tài)就是不會存儲數(shù)據(jù),你想一下,我們的controller,service和dao本身并不是線程安全的,只是調(diào)用里面的方法,而且多線程調(diào)用一個實例的方法,會在內(nèi)存中復(fù)制遍歷,這是自己線程的工作內(nèi)存,是最安全的。

因此在進行使用的時候,不要在bean中聲明任何有狀態(tài)的實例變量或者類變量,如果必須如此,也推薦大家使用ThreadLocal把變量變成線程私有,如果bean的實例變量或者類變量需要在多個線程之間共享,那么就只能使用synchronized,lock,cas等這些實現(xiàn)線程同步的方法了。

spring框架中使用了哪些設(shè)計模式及應(yīng)用場景

1.工廠模式,在各種BeanFactory以及ApplicationContext創(chuàng)建中都用到了

2.模版模式,在各種BeanFactory以及ApplicationContext實現(xiàn)中也都用到了

3.代理模式,Spring AOP 利用了 AspectJ AOP實現(xiàn)的! AspectJ AOP 的底層用了動態(tài)代理

4.策略模式,加載資源文件的方式,使用了不同的方法,比如:ClassPathResourece,FileSystemResource,ServletContextResource,UrlResource但他們都有共同的借口Resource;在Aop的實現(xiàn)中,采用了兩種不同的方式,JDK動態(tài)代理和CGLIB代理

5.單例模式,比如在創(chuàng)建bean的時候。

6.觀察者模式,spring中的ApplicationEvent,ApplicationListener,ApplicationEventPublisher

7.適配器模式,MethodBeforeAdviceAdapter,ThrowsAdviceAdapter,AfterReturningAdapter

8.裝飾者模式,源碼中類型帶Wrapper或者Decorator的都是

spring事務(wù)的實現(xiàn)方式原理是什么?

在使用Spring框架的時候,可以有兩種事務(wù)的實現(xiàn)方式,一種是編程式事務(wù),有用戶自己通過代碼來控制事務(wù)的處理邏輯,還有一種是聲明式事務(wù),通過@Transactional注解來實現(xiàn)。

在 Spring 中,事務(wù)的實現(xiàn)方式主要依賴于兩個核心概念:事務(wù)管理器(Transaction Manager)和代理模式。

  1. 事務(wù)管理器(Transaction Manager):Spring 提供了多個事務(wù)管理器的實現(xiàn),例如 DataSourceTransactionManager、JpaTransactionManager 等。事務(wù)管理器負責管理事務(wù)的開始、提交、回滾等操作。它與底層的數(shù)據(jù)庫、ORM 框架或其他事務(wù)資源進行交互,確保事務(wù)的正確執(zhí)行。

  2. 代理模式:Spring 使用 AOP(面向切面編程)和代理模式來實現(xiàn)事務(wù)。當方法被標注為事務(wù)性時,Spring 會動態(tài)地生成一個代理類來包裝該方法,代理類負責增加額外的邏輯,如事務(wù)的管理。

工作原理如下:

  1. 通過配置事務(wù)管理器,將其與當前的數(shù)據(jù)源或其他事務(wù)資源進行關(guān)聯(lián)。

  2. 在配置文件或注解中對需要進行事務(wù)管理的方法進行標注 @Transactional。

  3. 當標注的方法被調(diào)用時,Spring 會通過動態(tài)代理機制生成一個代理類,并在代理類中添加事務(wù)管理的邏輯。代理類會攔截方法的調(diào)用,并在方法執(zhí)行前后執(zhí)行事務(wù)的開啟、提交或回滾等操作。

  4. 根據(jù)配置的事務(wù)屬性,事務(wù)管理器會根據(jù)方法的執(zhí)行結(jié)果決定事務(wù)的提交或回滾。

具體的實現(xiàn)機制包括:

  • 事務(wù)的劃分:通過注解或配置方式,標識哪些方法需要進行事務(wù)管理。

  • 事務(wù)的邊界控制:Spring 會在適當?shù)臅r機開始一個事務(wù)(如方法開始時)和結(jié)束一個事務(wù)(如方法結(jié)束時)。

  • 事務(wù)的隔離級別與傳播行為控制:通過設(shè)置事務(wù)的隔離級別(如讀未提交、讀已提交等)和傳播行為(如支持當前事務(wù)、新建事務(wù)等),對事務(wù)進行精確控制。

  • 異常處理與事務(wù)回滾:對于出現(xiàn)異常的情況,根據(jù)配置的事務(wù)屬性決定是否回滾事務(wù)。如果方法內(nèi)部拋出了受檢查異常,Spring 默認會回滾事務(wù);如果拋出非受檢查異常,則根據(jù)異常類型決定是否回滾。

通過以上的機制和流程,Spring 能夠提供基于代理的事務(wù)管理功能,將事務(wù)的管理與具體業(yè)務(wù)邏輯解耦,使得事務(wù)管理更加靈活、方便和可控。

Transaction失效

1、bean對象沒有被spring容器管理

2、方法的訪問修飾符不是public

3、自身調(diào)用問題

4、數(shù)據(jù)源沒有配置事務(wù)管理器

5、數(shù)據(jù)庫不支持事務(wù)

6、異常被捕獲

7、異常類型錯誤或者配置錯誤

spring事務(wù)的隔離級別有哪些?

spring中的事務(wù)隔離級別就是數(shù)據(jù)庫的隔離級別,有以下幾種:

read uncommitted

read committed

repeatable read

serializable

在進行配置的時候,如果數(shù)據(jù)庫和spring代碼中的隔離級別不同,那么以spring的配置為主。

spring的事務(wù)傳播機制是什么?

Spring的事務(wù)傳播(Transaction Propagation)機制定義了在多個事務(wù)方法相互調(diào)用時,事務(wù)是如何傳播和管理的。事務(wù)傳播機制主要用于控制事務(wù)的邊界和隔離級別,以保證數(shù)據(jù)的一致性和完整性。

Spring框架定義了以下幾種事務(wù)傳播行為:

1、propagation_required:支持當前事務(wù),無事務(wù),另起新事物
2、propagation_required-new:新建事務(wù),若有舊事務(wù),掛起。
3、propagation_supports:支持當前事務(wù),無事務(wù),以非事務(wù)執(zhí)行
4、propagation_mandatory:以事務(wù)方式執(zhí)行,無事務(wù),拋異常
5、propagation_not_supported:不支持事務(wù),如有事務(wù),掛起
6、propagation_never:以非事務(wù)執(zhí)行,有事務(wù),拋異常
7、propagation_nested:內(nèi)切事務(wù)

這些事務(wù)傳播行為可以通過在方法上使用 @Transactional 注解來指定。例如:

@Transactional(propagation = Propagation.REQUIRED)
public void doSomething() {// 執(zhí)行業(yè)務(wù)邏輯
}

需要注意的是,事務(wù)的傳播行為只在嵌套方法調(diào)用中生效,對于同一個類中的不同方法調(diào)用,事務(wù)傳播行為不起作用。在開發(fā)過程中,根據(jù)業(yè)務(wù)需求和實際情況選擇適合的事務(wù)傳播行為可以有效地保證數(shù)據(jù)的一致性和完整性。

NESTED和REQUIRED_NEW的區(qū)別:

REQUIRED_NEW是新建一個事務(wù)并且新開始的這個事務(wù)與原有事務(wù)無關(guān),而NESTED則是當前存在事務(wù)時會開啟一個嵌套事務(wù),在NESTED情況下,父事務(wù)回滾時,子事務(wù)也會回滾,而REQUIRED_NEW情況下,原有事務(wù)回滾,不會影響新開啟的事務(wù)

NESTED和REQUIRED的區(qū)別:

REQUIRED情況下,調(diào)用方存在事務(wù)時,則被調(diào)用方和調(diào)用方使用同一個事務(wù),那么被調(diào)用方出現(xiàn)異常時,由于共用一個事務(wù),所以無論是否catch異常,事務(wù)都會回滾,而在NESTED情況下,被調(diào)用方發(fā)生異常時,調(diào)用方可以catch其異常,這樣只有子事務(wù)回滾,父事務(wù)不會回滾。

spring事務(wù)什么時候會失效?

在Spring框架中,事務(wù)的失效可能由以下情況引起:

  1. 未開啟事務(wù):在方法上沒有使用@Transactional注解或在XML配置中未配置事務(wù)管理器和事務(wù)攔截器時,事務(wù)將不會開啟,即使方法中出現(xiàn)數(shù)據(jù)庫操作也不會有事務(wù)支持。

  2. 異常未被捕獲:當在事務(wù)范圍內(nèi)的方法拋出未被捕獲的異常時,默認情況下事務(wù)將回滾。但是,如果異常被捕獲并處理(例如通過try-catch塊),那么事務(wù)將不會回滾。

  3. 不受事務(wù)管理的方法調(diào)用:如果在具有事務(wù)的方法內(nèi)部調(diào)用了另一個沒有使用@Transactional注解的方法,則被調(diào)用方法不會繼承事務(wù),即事務(wù)將被掛起,它將在調(diào)用返回后恢復(fù)。

  4. 事務(wù)邊界不一致:當在一個方法中通過注解配置的事務(wù)與使用編程式事務(wù)管理方式(通過TransactionTemplatePlatformTransactionManager)管理的事務(wù)混合使用時,事務(wù)可能會失效。這是因為Spring無法同時應(yīng)用兩種不同的事務(wù)管理方式。

  5. ThreadLocal問題:如果使用了并發(fā)編程中的ThreadLocal,例如在事務(wù)中使用了ThreadLocal保存狀態(tài),那么在多線程環(huán)境下,由于線程切換可能導(dǎo)致線程間的狀態(tài)共享問題,從而破壞了事務(wù)的一致性。

  6. 方法級別的調(diào)用問題:如果在同一個類中的一個使用@Transactional注解的方法調(diào)用了同一個類中另一個沒有使用注解的方法,事務(wù)將無法正常生效,因為Spring使用代理對象來管理事務(wù),而調(diào)用同一個類中的方法將不會經(jīng)過代理,導(dǎo)致事務(wù)失效。

需注意的是,事務(wù)失效并不是Spring框架的設(shè)計缺陷,而是由于使用不當或特定的情況下引起的。為了確保事務(wù)的正常工作,請確保在使用事務(wù)時遵循相關(guān)的最佳實踐,并注意上述可能導(dǎo)致事務(wù)失效的情況。

什么的是bean的自動裝配,它有哪些方式?

Bean的自動裝配是指Spring容器在創(chuàng)建Bean時,自動地根據(jù)特定規(guī)則在上下文中尋找匹配的依賴項,并將其注入到Bean中。這樣可以減少配置文件的編寫,提高開發(fā)效率,減少開發(fā)人員的工作量。

Spring框架支持以下幾種Bean的自動裝配方式:

1. **no(默認):** 不使用自動裝配,手動指定依賴注入的方式(通過構(gòu)造器、setter方法等)。

2. **byName:** 根據(jù)bean的名稱進行自動裝配,Spring容器在上下文中查找與屬性名稱匹配的bean,然后進行注入。

3. **byType:** 根據(jù)bean的類型進行自動裝配,Spring容器在上下文中查找與屬性類型匹配的bean,然后進行注入。如果匹配的bean有多個,則拋出異常。

4. **constructor:** 類似于byType,但是是應(yīng)用于構(gòu)造器參數(shù)的自動裝配方式。

5. **autodetect:** Spring根據(jù)情況自動選擇合適的自動裝配方式,該方式會先byType,如果找不到則會byName。

自動裝配可以通過在XML配置文件中的`<bean>`標簽的`autowire`屬性來指定,也可以通過使用注解(如`@Autowired`、`@Resource`)來實現(xiàn)。在XML配置文件中使用自動裝配的示例如下:

```xml
<bean id="beanA" class="com.example.BeanA" autowire="byName|byType|constructor|autodetect"/>
```

使用注解來實現(xiàn)自動裝配的示例如下:


@Component
public class BeanA {
? ? @Autowired
? ? private BeanB beanB;

? ? // Getter and Setter
}

通過配置自動裝配方式,Spring容器能夠根據(jù)預(yù)定義的規(guī)則來自動解決Bean之間的依賴關(guān)系,簡化了配置工作。開發(fā)人員可以根據(jù)實際情況選擇合適的自動裝配方式,提高了代碼的靈活性和可維護性。

spring是如何解決循環(huán)依賴的

Spring 在解決循環(huán)依賴時使用了三級緩存,分別是 singletonFactories、earlySingletonObjects 和 singletonObjects。這些緩存的使用可以幫助Spring在解決循環(huán)依賴問題時進行控制和管理。

  1. singletonFactories:在單例模式下,當 Spring 創(chuàng)建 Bean 時,如果發(fā)現(xiàn)該 Bean 正在創(chuàng)建中,它會將這個創(chuàng)建中的 Bean 存儲在 singletonFactories 緩存中。這樣可以用來檢測循環(huán)依賴。

  2. earlySingletonObjects:當 Bean 的實例化完成但尚未完成初始化時,該 Bean 會被存儲在 earlySingletonObjects 中。這樣可以確保其他 Bean 在初始化時可以引用到這些尚未初始化的 Bean。

  3. singletonObjects:一旦 Bean 創(chuàng)建完成并完成初始化后,Spring 將會將其存儲在 singletonObjects 緩存中。這樣其他的 Bean 可以直接引用到已經(jīng)初始化完成的 Bean 實例。

Spring 解決循環(huán)依賴的方法是通過依賴注入的過程中使用對象的代理。當發(fā)現(xiàn)循環(huán)依賴時,Spring 會創(chuàng)建一個提前暴露的、尚未完全初始化的代理對象作為依賴項,以滿足對象之間的交叉引用。

具體的解決流程如下:

  1. 當 Spring 容器初始化時,創(chuàng)建 Bean A 的過程中發(fā)現(xiàn)了循環(huán)依賴,需要解決 A 依賴于 B,而 B 又依賴于 A 的情況。

  2. 將正在創(chuàng)建 Bean A 的對象實例放入 singletonFactories 緩存中,表示該 Bean A 目前正在創(chuàng)建中。

  3. 接著創(chuàng)建 Bean B 的過程中,發(fā)現(xiàn) B 依賴于 A,但 A 正在創(chuàng)建中,因此從 singletonFactories 緩存中獲取正在創(chuàng)建的 Bean A 的對象實例。

  4. 當 Bean A 創(chuàng)建完成但尚未完成初始化時,將其放入 earlySingletonObjects 緩存中,表示 Bean A 已經(jīng)實例化但尚未初始化。

  5. 繼續(xù)創(chuàng)建 Bean B,并注入 Bean A 的未完成初始化的實例。

  6. 最后完成 Bean A 和 Bean B 的創(chuàng)建和初始化后,將 Bean A 和 Bean B 放入 singletonObjects 緩存中,表示它們是已經(jīng)創(chuàng)建完成和初始化的 Bean 實例。

需要注意的是,雖然 Spring 能夠解決大多數(shù)情況下的循環(huán)依賴,但如果存在循環(huán)鏈,即 A 依賴于 B,B 依賴于 C,C 又依賴于 A,則 Spring 將無法解決這種循環(huán)依賴關(guān)系,會拋出 BeanCurrentlyInCreationException 異常。

總結(jié)一下,Spring 解決循環(huán)依賴的方式是通過提前暴露半初始化的代理對象,以滿足循環(huán)依賴關(guān)系中的引用,然后在完成所有 Bean 的創(chuàng)建和初始化后,將代理對象替換為實際對象。這樣就能夠成功解決循環(huán)依賴的問題。

不能解決的幾種循環(huán)依賴

  1. 構(gòu)造函數(shù)循環(huán)依賴:如果Bean之間存在構(gòu)造函數(shù)注入,且存在循環(huán)依賴,Spring容器無法解決這種循環(huán)依賴,會拋出BeanCurrentlyInCreationException異常。

  2. 原型Bean循環(huán)依賴:如果兩個原型Bean之間存在循環(huán)依賴,Spring容器無法解決這種循環(huán)依賴,因為原型Bean每次獲取都會創(chuàng)建新的對象實例,無法緩存起來,也無法通過代理對象解決。

  3. @Async增強的bean循環(huán)依賴

pring中常見的幾種注解

Spring 框架中常見的注解包括但不限于:

  1. @Component:用于表示一個類是 Spring 容器管理的組件,通常與其他注解配合使用,如 @Repository、@Service、@Controller 等。

  2. @Autowired:標記在字段、構(gòu)造器、方法或者參數(shù)上,用于實現(xiàn)自動裝配,通過類型匹配進行依賴注入。

  3. @Qualifier:與 @Autowired 配合使用,在存在多個具有相同類型的實例時,通過指定名稱來選擇具體的實例進行注入。

  4. @Value:用于注入簡單屬性值,支持 SpEL 表達式,例如 @Value("${app.title}")

  5. @Configuration:標記在配置類上,表示該類是 Spring 的配置類,會告訴 Spring 應(yīng)用上下文去加載 Bean 定義。

  6. @Bean:標記在方法上,將方法的返回對象注冊為一個 Bean,該對象會被 Spring IoC 容器管理。

  7. @ComponentScan:配置包掃描路徑,用于自動掃描并注冊標記有 @Component 的類作為 Spring Bean。

  8. @RequestMapping:定義請求 URL 映射,用于處理 Web 請求,通常用在 Controller 類的方法上。

  9. @Service、@Repository、@Controller:用于添加更多細分類型的組件注解,讓 Spring 在掃描注解時能更清楚地區(qū)分各種組件類型。

  10. @Scope:定義 Bean 的作用域,例如 Singleton、Prototype、Request、Session 等。

  11. @Aspect、@Pointcut、@Before、@After@Around、@AfterReturning@AfterThrowing:用于定義切面和通知的注解,實現(xiàn)面向切面編程(AOP)。

  12. @Transactional:用于聲明事務(wù)處理的方法或類,標注在方法或類上,指明該方法或類需要進行事務(wù)處理。

這些注解是 Spring 框架中常見且重要的注解,它們能夠幫助我們簡化配置、實現(xiàn)依賴注入、定義 Bean、處理 Web 請求、實現(xiàn)事務(wù)管理等。

當然,還有更多在 Spring 框架中常見和常用的注解:

  1. @RequestMapping:在控制器類或方法上使用,用于映射 Web 請求的 URL 路徑和處理方法。

  2. @PathVariable:在方法參數(shù)上使用,用于從請求的 URL 中獲取路徑變量的值。

  3. @RequestParam:在方法參數(shù)上使用,用于從請求的參數(shù)中獲取值。

  4. @RequestHeader:在方法參數(shù)上使用,用于從請求頭中獲取值。

  5. @ResponseBody:通常在控制器方法上使用,用于將方法返回的對象轉(zhuǎn)換為指定的響應(yīng)格式(如 JSON)并作為響應(yīng)返回。

  6. @ModelAttribute:用于綁定請求參數(shù)到方法參數(shù)或方法的返回對象。

  7. @Valid:通常結(jié)合 JSR-303 標準的驗證注解一起使用,用于驗證方法參數(shù)或方法返回對象的數(shù)據(jù)的合法性。

  8. @InitBinder:用于配置用于表單數(shù)據(jù)綁定的 WebDataBinder,通常用于注冊自定義的屬性編輯器或驗證器。

  9. @RestController:一個方便的組合注解,結(jié)合了 @Controller@ResponseBody,用于定義 RESTful 風(fēng)格的控制器。

  10. @ConfigurationProperties:用于將屬性綁定到配置類中的屬性上,可以用于統(tǒng)一管理項目的配置參數(shù)。

  11. @Async:標記在方法上,允許方法異步執(zhí)行,可以提升系統(tǒng)的性能和并發(fā)處理能力。

  12. @Enable* 系列注解:如 @EnableCaching、@EnableScheduling@EnableAsync 等,用于啟用相應(yīng)的特性或功能。

這些注解在不同的場景中扮演著重要的角色,讓我們能夠更便捷地進行開發(fā)和配置,減少了大量的樣板代碼和配置工作。它們?yōu)?Spring 提供了更強大的功能和靈活性,簡化了開發(fā)過程。

spring、springmvc、springboot的區(qū)別是什么?

spring和springMvc:

  1. spring是一個一站式的輕量級的java開發(fā)框架,核心是控制反轉(zhuǎn)(IOC)和面向切面(AOP),針對于開發(fā)的WEB層(springMvc)、業(yè)務(wù)層(Ioc)、持久層(jdbcTemplate)等都提供了多種配置解決方案;

  2. springMvc是spring基礎(chǔ)之上的一個MVC框架,主要處理web開發(fā)的路徑映射和視圖渲染,屬于spring框架中WEB層開發(fā)的一部分;

springMvc和springBoot:

1、springMvc屬于一個企業(yè)WEB開發(fā)的MVC框架,涵蓋面包括前端視圖開發(fā)、文件配置、后臺接口邏輯開發(fā)等,XML、config等配置相對比較繁瑣復(fù)雜;

2、springBoot框架相對于springMvc框架來說,更專注于開發(fā)微服務(wù)后臺接口,不開發(fā)前端視圖,同時遵循默認優(yōu)于配置,簡化了插件配置流程,不需要配置xml,相對springmvc,大大簡化了配置流程;

總結(jié):

1、Spring 框架就像一個家族,有眾多衍生產(chǎn)品例如 boot、security、jpa等等。但他們的基礎(chǔ)都是Spring的ioc、aop等. ioc 提供了依賴注入的容器, aop解決了面向橫切面編程,然后在此兩者的基礎(chǔ)上實現(xiàn)了其他延伸產(chǎn)品的高級功能;

2、springMvc主要解決WEB開發(fā)的問題,是基于Servlet 的一個MVC框架,通過XML配置,統(tǒng)一開發(fā)前端視圖和后端邏輯;

3、由于Spring的配置非常復(fù)雜,各種XML、JavaConfig、servlet處理起來比較繁瑣,為了簡化開發(fā)者的使用,從而創(chuàng)造性地推出了springBoot框架,默認優(yōu)于配置,簡化了springMvc的配置流程;但區(qū)別于springMvc的是,springBoot專注于單體微服務(wù)接口開發(fā),和前端解耦,雖然springBoot也可以做成springMvc前后臺一起開發(fā),但是這就有點不符合springBoot框架的初衷了;

springmvc工作流程是什么?

當發(fā)起請求時被前置的控制器攔截到請求,根據(jù)請求參數(shù)生成代理請求,找到請求對應(yīng)的實際控制器,控制器處理請求,創(chuàng)建數(shù)據(jù)模型,訪問數(shù)據(jù)庫,將模型響應(yīng)給中心控制器,控制器使用模型與視圖渲染視圖結(jié)果,將結(jié)果返回給中心控制器,再將結(jié)果返回給請求者。

1、DispatcherServlet表示前置控制器,是整個SpringMVC的控制中心。用戶發(fā)出請求,DispatcherServlet接收請求并攔截請求。

2、HandlerMapping為處理器映射。DispatcherServlet調(diào)用HandlerMapping,HandlerMapping根據(jù)請求url查找Handler。

3、返回處理器執(zhí)行鏈,根據(jù)url查找控制器,并且將解析后的信息傳遞給DispatcherServlet

4、HandlerAdapter表示處理器適配器,其按照特定的規(guī)則去執(zhí)行Handler。

5、執(zhí)行handler找到具體的處理器

6、Controller將具體的執(zhí)行信息返回給HandlerAdapter,如ModelAndView。

7、HandlerAdapter將視圖邏輯名或模型傳遞給DispatcherServlet。

8、DispatcherServlet調(diào)用視圖解析器(ViewResolver)來解析HandlerAdapter傳遞的邏輯視圖名。 9、視圖解析器將解析的邏輯視圖名傳給DispatcherServlet。

10、DispatcherServlet根據(jù)視圖解析器解析的視圖結(jié)果,調(diào)用具體的視圖,進行試圖渲染

11、將響應(yīng)數(shù)據(jù)返回給客戶端

springmvc的九大組件有哪些?

Spring MVC(Model-View-Controller)是一個基于Java的MVC框架,用于開發(fā)Web應(yīng)用程序。下面是Spring MVC的九大組件:

  1. DispatcherServlet(調(diào)度器):是Spring MVC的核心組件,接收客戶端的請求并將其分派給相應(yīng)的處理器。

  2. HandlerMapping(處理器映射器):負責根據(jù)請求的URL映射到相應(yīng)的處理器(Controller)。

  3. HandlerAdapter(處理器適配器):將處理器(Controller)適配為一個能夠處理請求的處理器對象,并調(diào)用其處理方法。

  4. HandlerInterceptor(處理器攔截器):對請求進行預(yù)處理和后處理。在請求被調(diào)度到處理器之前和之后,可以執(zhí)行一些公共的任務(wù),如身份驗證、日志記錄等。

  5. ViewResolver(視圖解析器):根據(jù)邏輯視圖名(View Name)解析視圖對象,可以是JSP、Thymeleaf、Freemarker等等。

  6. View(視圖):負責渲染模型數(shù)據(jù),并將其呈現(xiàn)給用戶。常見的視圖技術(shù)包括JSP、HTML、JSON等。

  7. ModelAndView(模型和視圖):將模型數(shù)據(jù)與視圖對象封裝在一起,以便向視圖傳遞數(shù)據(jù)并指示要呈現(xiàn)的視圖。

  8. HandlerExceptionResolver(異常解析器):處理請求過程中產(chǎn)生的異常。將異常轉(zhuǎn)換為統(tǒng)一的錯誤視圖或錯誤消息。

  9. MultipartResolver(多部分解析器):處理文件上傳請求,解析多部分請求,獲取上傳的文件和表單數(shù)據(jù)。

這些組件共同協(xié)作,使得Spring MVC能夠接收、處理和響應(yīng)客戶端的請求,并以MVC模式將應(yīng)用程序的邏輯、數(shù)據(jù)和視圖進行了清晰的分離。

Spring框架中有哪些不同類型的事件

Spring 提供了以下5種標準的事件:

上下文更新事件(ContextRefreshedEvent):在調(diào)用ConfigurableApplicationContext 接口中的refresh()方法時被觸發(fā)。

上下文開始事件(ContextStartedEvent):當容器調(diào)用ConfigurableApplicationContext的Start()方法開始/重新開始容器時觸發(fā)該事件。

上下文停止事件(ContextStoppedEvent):當容器調(diào)用ConfigurableApplicationContext的Stop()方法停止容器時觸發(fā)該事件。

上下文關(guān)閉事件(ContextClosedEvent):當ApplicationContext被關(guān)閉時觸發(fā)該事件。容器被關(guān)閉時,其管理的所有單例Bean都被銷毀。

請求處理事件(RequestHandledEvent):在Web應(yīng)用中,當一個http請求(request)結(jié)束觸發(fā)該事件。如果一個bean實現(xiàn)了ApplicationListener接口,當一個ApplicationEvent 被發(fā)布以后,bean會自動被通知。

http://www.risenshineclean.com/news/47024.html

相關(guān)文章:

  • 知名高端網(wǎng)站設(shè)計企業(yè)百度網(wǎng)站檢測
  • 卡盟網(wǎng)站怎么做圖片素材網(wǎng)站seo方法
  • 網(wǎng)站搜索怎么做常見的網(wǎng)絡(luò)營銷推廣方式有哪些
  • 建程網(wǎng)app下載西安seo和網(wǎng)絡(luò)推廣
  • 便宜 虛擬主機sem 優(yōu)化軟件
  • 基金管理公司司網(wǎng)站建設(shè)要求國際新聞今天
  • wordpress扒站工具北京網(wǎng)站制作公司
  • 網(wǎng)站建設(shè)價錢差異外貿(mào)接單平臺哪個最好
  • 做網(wǎng)站如何導(dǎo)入信用卡付款一個產(chǎn)品的市場營銷策劃方案
  • ??诰W(wǎng)站開發(fā)公司電話建立一個網(wǎng)站的費用
  • 杭州濱江網(wǎng)站建設(shè)公司信息流優(yōu)化師面試常見問題
  • go 是做網(wǎng)站的嗎廣州seo推薦
  • 網(wǎng)站開發(fā)知識體系推廣普通話的意義簡短
  • 尋花問柳專注做一家男人愛的網(wǎng)站百度云網(wǎng)盤資源搜索
  • 網(wǎng)絡(luò)營銷做私活網(wǎng)站智慧軟文發(fā)稿平臺官網(wǎng)
  • asp.net 網(wǎng)站備份免費域名注冊網(wǎng)站
  • 做網(wǎng)站抄代碼免費seo軟件
  • 建設(shè)網(wǎng)站制作網(wǎng)站營銷方案模板
  • 大連今天最新通知電商運營seo
  • 哈爾濱網(wǎng)站設(shè)計有哪些步驟寧波網(wǎng)站推廣聯(lián)系方式
  • 企業(yè)網(wǎng)站基本信息早教優(yōu)化深圳seo
  • 福建省做鞋批發(fā)網(wǎng)站百度開放云平臺
  • 官方網(wǎng)站首頁在線seo推廣軟件
  • php怎么做多個網(wǎng)站網(wǎng)站關(guān)鍵詞快速排名技術(shù)
  • 河北建設(shè)集團官網(wǎng)如何做好seo基礎(chǔ)優(yōu)化
  • 一級a做片性視頻.網(wǎng)站在線觀看鄭州seo排名第一
  • 寵物寄養(yǎng)網(wǎng)站畢業(yè)設(shè)計重慶百度關(guān)鍵詞優(yōu)化軟件
  • 網(wǎng)站建設(shè)公司排名搜索大全
  • 鄂州做網(wǎng)站報價谷歌搜索引擎免費入口鏡像
  • 廈門企業(yè)網(wǎng)站建設(shè)補貼百度官網(wǎng)首頁網(wǎng)址