1. 程式人生 > >@Bean 註解全解析

@Bean 註解全解析

目錄

    • @Bean 基礎宣告
    • @Bean 基本構成及其使用
    • @Bean 註解與其他註解產生的火花
      • @Profile 註解
      • @Scope 註解
      • @Lazy 註解
      • @DependsOn 註解
      • @Primary 註解

隨著SpringBoot的流行,基於註解式開發的熱潮逐漸覆蓋了基於XML純配置的開發,而作為Spring中最核心的bean當然也能夠使用註解的方式進行表示。所以本篇就來詳細的討論一下作為Spring中的Bean到底都有哪些用法。

@Bean 基礎宣告

Spring的@Bean註解用於告訴方法,產生一個Bean物件,然後這個Bean物件交給Spring管理。產生這個Bean物件的方法Spring只會呼叫一次,隨後這個Spring將會將這個Bean物件放在自己的IOC容器中。

SpringIOC 容器管理一個或者多個bean,這些bean都需要在@Configuration註解下進行建立,在一個方法上使用@Bean註解就表明這個方法需要交給Spring進行管理。

快速搭建一個maven專案並配置好所需要的Spring 依賴

<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-context</artifactId>
  <version>4.3.13.RELEASE</version>
</dependency>

<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-beans</artifactId>
  <version>4.3.13.RELEASE</version>
</dependency>

<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-core</artifactId>
  <version>4.3.13.RELEASE</version>
</dependency>

<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-web</artifactId>
  <version>4.3.13.RELEASE</version>
</dependency>

在src根目錄下建立一個AppConfig的配置類,這個配置類也就是管理一個或多個bean 的配置類,並在其內部宣告一個myBean的bean,並建立其對應的實體類

@Configuration
public class AppConfig {

    // 使用@Bean 註解表明myBean需要交給Spring進行管理
    // 未指定bean 的名稱,預設採用的是 "方法名" + "首字母小寫"的配置方式
    @Bean
    public MyBean myBean(){
        return new MyBean();
    }
}

public class MyBean {

    public MyBean(){
        System.out.println("MyBean Initializing");
    }
}

在對應的test資料夾下建立一個測試類SpringBeanApplicationTests,測試上述程式碼的正確性

public class SpringBeanApplicationTests {

    public static void main(String[] args) {
        ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
        context.getBean("myBean");
    }
}

輸出 : MyBean Initializing

隨著SpringBoot的流行,我們現在更多采用基於註解式的配置從而替換掉了基於XML的配置,所以本篇文章我們主要探討基於註解的@Bean以及和其他註解的使用。

@Bean 基本構成及其使用

在簡單介紹了一下如何宣告一個Bean元件,並將其交給Spring進行管理之後,下面我們來介紹一下Spring 的基本構成

@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Bean {

    @AliasFor("name")
    String[] value() default {};

    @AliasFor("value")
    String[] name() default {};

    Autowire autowire() default Autowire.NO;

    String initMethod() default "";

    String destroyMethod() default AbstractBeanDefinition.INFER_METHOD;

}

@Bean不僅可以作用在方法上,也可以作用在註解型別上,在執行時提供註冊。

value: name屬性的別名,在不需要其他屬性時使用,也就是說value 就是預設值

name: 此bean 的名稱,或多個名稱,主要的bean的名稱加別名。如果未指定,則bean的名稱是帶註解方法的名稱。如果指定了,方法的名稱就會忽略,如果沒有其他屬性宣告的話,bean的名稱和別名可能通過value屬性配置

autowire : 此註解的方法表示自動裝配的型別,返回一個Autowire型別的列舉,我們來看一下Autowire列舉型別的概念

// 列舉確定自動裝配狀態:即,bean是否應該使用setter注入由Spring容器自動注入其依賴項。
// 這是Spring DI的核心概念
public enum Autowire {

  // 常量,表示根本沒有自動裝配。
    NO(AutowireCapableBeanFactory.AUTOWIRE_NO),
    // 常量,通過名稱進行自動裝配
    BY_NAME(AutowireCapableBeanFactory.AUTOWIRE_BY_NAME),
    // 常量,通過型別進行自動裝配
    BY_TYPE(AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE);

    private final int value;
    Autowire(int value) {
        this.value = value;
    }
    public int value() {
        return this.value;
    }
    public boolean isAutowire() {
        return (this == BY_NAME || this == BY_TYPE);
    }
}

autowire的預設值為No,預設表示不通過自動裝配。

initMethod: 這個可選擇的方法在bean例項化的時候呼叫,InitializationBean介面允許bean在合適的時機通過設定註解的初始化屬性從而呼叫初始化方法,InitializationBean 介面有一個定義好的初始化方法

void afterPropertiesSet() throws Exception;

Spring不推薦使用InitializationBean 來呼叫其初始化方法,因為它不必要地將程式碼耦合到Spring。Spring推薦使用@PostConstruct註解或者為POJO類指定其初始化方法這兩種方式來完成初始化。

不推薦使用:

public class InitBean implements InitializingBean {

    public void afterPropertiesSet() {}
}

destroyMethod: 方法的可選擇名稱在呼叫bean示例在關閉上下文的時候,例如JDBC的close()方法,或者SqlSession的close()方法。DisposableBean 介面的實現允許在bean銷燬的時候進行回撥呼叫,DisposableBean 介面之後一個單個的方法

void destroy() throws Exception;

Spring不推薦使用DisposableBean 的方式來初始化其方法,因為它會將不必要的程式碼耦合到Spring。作為替代性的建議,Spring 推薦使用@PreDestory註解或者為@Bean註解提供 destroyMethod 屬性,

不推薦使用:

public class DestroyBean {

    public void cleanup() {}
}

推薦使用:

public class MyBean {

    public MyBean(){
        System.out.println("MyBean Initializing");
    }

    public void init(){
        System.out.println("Bean 初始化方法被呼叫");
    }

    public void destroy(){
        System.out.println("Bean 銷燬方法被呼叫");
    }
}

@Configuration
public class AppConfig {

//    @Bean
    @Bean(initMethod = "init", destroyMethod = "destroy")
    public MyBean myBean(){
        return new MyBean();
    }

}

修改一下測試類,測試其初始化方法和銷燬方法在何時會被呼叫

public class SpringBeanApplicationTests {

    public static void main(String[] args) {

        // ------------------------------ 測試一  ------------------------------
        ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
//        context.getBean("myBean");
      
        // 變體
        context.getBean("myBean");
        ((AnnotationConfigApplicationContext) context).destroy();
//      ((AnnotationConfigApplicationContext) context).close();
    }
}

初始化方法在得到Bean的例項的時候就會被呼叫,銷燬方法在容器銷燬或者容器關閉的時候會被呼叫。

@Bean 註解與其他註解產生的火花

在上面的一個小節中我們瞭解到了@Bean註解的幾個屬性,但是對於@Bean註解的功能來講這有點太看不起bean了,@Bean另外一個重要的功能是能夠和其他註解產生化學反應,如果你還不瞭解這些註解的話,那麼請繼續往下讀,你會有收穫的

這一節我們主要探討@profile,@scope,@lazy,@depends-on @primary等註解

@Profile 註解

@Profile的作用是把一些meta-data進行分類,分成Active和InActive這兩種狀態,然後你可以選擇在active 和在Inactive這兩種狀態下配置bean,在Inactive狀態通常的註解有一個!操作符,通常寫為:@Profile("!p"),這裡的p是Profile的名字。

三種設定方式:

  • 可以通過ConfigurableEnvironment.setActiveProfiles()以程式設計的方式啟用

  • 可以通過AbstractEnvironment.ACTIVE_PROFILES_PROPERTY_NAME (spring.profiles.active )屬性設定為

    JVM屬性

  • 作為環境變數,或作為web.xml 應用程式的Servlet 上下文引數。也可以通過@ActiveProfiles 註解在整合測試中以宣告方式啟用配置檔案。

作用域

  • 作為類級別的註釋在任意類或者直接與@Component 進行關聯,包括@Configuration 類
  • 作為原註解,可以自定義註解
  • 作為方法的註解作用在任何方法

注意:

​ 如果一個配置類使用了Profile 標籤或者@Profile 作用在任何類中都必須進行啟用才會生效,如果@Profile({"p1","!p2"}) 標識兩個屬性,那麼p1 是啟用狀態 而p2 是非啟用狀態的。

現有一個POJO類為Subject學科類,裡面有兩個屬性,一個是like(理科)屬性,一個是wenke(文科)屬性,分別有兩個配置類,一個是AppConfigWithActiveProfile ,一個是AppConfigWithInactiveProfile,當系統環境是 "like"的時候就註冊 AppConfigWithActiveProfile ,如果是 "wenke",就註冊 AppConfigWithInactiveProfile,來看一下這個需求如何實現

Subject.java

// 學科
public class Subject {

    // 理科
    private String like;
    // 文科
    private String wenke;

   get and set ...

    @Override
    public String toString() {
        return "Subject{" +
                "like='" + like + '\'' +
                ", wenke='" + wenke + '\'' +
                '}';
    }
}

AppConfigWithActiveProfile.java 註冊Profile 為like 的時候

@Profile("like")
@Configuration
public class AppConfigWithActiveProfile {

    @Bean
    public Subject subject(){
        Subject subject = new Subject();
        subject.setLike("物理");
        return subject;
    }

}

AppConfigWithInactiveProfile.java 註冊Profile 為wenke 的時候

@Profile("wenke")
@Configuration
public class AppConfigWithInactiveProfile {

    @Bean
    public Subject subject(){
        Subject subject = new Subject();
        subject.setWenke("歷史");
        return subject;
    }
}

修改一下對應的測試類,設定系統環境,當Profile 為like 和 wenke 的時候分別註冊各自對應的屬性

// ------------------------------ 測試 profile  ------------------------------
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
// 啟用 like 的profile
context.getEnvironment().setActiveProfiles("like");
context.register(AppConfigWithActiveProfile.class,AppConfigWithInactiveProfile.class);
context.refresh();
Subject subject = (Subject) context.getBean("subject");
System.out.println("subject = " + subject);

把context.getEnvironment().setActiveProfiles("wenke") 設定為wenke,觀察其對應的輸出內容發生了變化,這就是@Profile的作用,有一層可選擇性註冊的意味。

@Scope 註解

在Spring中對於bean的預設處理都是單例的,我們通過上下文容器.getBean方法拿到bean容器,並對其進行例項化,這個例項化的過程其實只進行一次,即多次getBean 獲取的物件都是同一個物件,也就相當於這個bean的例項在IOC容器中是public的,對於所有的bean請求來講都可以共享此bean。

那麼假如我不想把這個bean被所有的請求共享或者說每次呼叫我都想讓它生成一個bean例項該怎麼處理呢?

多例Bean

bean的非單例原型範圍會使每次發出對該特定bean的請求時都建立新的bean例項,也就是說,bean被注入另一個bean,或者通過對容器的getBean()方法呼叫來請求它,可以用如下圖來表示:

通過一個示例來說明bean的多個例項

新建一個AppConfigWithAliasAndScope配置類,用來定義多例的bean,

@Configuration
public class AppConfigWithAliasAndScope {

    /**
     * 為myBean起兩個名字,b1 和 b2
     * @Scope 預設為 singleton,但是可以指定其作用域
     * prototype 是多例的,即每一次呼叫都會生成一個新的例項。
     */
    @Bean({"b1","b2"})
    @Scope("prototype")
    public MyBean myBean(){
        return new MyBean();
    }
}

測試一下多例的情況:

// ------------------------------ 測試scope  ------------------------------
ApplicationContext context = new AnnotationConfigApplicationContext(AppConfigWithAliasAndScope.class);
MyBean myBean = (MyBean) context.getBean("b1");
MyBean myBean2 = (MyBean) context.getBean("b2");
System.out.println(myBean);
System.out.println(myBean2);

其他情況

除了多例的情況下,Spring還為我們定義了其他情況:

Scope Descriptionn
singleton 預設單例的bean定義資訊,對於每個IOC容器來說都是單例物件
prototype bean物件的定義為任意數量的物件例項
request bean物件的定義為一次HTTP請求的生命週期,也就是說,每個HTTP請求都有自己的bean例項,它是在單個bean定義的後面建立的。僅僅在web-aware的上下文中有效
session bean物件的定義為一次HTTP會話的生命週期。僅僅在web-aware的上下文中有效
application bean物件的定義範圍在ServletContext生命週期內。僅僅在web-aware的上下文中有效
websocket bean物件的定義為WebSocket的生命週期內。僅僅在web-aware的上下文中有效

singleton和prototype 一般都用在普通的Java專案中,而request、session、application、websocket都用於web應用中。

request、session、application、websocket的作用範圍

你可以體會到 request、session、application、websocket 的作用範圍在當你使用web-aware的ApplicationContext應用程式上下文的時候,比如XmlWebApplicationContext的實現類。如果你使用了像是ClassPathXmlApplicationContext的上下文環境時,就會丟擲IllegalStateException因為Spring不認識這個作用範圍。

@Lazy 註解

@Lazy : 表明一個bean 是否延遲載入,可以作用在方法上,表示這個方法被延遲載入;可以作用在@Component (或者由@Component 作為原註解) 註釋的類上,表明這個類中所有的bean 都被延遲載入。如果沒有@Lazy註釋,或者@Lazy 被設定為false,那麼該bean 就會急切渴望被載入;除了上面兩種作用域,@Lazy 還可以作用在@Autowired和@Inject註釋的屬性上,在這種情況下,它將為該欄位建立一個惰性代理,作為使用ObjectFactory或Provider的預設方法。下面來演示一下:

@Lazy
@Configuration
@ComponentScan(basePackages = "com.spring.configuration.pojo")
public class AppConfigWithLazy {

    @Bean
    public MyBean myBean(){
        System.out.println("myBean Initialized");
        return new MyBean();
    }

    @Bean
    public MyBean IfLazyInit(){
        System.out.println("initialized");
        return new MyBean();
    }
}
  • 修改測試類
public class SpringConfigurationApplication {

    public static void main(String[] args) {

        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfigWithLazy.class);

        // 獲取啟動過程中的bean 定義的名稱
        for(String str : context.getBeanDefinitionNames()){
            System.out.println("str = " + str);
        }
    }
}

輸出你會發現沒有關於bean的定義資訊,但是當把@Lazy 註釋拿掉,你會發現輸出了關於bean的初始化資訊

@DependsOn 註解

指當前bean所依賴的bean。任何指定的bean都能保證在此bean建立之前由IOC容器建立。在bean沒有通過屬性或建構函式引數顯式依賴於另一個bean的情況下很少使用,可能直接使用在任何直接或者間接使用 Component 或者Bean 註解表明的類上。來看一下具體的用法

新建三個Bean,分別是FirstBean、SecondBean、ThirdBean三個普通的bean,新建AppConfigWithDependsOn並配置它們之間的依賴關係

public class FirstBean {

    @Autowired
    private SecondBean secondBean;

    @Autowired
    private ThirdBean thirdBean;

    public FirstBean() {
        System.out.println("FirstBean Initialized via Constuctor");
    }
}

public class SecondBean {

    public SecondBean() {
        System.out.println("SecondBean Initialized via Constuctor");
    }
}

public class ThirdBean {

    public ThirdBean() {
        System.out.println("ThirdBean Initialized via Constuctor");
    }
}

@Configuration
public class AppConfigWithDependsOn {

    @Bean("firstBean")
    @DependsOn(value = {
            "secondBean",
            "thirdBean"
    })
    public FirstBean firstBean() {
        return new FirstBean();
    }

    @Bean("secondBean")
    public SecondBean secondBean() {
        return new SecondBean();
    }

    @Bean("thirdBean")
    public ThirdBean thirdBean() {
        return new ThirdBean();
    }
}

使用測試類進行測試,如下

// ------------------------------ 測試 DependsOn  ------------------------------
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfigWithDependsOn.class);
context.getBean(FirstBean.class);
context.close();

輸出 :

SecondBean Initialized via Constuctor
ThirdBean Initialized via Constuctor
FirstBean Initialized via Constuctor

由於firstBean 的建立過程首先需要依賴secondBeanthirdBean的建立,所以secondBean 首先被載入其次是thirdBean 最後是firstBean。

如果把@DependsOn 註解加在AppConfigWithDependsOn 類上則它們的初始化順序就會變為 firstBean、secondBean、thirdBean

@Primary 註解

指示當多個候選者有資格自動裝配依賴項時,應優先考慮bean。此註解在語義上就等同於在Spring XML中定義的bean 元素的primary屬性。注意: 除非使用component-scanning進行元件掃描,否則在類級別上使用@Primary不會有作用。如果@Primary 註解定義在XML中,那麼@Primary 的註解元註解就會忽略,相反使用

@Primary 的兩種使用方式

  • 與@Bean 一起使用,定義在方法上,方法級別的註解
  • 與@Component 一起使用,定義在類上,類級別的註解

通過一則示例來演示一下:

新建一個AppConfigWithPrimary類,在方法級別上定義@Primary註解

@Configuration
public class AppConfigWithPrimary {

    @Bean
    public MyBean myBeanOne(){
        return new MyBean();
    }

    @Bean
    @Primary
    public MyBean myBeanTwo(){
        return new MyBean();
    }
}

上面程式碼定義了兩個bean ,其中myBeanTwo 由@Primary 進行標註,表示它首先會進行註冊,使用測試類進行測試

// ------------------------------ 測試 Primary  ------------------------------
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfigWithPrimary.class);
MyBean bean = context.getBean(MyBean.class);
System.out.println(bean);

你可以嘗試放開@Primary ,使用測試類測試的話會發現出現報錯資訊,因為你嘗試獲取的是MyBean.class,而我們程式碼中定義了兩個MyBean 的型別,所以需要@Primary 註解表明哪一個bean需要優先被獲取。

文章參考:

spring @Profile的運用示例

https://www.javaguides.net/2018/10/spring-dependson-annotation-example.html

公眾號提供 優質Java資料 以及CSDN免費下載 許可權,歡迎你關注我

相關推薦

@Bean 註解解析

目錄 @Bean 基礎宣告 @Bean 基本構成及其使用 @Bean 註解與其他註解產生的火花 @Profile 註解 @Scope 註解 @Lazy 註解

SpringMVC之Controller常用註解功能解析

一、簡介 在SpringMVC中,控制器Controller負責處理由DispatcherServlet分發的請求,它把使用者請求的資料經過業務處理層處理之後封裝成一個Model ,然後再把該Model返回給對應的View進行展示。在SpringMVC 中提供了一個非常簡便

Java事務處理解析(七)—— 像Spring一樣使用Transactional註解(Annotation)

在本系列的上一篇文章中,我們講到了使用動態代理的方式完成事務處理,這種方式將service層的所有public方法都加入到事務中,這顯然不是我們需要的,需要代理的只是那些需要操作資料庫的方法。在本篇中,我們將講到如何使用Java註解(Annotation)來標記需要事務處

SpringMVC之@Controller常用註解功能解析

一、簡介在SpringMVC中,控制器Controller負責處理由DispatcherServlet分發的請求,它把使用者請求的資料經過業務處理層處理之後封裝成一個Model ,然後再把該Model返回給對應的View進行展示。在SpringMVC 中提供了一個非常簡便的定

Visual Studio 2017各版本安裝包離線下載、安裝解析

pla 離線文件 win10 unit splay and 文件下載 python擴展 erl 轉自 寂靜·櫻花雨 Visual Studio 2017各版本安裝包離線下載、安裝全解析 感謝IT之家網友 寂靜·櫻花雨 的投稿 關於Visual

jQuery Ajax 解析

windows 我不 編輯器 som lsp 開始 cif bob cache jQuery Ajax 全解析 本文地址: jQuery Ajax 全解析 本文作者:QLeelulu 轉載請標明出處! jQuery確實是一個挺好的輕量級的JS框架,能幫助我們快速的開發JS

Android異步載入解析之開篇瞎扯淡

com des turn pro 能夠 eat launch 卡頓 ring Android異步載入概述 Android異步載入在Android中使用的很廣泛,除了是由於避免在主線程中做網絡操作。更是為了避免在顯示時由於時間太長而造成ANR,添加顯示的流暢性,特別是像Li

Spring學習之路(三)bean註解管理AOP操作

spec resource 自定義屬性 開始 java framework XML 方法名 jar包 在類上面、方法上面、屬性上面添加註解;並用bean來管理; 書寫方法:@註解名稱(屬性名稱=值) 第一步:導入jar包   導入spring-aop.jar(spri

PHP 常量、PHP 變量解析(超局變量、變量的8種數據類型等)

ret each 回收 操作系統 js xml name static bject 單獨 常量特點 常量一旦被定義就無法更改或撤銷定義。 常量名不需要開頭的$ 與變量不同,常量貫穿整個腳本是自動全局的。 作用域不影響對常量的訪問 常量值只能是字符串或數字 設置 PHP

一起寫框架-Ioc內核容器的實現-對象的調用-@Bean註解註入容器的對象(十二)

擴展 lac iter component cts block 根據 spa urn 實現功能 現實需求中,有一些類似無法加入掃描組件註解的。如jdk裏面的類。 那麽框架必須要支持將沒有組件註解標識的類也可以有一個方式註入到容器裏面。 那麽,我們通過類似Spring的@

資深站長幹貨:小說網站從建立到盈利解析

網絡資源從2007年做站,剛好十年了。時間過得真快。因為自己是兼職做站,所以一直斷斷續續,也沒有什麽大的成績。做過地方論壇,電影站,股票站,文章站,小說站等,能嘗試的都嘗試了。學了很多東西,也浪費了不少時間,做為一種愛好,就這樣堅持下來了。從剛開始的虛擬主機,到後來的VPS,再到現在的獨立服務器;經歷過網站沒

Python 直接賦值、淺拷貝和深度拷貝解析

ima img 引入 對象的引用 print function 引用 輸出結果 ons 直接賦值:其實就是對象的引用(別名)。 淺拷貝(copy):拷貝父對象,不會拷貝對象的內部的子對象。 深拷貝(deepcopy): copy 模塊的 deepcopy 方法

java事務處理解析

成功 spa 做了 開發 overflow lan 進行 訪問 ksh 最近學習java事務,看到一位前輩的系列博客不錯,轉載過來作為記錄 轉載地址:http://www.davenkin.me/post/2013-02-16/40048284001 (一)Jav

Dagger2 使用解析

ember factor 控制器 oid 好處 人的 field 會有 幫我 Dagger2 使用全解析 Dagger是一個註入工具,何為註入,我們要生產一批機器人,每個機器人都有一個控制器,我們可以在機器人內部 new 出一個控制器: class Robot {

【面試加分項】java自己定義註解解析註解

有一個 構造 ace catch .get doc 做的 document field 我之前的博客中說明過自己定義註解的聲明今天我們來看看怎樣對我們自己定義的註解進

【嵌入式】Arduino編程基礎到應用解析

接口 實現 關於 第一次 學習 wid 標誌位 解碼 post Arduino Author: Andrew.Du 基礎 基礎語法: setup() loop() pinMode(引腳,模式) pinMode(13,OUTPUT);

IOC裝配Bean(註解方式)(5)

IOC裝配Bean(註解方式)Spring的註解裝配Bean Spring2.5 引入使用註解去定義Bean @Component 描述Spring框架中Bean Spring的框架中提供了與@Component註解等效的三個註解: @Repository 用於對DAO實現類進行標註 @Service 用

spring-bean(註解方式-管理及依賴註入)

sca 支持 nbsp 開啟 const tex ng- autowire 作用 Bean管理(註解方式) 1、添加註解的依賴包:Spring-aop.jar 2、配置spring的XML文件的引入(查官方源碼) 3、開啟註解的掃描 <context:compon

spring常用管理bean註解

fig tran ebean 構造 control prop repos set resp spring提供了多個註解聲明Bean為spring管理的Bean @Controller  聲明此類是一個MVC類,通常與@RequestMapping一起使用 @Con

NGINX源碼安裝配置詳解(./configure),最解析

unzip roo without rpc服務 所有 googl 版本 並且 大文件 NGINX ./configure詳解 在"./configure"配置中,"--with"表示啟用模塊,也就是說這些模塊在編譯時不會自動構建&qu