SpringBoot自動裝配


SpringBoot

自動裝配

啟動類通過@SpringBootApplication 進行啟動

@SpringBootApplication
public class DemoApplication {
    public static void main(String[] args) {
    		SpringApplication.run(DemoApplication.class, args);
    }
}

主要有3個重要的注解@SpringBootConfiguration ,@EnableConfiguration@ComponentScan

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = {
@Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {
}

@SpringBootConfiguration

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration
public @interface SpringBootConfiguration {
}

從源碼中可以看出SpringBootConfiguration是@Configuration的派生注解,與@Configuration注解的功能是一致的,標注這個類是一個配置類,只不過@SpringBootConfiguration是springboot的注解,而@Configuration是Spring的注解。

@EnableConfiguration

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import({EnableAutoConfigurationImportSelector.class})
public @interface EnableAutoConfiguration {
    String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";
    Class<?>[] exclude() default {};
    String[] excludeName() default {};
}

@EnableAutoConfiguration注解的作用主要是開啟自動裝配的功能,有2個比較重要的注解@AutoConfigurationPackage:這個用來將啟動類所在包,以及下面所有子包里面的所有組件掃描到Spring容器中,如下圖,啟動類與engine包和smartcheck同級,Demo與onlyou包同級,當啟動類啟動時並不會加載到Demo類,這就是為什么我們在SpringBoot項目中要把啟動類放在項目的最高級中。

@Import({EnableAutoConfigurationImportSelectors.class})實現了ImportSelector接口,主要的是

public String[] selectImports(AnnotationMetadata metadata) {
  if (!this.isEnabled(metadata)) {
    	return NO_IMPORTS;
  } else {
    try {
      //獲取 @EnableAutoConfigoration 標注類的元信息,也就是獲取該注解 exclude、excludeName 屬性值
      AnnotationAttributes attributes = this.getAttributes(metadata);
      //獲取META-INF/spring.factories文件下自動裝配的類名集合
      List<String> configurations = this.getCandidateConfigurations(metadata, attributes);
      //去除重復的自動裝配組件,就是將List轉為Set進行去重
      configurations = this.removeDuplicates(configurations);
      //這部分就是根據上面獲取的 exclude 及 excludeName 屬性值,排除指定的類
      Set<String> exclusions = this.getExclusions(metadata, attributes);
      //刪除對應的例外配置
      configurations.removeAll(exclusions);
      //排序,因為自動配置會有bean引用依賴,先按字母排序,再根據order排序,再根據ConfigurationBefore等排序
      configurations = this.sort(configurations);
      //輸出滿足條件的配置項目
      this.recordWithConditionEvaluationReport(configurations, exclusions);
      return (String[])configurations.toArray(new String[configurations.size()]);
    } catch (IOException var5) {
      throw new IllegalStateException(var5);
    }
  }
}

@ComponentScan

自定義自動裝配

在 Spring Boot 項目中,我們將大量的參數配置在 application.properties 或 application.yml 文件中,通過@ConfigurationProperties 注解,我們可以獲取這些參數值

首先在目錄下新增配置文件類,通過@ConfigurationProperties注解該類對配置的屬性進行綁定

@ConfigurationProperties(prefix = "framework.service.trace")
public class ServiceTraceProperties {
    public static final String PREFIX = "framework.service.trace";
    private String endpoint;
    private boolean enabled;
    private Float sampling = 0.1F;
  
    public ServiceTraceProperties() {
    }

    public Float getSampling() {
        return this.sampling;
    }

    public void setSampling(Float sampling) {
        this.sampling = sampling;
    }

    public boolean isEnabled() {
        return this.enabled;
    }

    public void setEnabled(boolean enabled) {
        this.enabled = enabled;
    }

    public String getEndpoint() {
        return this.endpoint;
    }

    public void setEndpoint(String endpoint) {
        this.endpoint = endpoint;
    }
}

其次通過@Configuration聲明該類為bean,@EnableConfigurationProperties使使用 @ConfigurationProperties 注解的類生效。

@Configuration
@EnableConfigurationProperties({ServiceTraceProperties.class})
@ConditionalOnProperty(name = {"framework.service.trace.enabled"},havingValue = "true")
public class ServiceTraceConfiguration {
    @Autowired
    private ServiceTraceProperties properties;

    public ServiceTraceConfiguration() {
    }

    @Bean
    Sender sender() {
        return OkHttpSender.create(this.properties.getEndpoint());
    }

    @Bean
    AsyncReporter<Span> spanReporter() {
        return AsyncReporter.create(this.sender());
    }

    @Bean
    Tracing tracing(@Value("${framework.dubbo.application.name}") String serviceName) {
        return 					Tracing.newBuilder().sampler(CountingSampler.create(this.properties.getSampling())).localServiceName(serviceName).propagationFactory(ExtraFieldPropagation.newFactory(B3Propagation.FACTORY, new String[]{"user-name"})).currentTraceContext(ThreadLocalCurrentTraceContext.newBuilder().addScopeDecorator(MDCScopeDecorator.create()).build()).spanReporter(this.spanReporter()).build();
    }
}

最后在resource目錄下新建spring.factories 文件,將需要自動裝配的配置暴露出來

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.onlyou.framework.boot.autoconfigure.TransactionManagementAutoConfiguration,\
com.onlyou.framework.boot.autoconfigure.ServiceTraceConfiguration


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM