日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網為廣大站長提供免費收錄網站服務,提交前請做好本站友鏈:【 網站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

如果使用@ConditionalOnClass或@ConditionalOnMissingClass作為元注釋的一部分來組合自己的組合注釋,則必須使用name,因為在這種情況下引用類不會被處理。

理解自動配置bean

在底層,自動配置是用標準的@Configuration類實現的。附加的@Conditional注釋用于約束何時應用自動配置。通常,自動配置類使用@ConditionalOnClass和@ConditionalOnMissingBean注釋。這確保了自動配置僅在找到相關類且尚未聲明自己的@configuration時適用。

你可以瀏覽spring-boot-autoconfigure的源代碼,以查看Spring提供的@Configuration類(參見META-INF/spring.factories 文件)。

定位候選自動配置

Spring Boot檢查是否存在META-INF/spring.factories文件在你發布的jar中。該文件應該在EnableAutoConfiguration為key下列出你的配置類,如下例所示:

org.springframework.boot.autoconfigure.EnableAutoConfiguration=
com.pack.bus.autoconfigure.BusAutoConfiguration,
com.pack.bus.autoconfigure.BusWebAutoConfiguration

自動配置只能以這種方式加載。確保它們是在特定的包空間中定義的,并且它們永遠不是組件掃描的目標。此外,自動配置類不應該允許組件掃描來查找其他組件。應該使用特定的@Imports。

如果你的配置需要按特定順序應用,你可以使用@AutoConfigureAfter或@AutoConfigureBefore注釋。例如,如果你提供了特定于web的配置,你的類可能需要應用在WebMvcAutoConfiguration之后。

可以使用@AutoConfigureOrder。該注釋具有與常規@Order注釋相同的語義,但為自動配置類提供了專用的順序。

與標準的@Configuration類一樣,自動配置類的應用順序只影響其bean定義的順序。隨后創建這些bean的順序不受影響,由每個bean的依賴關系和@DependsOn關系決定。

條件注釋

你幾乎總是希望在自動配置類中包含一個或多個@Conditional注解。@ConditionalOnMissingBean注解是一個常見的例子,它允許開發人員在對默認值不滿足時覆蓋自動配置。

Spring Boot包含很多@Conditional注解,你可以在自己的代碼中重用這些注解,方法是注解@Configuration類或單獨的@Bean方法。這些注釋包括:

  • Class Conditions

@ConditionalOnClass和@ConditionalOnMissingClass注解讓@Configuration類根據特定類的存在與否被包含。由于注釋元數據是通過ASM解析的,因此你可以使用value屬性來引用真正的類,即使這個類可能實際上沒有出現在正在運行的應用程序類路徑中。如果想用字符串指定類名,也可以使用name屬性。

這種機制不適用于@Bean方法,因為@Bean方法的返回類型通常是條件的目標:在方法的條件應用之前,JVM將加載類并可能處理方法引用,如果類不存在,則這些引用將失敗。

為了處理這種情況,可以使用一個單獨的@Configuration類來隔離這種情況,如下面的例子所示:

@Configuration(proxyBeanMethods = false)
// Some conditions ...
public class MyAutoConfiguration {
  // Auto-configured beans ...
  @Configuration(proxyBeanMethods = false)
  @ConditionalOnClass(SomeService.class)
  public static class SomeServiceConfiguration {
    @Bean
    @ConditionalOnMissingBean
    public SomeService someService() {
      return new SomeService();
    }


  }
}

如果使用@ConditionalOnClass或@ConditionalOnMissingClass作為元注釋的一部分來組合自己的組合注釋,則必須使用name,因為在這種情況下引用類不會被處理。

  • Bean Conditions

@ConditionalOnBean和@ConditionalOnMissingBean注解讓一個bean根據特定bean的存在與否被包含進來。可以使用value屬性按類型指定bean,也可以使用name指定bean。search屬性允許您限制在搜索bean時應該考慮的ApplicationContext層次結構。

當放在@Bean方法上時,目標類型默認為方法的返回類型,如下面的例子所示:

@Configuration(proxyBeanMethods = false)
public class MyAutoConfiguration {


  @Bean
  @ConditionalOnMissingBean
  public SomeService someService() {
    return new SomeService();
  }
}
  • Property Conditions

@ConditionalOnProperty注解讓配置基于Spring環境屬性包含。使用prefix和name屬性指定要檢查的屬性。默認情況下,匹配任何存在且不等于false的屬性。你還可以使用havingValue和matchIfMissing屬性來創建更高級的檢查。

  • Resource Conditions

@ConditionalOnResource注解讓配置只在特定資源存在時才包含??梢允褂贸S玫腟pring約定來指定資源,如下面的例子所示。

  • Web Application Conditions

@ConditionalOnWebApplication和@ConditionalOnNotWebApplication注解讓應用程序根據是否是“web應用程序”來包含配置?;趕ervlet的web應用程序是任何使用Spring WebApplicationContext、定義會話范圍或具有ConfigurableWebEnvironment的應用程序。任何使用ReactiveWebApplicationContext或者ConfigurableReactiveWebEnvironment的應用都可以被稱為響應式web應用。

@ConditionalOnWarDeployment注解根據應用程序是否是部署到容器中的傳統WAR應用程序來包含配置。此條件不適用于與嵌入式服務器一起運行的應用程序。

  • SpEL Expression Conditions

@ConditionalOnExpression注解讓配置基于SpEL表達式的結果包含。

創建自己的Starter

  • 命名

你應該確保為你的starter程序提供適當的命名空間。即使你用了不同的Maven groupId,也不要用spring-boot來啟動模塊名。我們可能會在未來為你的自動配置提供官方支持。

根據經驗,你應該在starter之后命名一個組合模塊。例如,假設你正在為“acme”創建一個starter程序,并且你將自動配置模塊命名為acme-spring-boot,而starter程序命名為acme-spring-boot-starter。如果只有一個模塊組合了這兩個模塊,請將其命名為acme-spring-boot-starter。

  • 配置key

如果starter提供了配置key,它們使用唯一的命名空間。不要把key放在Spring Boot使用的命名空間中(比如server、management、Spring等)。

為每個屬性添加JAVAdoc,確保配置項有文檔記錄,如下面的例子所示。

@ConfigurationProperties("acme")
public class AcmeProperties {


  /**
   * Whether to check the location of acme resources.
   */
  private boolean checkLocation = true;
  /**
   * Timeout for establishing a connection to the acme server.
   */
  private Duration loginTimeout = Duration.ofSeconds(3);
}
  • 完整示例

本示例主要功能是實現日志記錄功能

自動配置類

@Configuration
@EnableConfigurationProperties(LogsProperties.class)
@ConditionalOnProperty(prefix = "logs", name = "enabled", havingValue = "true")
@EnableAspectJAutoProxy
public class LogsAutoConfiguration {
  
  private static final Logger logger = LoggerFactory.getLogger(LogsAutoConfiguration.class) ;
  
  @Resource
  private LogsProperties logsProperties ;
  
  @Bean
  public AspectJExpressionPointcutAdvisor logAdvisor() {
    AspectJExpressionPointcutAdvisor advisor = new AspectJExpressionPointcutAdvisor() ;
    logger.info("執行表達式:{}", logsProperties.getPointcut()) ;
    advisor.setExpression(logsProperties.getPointcut()) ;
    advisor.setAdvice(new SystemAroundOperator()) ;
    return advisor ;
  }
}

自定義注解

@Documented
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface SystemLog {
  
  /**
   * <p>操作說明</p>
   * @return
  */
  String value() default "" ;
}

屬性key配置

/**
 *   日志功能屬性配置
 *   @author xg
 */
@ConfigurationProperties(prefix = "logs")
public class LogsProperties {
  /**
   *   切入點定義<br/>
   *    示例:execution(public * com.pack.controller.*.*(..))
   */
  private String pointcut ;
  /**
   *   是否開啟日志功能
   */
  private boolean enabled = true ;
}

Advice定義

public class SystemAroundOperator implements MethodInterceptor {


  private static final Logger logger = LoggerFactory.getLogger(SystemAroundOperator.class);


  @Override
  public Object invoke(MethodInvocation invocation) throws Throwable {
    // 開始執行時間
    long start = System.currentTimeMillis();
    Method method = invocation.getMethod() ;
    SystemLog annoLog = null ;
    if (method.isAnnotationPresent(SystemLog.class)) {
      annoLog = method.getAnnotation(SystemLog.class) ;
      String value = annoLog.value() ;
      try {
        Object result = invocation.proceed() ;
        // 方法執行時間
        Long execTime = System.currentTimeMillis() - start ;
        logger.info("{}, 業務執行時間:{} ms", value, execTime) ;
        return result ;
      } catch (Throwable t) {
        Long execTime = System.currentTimeMillis() - start ;
        logger.info("{}, 業務執行時間:{} ms,發生異常信息:{}", value, execTime, t.getMessage()) ;
        throw t ;
      }
    }
    return invocation.proceed();
  }
}

配置META-INFspring.factories

org.springframework.boot.autoconfigure.EnableAutoConfiguration=
com.pack.config.LogsAutoConfiguration

以上就實現自定義starter的流程。

分享到:
標簽:SpringBoot
用戶無頭像

網友整理

注冊時間:

網站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網站吧!
最新入駐小程序

數獨大挑戰2018-06-03

數獨一種數學游戲,玩家需要根據9

答題星2018-06-03

您可以通過答題星輕松地創建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數有氧達人2018-06-03

記錄運動步數,積累氧氣值。還可偷

每日養生app2018-06-03

每日養生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定