最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java?Spring原理之Bean的作用域、Bean的生命周期及Spring自動配置詳解

 更新時間:2025年11月26日 08:28:34   作者:英雄不問出處~  
Spring是一個非常流行的Java應用程序框架,它提供了一個靈活的機制來管理Bean的生命周期和作用域,這篇文章主要介紹了Java?Spring原理之Bean的作用域、Bean的生命周期及Spring自動配置的相關資料,需要的朋友可以參考下

Spring原理

Bean的作用域

  1. 概念:從Context中獲取對象,得到的都是同一個,這種行為模式,就稱為bean的作用域
    多次獲取,拿到的Bean的對象都是同一個

  2. 在Spring中支持6種作用域,后4種在Spring MVC環(huán)境才生效
    (1) singleton:單例作用域
    每個Spring IoC容器內同名稱的bean只有一個實例(單例)(默認)
    (2) prototype:原型作用域(多例作用域)
    每次使用該bean時會創(chuàng)建新的實例(非單例)
    (3) request:請求作用域
    每個HTTP 請求生命周期內, 創(chuàng)建新的實例(web環(huán)境中, 了解)
    (4) session:會話作用域
    每個HTTP Session生命周期內, 創(chuàng)建新的實例(web環(huán)境中, 了解)
    (5) Application: 全局作用域
    每個ServletContext生命周期內, 創(chuàng)建新的實例(web環(huán)境中, 了解)
    (6) websocket:HTTP WebSocket 作用域
    每個WebSocket生命周期內, 創(chuàng)建新的實例(web環(huán)境中,了解)

驗證是單例的

  1. 從context中獲取對象
  2. 屬性注入獲取對象
@Configuration
public class BeanConfig {
    @Bean
    public User user1(){
        return new User(1,"zhangsan");
    }

    // 聲明作用的范圍(聲明了一個單例的作用域)
    // 聲明了一個單例的對象
    @Scope(ConfigurableBeanFactory.SCOPE_SINGLETON)
    // @Scope("singleton")
    @Bean
    public User singleUser(){
        return new User();
    }
}

    // 有多個@Autowired的時候,指定名稱使用哪個
    @Resource(name = "singleUser")
    private User singleUser;
    
@RequestMapping("scope")
@RestController
public class BeanScopeController {
    @Autowired
    private ConfigurableApplicationContext context;

    // 有多個@Autowired的時候,指定名稱使用哪個
    @Resource(name = "singleUser")
    private User singleUser;

    @RequestMapping("/single")
    public String single(){
         // 1. 從context中獲取對象
        String user = (String) context.getBean("singleUser");
        // 2. 屬性注入獲取對象

        return "從context中獲取的對象 " + System.identityHashCode(user)
                + "屬性注入獲取的對象" + System.identityHashCode(singleUser);
    }
}
  1. 結果展示:可以看出他們獲取的是同一個對象

多例的作用域

  1. 多例模式(原型模式)
    屬性注入在程序啟動的時候會創(chuàng)建一個對象,之后再重新啟動,才會改變

context獲取的對象,每次重新啟動都會重新獲取對象,因此每次對象都會發(fā)生變化

  //對象
 @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
    @Bean
    public User prototypeUser(){
        return new User();
    }

 // 注解
@Resource(name = "prototypeUser")
    private User prototypeUser;

@RequestMapping("/phototype")
    public String phototype(){
        // 1. 從context中獲取對象
        User user = (User) context.getBean("prototypeUser");
        // 2. 屬性注入獲取對象

        return "從context中獲取的對象 " + System.identityHashCode(user)
                + "屬性注入獲取的對象" + System.identityHashCode(prototypeUser);
    }
  1. 展示效果:每次刷新,拿到的不是同一個對象,每次請求都會生成一個新的對象

  2. 出現(xiàn)的問題:沒有驗證成功的原因是我們寫的是同一個User對象,@Data中的hashcode()會根據(jù)id判斷他們是否是同一個對象,**這里的new User()都是同一個對象,那么這里就判斷了他們是同一個對象,Spring進行了優(yōu)化,**因此每次request刷新都不變,理論上每次刷新,都會創(chuàng)建一個新的對象,每次都會變化
    這里就要使用jdk,自帶的toString()方法,jdk有hashcode()方法,用自帶的toString()方法,它每次new都會生成不同的對象,因此可以看出request,每次都是變化的了
    所以這里不同@Data,而用@Getter和@Setter

對上面問題的再一次解釋:
Spring使用了代理模式,所以代理的User,每次都是同一個

Spring中才有代理模式:

request的作用域

  1. @RequestScope等同于@Scope,這兩者含義是一樣的

  2. 雖然是同一個對象,但是每次請求都會重新創(chuàng)建對象

// request的作用域
@RequestScope
    @Bean
    public User requestUser(){
        return new User();
    }


// 注解的方式
@Resource(name = "requestUser")
    private User requestUser;

@RequestMapping("/request")
    public String request(){
        // 1. 從context中獲取對象
        User user = (User) context.getBean("requestUser");
        // 2. 屬性注入獲取對象

        return "從context中獲取的對象 " + System.identityHashCode(user)
                + "屬性注入獲取的對象" + System.identityHashCode(requestUser);
    }

session的作用域

  1. 在不同的瀏覽器下,是不同的會話,自然會出現(xiàn)不同的地址
@SessionScope
    @Bean
    public User sessionUser(){
        return new User();
    }
@Resource(name = "sessionUser")
    private User sessionUser;

@RequestMapping("/session")
    public String session(){
        // 1. 從context中獲取對象
        User user = (User) context.getBean("sessionUser");
        // 2. 屬性注入獲取對象

        return "從context中獲取的對象 " + System.identityHashCode(user)
                + "屬性注入獲取的對象" + System.identityHashCode(sessionUser);
    }
  1. 效果展示:
    如果是同一個瀏覽器,并且沒有清除cookie,那么session不會發(fā)生變化

    如果是不同的瀏覽器,就是不同的cookie,session自然會發(fā)生變化

application的作用域

  1. application的作用域:在整個應用中都是同一個的,和我們的單例一樣,在同一個應用中都是同一個

  2. 兩者的區(qū)別:一個web容器中(一個tomcat中),可以部署多個服務(多個ApplicationContext),而一個Web容器中有多個ServletContext - 每個Web應用都有自己獨立的ServletContext實例

一個tomcat可以啟動多個web服務

@ApplicationScope
    @Bean("applicationUser")// 指定名字
    public User applicationUser(){
        return new User();
    }

// 注解注入
@Resource(name = "applicationUser")
    private User applicationUser;

@RequestMapping("/application")
    public String application(){
        // 1. 從context中獲取對象
        User user = (User) context.getBean("applicationUser");
        // 2. 屬性注入獲取對象

        return "從context中獲取的對象 " + user
                + "屬性注入獲取的對象" + applicationUser;
    }
  1. 在不同的瀏覽器中,進行展示,都是同一個

Bean的生命周期

代碼的使用

  1. 對象的生命周期:生命周期指的是一個對象從誕生到銷毀的整個生命過程, 我們把這個過程就叫做一個對象的生命周期。

Bean 的生命周期分為以下5個部分:
2. 實例化(為Bean分配內存空間)
3. 屬性賦值(Bean注入和裝配, 比如 @AutoWired )
4. 初始化
a. 執(zhí)行各種通知, 如 BeanNameAware , BeanFactoryAware ,
ApplicationContextAware 的接口方法.
b. 執(zhí)行初始化方法
? xml定義 init-method
? 使用注解的方式 @PostConstruct
? 執(zhí)行初始化后置方法( BeanPostProcessor )
5. 使用Bean
6. 銷毀Bean
a. 銷毀容器的各種方法, 如 @PreDestroy , DisposableBean 接口方法, destroy-
method

舉個例子:

2. 寫一個案例,來驗證Bean的生命周期

// BeanLifeComponent
@Component
public class BeanLifeComponent {
    private User user;
    // 構造
    public BeanLifeComponent() {
        System.out.println("執(zhí)行構造方法~");
    }

    // 屬性注入
    // 指定注入的對象
    // 表示注入的user1對象
    @Qualifier("user1")
    @Autowired
    public void setUser1(User user) {
        this.user = user;
        System.out.println("屬性注入~");
    }

    // 初始化
    // 使用@PostConstruct實現(xiàn)初始化
    @PostConstruct // 這個用的比較多
    public void init(){
        System.out.println("執(zhí)行初始化方法~");
    }

    // 使用
    public void use(){
        System.out.println("執(zhí)行use方法~");
    }

    // 銷毀
    // 基本上不會用
    @PreDestroy // pre表示 bean 銷毀前執(zhí)行,銷毀的時候就直接清理對象了
    public void destroy(){
        System.out.println("執(zhí)行destroy銷毀方法~");
    }
}

// 測試方法
public static void main(String[] args) {
        ConfigurableApplicationContext context = SpringApplication.run(SpringConfigApplication.class, args);
        BeanLifeComponent lifeComponent = context.getBean(BeanLifeComponent.class);
        lifeComponent.use();
        // 有不手動點擊結束進程的方式來執(zhí)行destroy方法
        // ((AbstractApplicationContext)context).destroy();
   }

展示效果:

手動關閉進程:

源碼閱讀

了解生命周期的分類

  1. bean的實例化,屬性注入,bean的初始化

2. 執(zhí)行各種通知,這些通知都是在初始化方法之前執(zhí)行,屬性注入之后執(zhí)行的

SpringBoot自動配置

  1. 這些注解的底層就是Spring自動配置的

  2. 元注解:是注解其他注解的注解

有選擇地導入配置類

總結

到此這篇關于Java Spring原理之Bean的作用域、Bean的生命周期及Spring自動配置的文章就介紹到這了,更多相關Java Spring原理詳解內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

最新評論

博野县| 柳州市| 舞阳县| 泸水县| 玉门市| 英超| 荆门市| 石狮市| 乐山市| 清流县| 曲周县| 陇川县| 垦利县| 抚宁县| 麦盖提县| 桑日县| 左贡县| 建瓯市| 定兴县| 武功县| 宿迁市| 紫云| 西华县| 定襄县| 邵阳县| 文成县| 焉耆| 天津市| 富顺县| 特克斯县| 东安县| 漾濞| 平度市| 临高县| 长沙县| 平塘县| 闸北区| 安仁县| 日土县| 兴和县| 江阴市|