<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      技術面:Spring (bean的生命周期、創建方式、注入方式、作用域)

      Spring Bean的生命周期是什么樣的?

      在Spring容器里一個Bean的從創建到銷毀一般都是經歷了以下幾個階段:
      定義階段(Bean元信息配置)=>實例化階段(創建Bean對象)=>初始化階段(執行初始化邏輯)=>使用階段(Bean可用)=>銷毀階段(釋放資源)
      Spring bean的生命周期

      定義階段(BeanDefinition解析)

      Spring通過配置(XML、注解、Java配置)解析Bean的元數據,生成BeanDefinition對象
      BeanDefinition存儲了Bean的類名、作用域(scope)、依賴項(depends-on)、初始化方法、銷毀方法等元數據。
      所有BeanDefinition存儲在容器的BeanDefinitionMap(一個HashMap)中,鍵為Bean名稱,值為BeanDefinition對象。
      解析器:

      • XML配置:XmlBeanDefinitionReader解析<bean>標簽。
      • 注解配置:ClassPathBeanDefinitionScanner掃描@Component等注解。
      • Java配置:ConfigurationClassPostProcessor解析@Bean方法。

      實例化階段(創建Bean實例)

      根據BeanDefinition通過反射或工廠方法創建Bean實例(對象),但此時屬性未注入
      默認通過無參構造方法實例化(若未指定,Spring會強制要求無參構造)。

      AbstractAutowireCapableBeanFactory類中的createBeanInstance方法中實現。

      屬性值填充(依賴注入)

      為Bean的屬性設置值或注入依賴

      • 通過@Autowired@ValueXML<property>等方式注入屬性。
      • 若注入的依賴是其他Bean,會遞歸觸發依賴Bean的生命周期。
      • 循環依賴問題:在屬性注入階段處理循環依賴(通過三級緩存解決)。

      AbstractAutowireCapableBeanFactorypopulateBean方法中處理。

      Aware接口回調設置

      若Bean實現了特定Aware接口,Spring會回調對應方法,注入容器相關對象

      • BeanNameAware:注入Bean在容器中的名稱(setBeanName(String beanName))。
      • BeanFactoryAware:注入當前Bean所在的BeanFactory(setBeanFactory(BeanFactory beanFactory))。
      • ApplicationContextAware:若容器是ApplicationContext,注入應用上下文(setApplicationContext(ApplicationContext applicationContext))。

      AbstractAutowireCapableBeanFactoryinitializeBean方法中調用。

      BeanPostProcessor前置處理

      在Bean初始化前,允許自定義BeanPostProcessor對Bean實例進行處理。
      主要是調用BeanPostProcessorpostProcessBeforeInitialization方法。
      常見的實現類

      • ApplicationContextAwareProcessor:處理ApplicationContextAware接口。
      • InitDestroyAnnotationBeanPostProcessor:處理@PostConstruct注解。

      AbstractAutowireCapableBeanFactoryapplyBeanPostProcessorsBeforeInitialization方法執行。

      InitializingBean處理以及自定義init-method處理

      執行Bean的初始化邏輯。
      InitializingBean處理,在所有Bean屬性設置完成后進行初始化操作。如果Bean實現了InitializingBean接口,InitializingBeanafterPropertiesSet方法會被調用。

      自定義init-method處理,如果Bean在配置文件中定義了初始化方法那么該方法會被調用。
      例如:通過XML配置init-method或Java配置@Bean(initMethod="xxx")。

      AbstractAutowireCapableBeanFactoryinvokeInitMethods方法中調用

      BeanPostProcessor后置處理

      在Bean初始化后,允許自定義BeanPostProcessor對Bean實例進行處理。
      BeanPostProcessorpostProcessAfterInitialization方法會被調用。

      常見用途:AOP代理(如AbstractAutoProxyCreator在此階段為目標對象創建代理)

      AbstractAutowireCapableBeanFactoryapplyBeanPostProcessorsAfterInitialization方法執行

      注冊DisposableBean回調

      如果Bean實現了DisposableBean接口或在Bean定義中指定了自定義的銷毀方法,Spring容器會為這些Bean注冊一個銷毀回調,確保在容器關閉時能夠正確地清理資源。

      AbstractAutowireCapableBeanFactory類中的registerDisposableBeanlfNecessary方法中實現

      Bean使用階段

      Bean已完全初始化,可被應用程序使用。通過依賴注入獲取Bean實例(如@AutowiredApplicationContext.getBean())。
      此階段Bean處于“可用”狀態,直到容器關閉。

      Bean銷毀階段

      容器關閉時,釋放Bean資源。
      主要步驟:

      • 接口回調:若Bean實現了DisposableBean,調用destroy方法。
      • 注解:若方法標注了@PreDestroy,Spring會調用該方法。
      • 自定義銷毀方法:通過XML配置destroy-method或Java配置@Bean(destroyMethod="xxx")
      • 資源釋放:如關閉數據庫連接、釋放文件句柄等。

      DisposableBeanAdapterdestroy方法中實現

      總結

      通過代碼出處,可以觀察到整個Bean的創建的過程都依賴于AbstractAutowireCapableBeanFactory這個類,而銷毀主要依賴DisposableBeanAdapter這個類。
      AbstractAutowireCapableBeanFactory 的入口處,doCreateBean的核心代碼如下,其中包含了實例化、設置屬性值、初始化Bean以及注冊銷毀回調的幾個核心方法。
      這里就不貼代碼了,想更深入看細節的可以去看源碼。

      Spring中創建Bean的方式有哪些?

      基于注解的自動掃描

      通過注解標記類,并配合組件掃描實現自動注冊。
      常見的注解有
      @Component, @Service, @Repository, @Controller(及其衍生注解)。

      例如:當在類上添加@Component時,再在配置類或 XML 中啟用組件掃描(@ComponentScan<context:component-scan>)。這個類在服務啟動時會自動被掃描到,然后注入到Spring容器。

      @Configuration
      @ComponentScan("com.jimoer.service")
      public class BeanConfig {
      
      }
      
      @Service
      public class UserService {
          public void hello() {
              System.out.println("Hello from UserService");
          }
      }
      
      @Component
      public class UserHandler {
          public void hello() {
              System.out.println("Hello from UserHandler");
          }
      }
      
      @Repository
      public class UserRepository {
          public void hello() {
              System.out.println("Hello from UserRepository");
          }
      }
      
      @Controller
      public class UserController {
          public void hello() {
              System.out.println("Hello from UserController");
          }
      }
      

      使用@Configuration與@Bean 注解

      通過 @Configuration 標注的配置類,顯式定義 Bean 的創建邏輯。
      適用于:需要精確控制 Bean 的初始化邏輯(如依賴其他 Bean 或復雜條件)。

      @Configuration
      public class AppConfig {
          @Bean
          public UserService userService() {
              return new UserService();
          }
      }
      

      XML 配置文件

      通過 xml 的方式來定義 Bean。
      在SpringBoot 流行以前,這種方式挺多的, SpringBoot 流行起來之后,這么用的越來越少了。

      <beans xmlns="http://www.springframework.org/schema/beans"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"
          <bean id="userService" class="com.jimoer.demo.UserServiceImpl">
             <property name="message" value="Hello Spring!" />
          </bean>
      </beans>
      
      ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
      UserService userService = context.getBean("userService");
      

      更適用于遺留項目或需要與非注解配置兼容的場景。

      使用@Import注解

      @Import注解的作用是快速導入某一個或多個類,使這些類能夠被Spring加載到IOC容器中進行管理。
      讓類被Spring 的 IOC 容器管理,這不也是創建 Bean 么,因此,這種方式也可以算是創建Bean的一種方式。

      @Import({UserServiceImpl.class})
      @Configuration
      public class UserBeanConfiguration {
      }
      

      自定義注解

      通過自定義一種注解,然后在 Spring 應用啟動過程中,通過自定義的 BeanDefinitionRegistryPostProcessorBeanfactoryPostProcessor 來掃描配置的包路徑,識別出帶有自定義注解的類。
      這些處理器解析注解中的屬性(如接口類、版本號、超時時間等),并基于這些信息創建 Spring的 BeanDefinition
      例如:Dubbo框架使用的@DubboService注解

      @DubboService("version=1.0.0")
      public class UserServiceImpl implements UserFacadeService {
      
      }
      

      動態注冊(運行時注冊)

      在運行時通過 BeanDefinitionRegistry 動態注冊 Bean。

      // 獲取 BeanFactory
      ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
      
      // 定義 Bean 的元數據
      GenericBeanDefinition userDefinition = new GenericBeanDefinition();
      userDefinition.setBeanClass(UserService.class);
      
      // 注冊 Bean
      beanFactory.registerBeanDefinition("userService", userDefinition);
      

      適用于:根據運行時條件動態生成 Bean(如插件化系統、動態配置)。

      Spring Bean的注入方式有哪些?

      使用@Autowired注解

      @Autowired注解是Spring框架提供的一個注解,支持多種方式自動將Spring的bean注入到其他Bean中。

      字段注入

      @Component
      public class JimoerUserService {
          @Autowired
          private UserRepository userRepository;
      }
      

      構造方法注入

      @Component
      public class JimoerUserService {
          private final UserRepository userRepository;
      
          // Spring 4.3+ 可省略 @Autowired(單構造器)
          @Autowired
          public JimoerUserService(UserRepository userRepository) {
              this.userRepository = userRepository;
          }
      }
      

      setter注入

      @Component
      public class JimoerUserService {
          private UserRepository userRepository;
      
          @Autowired
          public void setUserRepository(UserRepository userRepository) {
              this.userRepository = userRepository;
          }
      }
      

      使用@Resource和@Inject注解

      除了Spring提供的注解,JDK也提供了可以互相注入Bean的注解,有@Resource@Inject

      @Component
      public class JimoerUserService {
          @Resource
          private UserRepository userRepository;
      }
      
      @Component
      public class JiomerUserService {
          @Inject
          private UserRepository userRepository;
      }
      

      使用XML配置注入

      如何不使用注解注入,還可以使用XML文件的配置進行Bean的互相注入。

      <bean id="userRepository" class="com.jimoer.UserRepository"/>
      <!-- 構造方法注入 -->
      <bean id="userService" class="com.jiomer.UserService">
          <constructor-arg ref="userRepository"/>
      </bean>
      <!-- 字段注入 -->
      <bean id="jimoerUserService" class="com.jiomer.JimoerUserService">
          <property name="userRepository" ref="userRepository"/>
      </bean>
      

      構造方法自動注入

      其實從 Spring 4.3 開始,除非一個類中聲明了至少兩個構造函數,否則不需要用 @Autowired 標注構造函數,這個構造函數也能直接注入 Bean。

      @Component
      public class JimoerUserService {
      	private UserRepository userRepository;
      	public JimoerUserService(UserRepository userRepository){
      		this.userRepository=userRepository;
      	}
      }
      

      Spring Bean的作用域有哪些?

      Spring的Bean的作用域,就是指這個Bean在哪個范圍內可以被使用。
      不同的作用域決定了Bean的創建管理和銷毀的方式。

      常見的作用域有SingletonPrototypeRequestSessionApplication這五種。
      在代碼中,可以在定義一個Bean的時候,通過@Scope 注解來指定他的作用域。

      如果沒有指定Bean的作用域,默認是Singleton(單例)。

      Singleton(單例)

      • 周期:Spring 容器啟動時創建實例,容器關閉時銷毀。
      • 作用域:每個Spring IOC容器,只創建一個Bean實例。
      • 適用于:無狀態服務(如工具類、緩存管理器、數據庫連接池)。
      • 線程安全:需注意,若 Bean 有可變狀態(即Bean中存在線程共享變量),需通過同步機制或線程安全集合處理。
      • 配置方式:
      @Component // 默認即為 singleton
      public class SingletonBean {
      }
      

      Propertype(原型)

      • 周期:每次調用 getBean() 或注入時創建新實例,容器不負責銷毀。
      • 適用于:有狀態 Bean(如用戶會話數據、臨時對象)。
      • 線程安全:實例獨立,避免線程安全問題。
      • 配置方式:
      @Component
      @Scope("prototype")
      public class PrototypeBean {
      }
      

      Request(HTTP 請求)

      • 周期:每個 HTTP 請求創建一個實例,請求結束后銷毀。
      • 適用于:Web 應用中請求級別的數據共享(如請求日志、上下文信息)。

      僅適用于 Web 應用環境。

      • 配置方式:
      @Component
      @Scope("request")
      public class RequestBean {
      }
      

      Session(HTTP 會話)

      • 周期:每個用戶會話(HttpSession)創建一個實例,會話結束時銷毀。
      • 適用于:用戶會話數據(如購物車、用戶偏好設置)。

      僅適用于 Web 應用環境。

      • 配置方式:
      @Component
      @Scope("session")
      public class SessionBean {
      }
      

      Application(應用)

      • 周期:Web 應用啟動時創建實例,應用關閉時銷毀。
      • 適用于:全局配置或共享資源(如應用級緩存、配置信息)。類似 singleton,但綁定到 ServletContext

      僅適用于 Web 環境

      • 配置方式:
      @Component
      @Scope("application")
      public class ApplicationBean {
      }
      

      Websocket(WebSocket 會話)

      • 周期:WebSocket 連接建立時創建實例,連接關閉時銷毀。
      • 適用于:WebSocket 會話上下文數據(如實時通信狀態)。

      僅適用于 WebSocket 應用。

      • 配置方式:
      @Component
      @Scope("websocket")
      public class WebSocketBean {
      }
      

      自定義作用域

      一般情況下,在開發過程中,都是使用Singleton作用域,有時候也會用Propertype,其他幾個用的都不多。但是除了上面列舉的6個Spring提供作用域以外,還可以自己定義Bean作用域。

      自定義一個Spring Bean的作用域,需要實現org.springframework.beans.factory.config.Scope接口,主要是實現如下幾個方法來管理Bean的生命周期。

      package org.springframework.beans.factory.config;
      
      import org.springframework.beans.factory.ObjectFactory;
      
      public interface Scope {
          Object get(String var1, ObjectFactory<?> var2);
      
          Object remove(String var1);
      
          void registerDestructionCallback(String var1, Runnable var2);
      
          Object resolveContextualObject(String var1);
      
          String getConversationId();
      }
      

      自定義一個類,然后實現Scope接口,來實現我們自己的Bean作用域。

      public class JimoerScope implements Scope{
          @Override
          public Object get(String s, ObjectFactory<?> objectFactory) {
              // 獲取Bean的邏輯
              return objectFactory.getObject();
          }
      
          @Override
          public Object remove(String s) {
              // 移除Bean的邏輯
              return null;
          }
      
          @Override
          public void registerDestructionCallback(String s, Runnable runnable) {
              // 注冊Bean銷毀時的回調
          }
      
          @Override
          public Object resolveContextualObject(String s) {
              // 解析上下文
              return null;
          }
      
          @Override
          public String getConversationId() {
              // 獲取會話ID
              return "";
          }
      }
      

      接下來,我們將Spring配置中注冊這個自定義的作用域。
      這可以通過ConfigurableBeanFactory.registerScope 方法實現。

      import org.springframework.beans.factory.config.ConfigurableBeanFactory;
      import org.springframework.context.annotation.Bean;
      import org.springframework.context.annotation.Configuration;
      
      @Configuration
      public class AppConfig {
      
          @Bean
          public JimoerScope jimoerScope(ConfigurableBeanFactory beanFactory) {
              JimoerScope jimoerScope = new JimoerScope();
              beanFactory.registerScope("jimoer", jimoerScope);
              return jimoerScope;
          }
      
      }
      

      此時在Bean定義中使用自定義的作用域的名稱jimoer
      Spring 容器將會根據你的自定義邏輯來創建和管理這些 Bean。

      @Component
      @Scope("jimoer")
      public class CustomerScopeTest {
      }
      
      posted @ 2025-09-13 21:51  紀莫  閱讀(145)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 亚洲国产精品热久久一区| 我和亲妺妺乱的性视频| 无码免费大香伊蕉在人线国产| 日本一区三区高清视频| 日韩国产亚洲一区二区三区| 污污内射在线观看一区二区少妇| 中文字幕av日韩有码| 少妇高潮喷水正在播放 | 国产主播精品福利午夜二区| 中文有无人妻VS无码人妻激烈| 国产精品一区二区三区激情| 十八禁午夜福利免费网站| 欧美成人h精品网站| 91亚洲国产三上悠亚在线播放| 精品亚洲欧美高清不卡高清| 日日摸夜夜添狠狠添欧美| 江阴市| 粉嫩av一区二区三区蜜臀| 亚洲免费成人av一区| 国产高清在线a视频大全| 亚洲精品成人综合色在线| 国产偷自一区二区三区在线| 伊人久在线观看视频| 丁香婷婷色综合激情五月| 国产成人精品无码专区| 国产在线播放专区av| 欧美丰满熟妇xxxx性| 在线观看中文字幕国产码| 国产精品免费视频不卡| 久久精品国产99久久久古代| 亚洲 欧美 中文 日韩aⅴ| 日韩精品中文字幕有码| 久久se精品一区精品二区| 兔费看少妇性l交大片免费| 亚洲人成小说网站色在线| 激情影院内射美女| 天干天干啦夜天干天2017| 26uuu另类亚洲欧美日本| 中文字幕久久熟女蜜桃| 亚洲视频一区| 国产偷窥熟女高潮精品视频|