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

一文帶你了解SpringBoot中常用注解的原理和使用

 更新時(shí)間:2022年11月01日 14:32:33   作者:twilight0402  
這篇文章主要介紹了一文帶你了解SpringBoot中常用注解的原理和使用

@AutoConfiguration

讀取所有jar包下的 /META-INF/spring.factories 并追加到一個(gè) LinkedMultiValueMap 中。每一個(gè)url中記錄的文件路徑如下:

file:/C:/Users/wangchao/apache-maven-3.5.0/repo/com/baomidou/mybatis-plus-boot-starter/3.5.1/mybatis-plus-boot-starter-3.5.1.jar!/META-INF/spring.factories

按照如下路徑查看

// 1. @EnableAutoConfiguration
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
    
}

// 2. AutoConfigurationImportSelector.class#selectImports()
public class AutoConfigurationImportSelector implements DeferredImportSelector, BeanClassLoaderAware,
		ResourceLoaderAware, BeanFactoryAware, EnvironmentAware, Ordered {
	@Override
	public String[] selectImports(AnnotationMetadata annotationMetadata) {
		if (!isEnabled(annotationMetadata)) {
			return NO_IMPORTS;
		}
		AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(annotationMetadata);
		return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
	}
}

// 3. AutoConfigurationImportSelector.class#getAutoConfigurationEntry()
protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
	if (!isEnabled(annotationMetadata)) {
		return EMPTY_ENTRY;
	}
	AnnotationAttributes attributes = getAttributes(annotationMetadata);
	List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes);
	configurations = removeDuplicates(configurations);
	Set<String> exclusions = getExclusions(annotationMetadata, attributes);
	checkExcludedClasses(configurations, exclusions);
	configurations.removeAll(exclusions);
	configurations = getConfigurationClassFilter().filter(configurations);
	fireAutoConfigurationImportEvents(configurations, exclusions);
	return new AutoConfigurationEntry(configurations, exclusions);
}


// 4. AutoConfigurationImportSelector.class#getCandidateConfigurations()
protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
	List<String> configurations = SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(),
			getBeanClassLoader());
	Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you "
			+ "are using a custom packaging, make sure that file is correct.");
	return configurations;
}

// 5. org.springframework.core.io.support.SpringFactoriesLoader#loadFactoryNames()
public static List<String> loadFactoryNames(Class<?> factoryType, @Nullable ClassLoader classLoader) {
	String factoryTypeName = factoryType.getName();
	return loadSpringFactories(classLoader).getOrDefault(factoryTypeName, Collections.emptyList());
}

最終使用 loadSpringFactories(@Nullable ClassLoader classLoader) 方法讀取所有配置文件。

// 6. org.springframework.core.io.support.SpringFactoriesLoader#loadSpringFactories()
private static Map<String, List<String>> loadSpringFactories(@Nullable ClassLoader classLoader) {
		MultiValueMap<String, String> result = cache.get(classLoader);
		if (result != null) {
			return result;
		}

		try {
			Enumeration<URL> urls = (classLoader != null ?
					classLoader.getResources(FACTORIES_RESOURCE_LOCATION) :
					ClassLoader.getSystemResources(FACTORIES_RESOURCE_LOCATION));
			result = new LinkedMultiValueMap<>();
			while (urls.hasMoreElements()) {
			    // 讀取所有jar包下的 /META-INF/spring.factories
				URL url = urls.nextElement();
				UrlResource resource = new UrlResource(url);
				Properties properties = PropertiesLoaderUtils.loadProperties(resource);
				for (Map.Entry<?, ?> entry : properties.entrySet()) {
					String factoryTypeName = ((String) entry.getKey()).trim();
					for (String factoryImplementationName : StringUtils.commaDelimitedListToStringArray((String) entry.getValue())) {
						result.add(factoryTypeName, factoryImplementationName.trim());
					}
				}
			}
			cache.put(classLoader, result);
			return result;
		}
		catch (IOException ex) {
			throw new IllegalArgumentException("Unable to load factories from location [" +
					FACTORIES_RESOURCE_LOCATION + "]", ex);
		}
	}

tomcat的自動(dòng)配置內(nèi)置于springboot的autoconfiguration中。參考tomcat的自動(dòng)配置:SpringBoot如何實(shí)現(xiàn)Tomcat自動(dòng)配置

mybatis-plus的配置沒有被springboot包括。因此mybatis-stater中包含一個(gè)包mybatis-spring-boot-autoconfigure,這其中配置了需要自動(dòng)配置的類。

因此我們也可以在自己的項(xiàng)目下新建 /META-INF/spring.factories ,并配置自動(dòng)配置類。

@Import

@Import 用于導(dǎo)入配置類或需要前置加載的類。被導(dǎo)入的類會(huì)注冊(cè)為Bean,可直接作為Bean被引用。它的 value 屬性可以支持三種類型:

  • 被 @Configuration 修飾的配置類、或普通類(4.2版本之后可以)。
  • ImportSelector 接口的實(shí)現(xiàn)。
  • ImportBeanDefinitionRegistrar 接口的實(shí)現(xiàn)。

@Import 的配置

@Configuration
@Import(value = {TestA.class, TestB.class, MyImportSelector.class, MyImportBeanDefinitionRegistrar.class})
public class ConfigurationTest {

}

導(dǎo)入一個(gè)普通類

package com.example.ssmpdemo.entity;

public class TestA {
    public void fun(){
        System.out.println("testA");
    }
}

導(dǎo)入一個(gè)配置類

package com.example.ssmpdemo.entity;

import org.springframework.context.annotation.Configuration;

@Configuration
public class TestB {
    public void fun(){
        System.out.println("testB");
    }
}

通過實(shí)現(xiàn) ImportSelector 接口

import org.springframework.context.annotation.ImportSelector;
import org.springframework.core.type.AnnotationMetadata;

public class MyImportSelector implements ImportSelector {
    @Override
    public String[] selectImports(AnnotationMetadata importingClassMetadata) {
        return new String[]{"com.example.ssmpdemo.entity.TestC"};
    }
}

通過重寫 ImportBeanDefinitionRegistrar 的 registerBeanDefinitions 方法。

import com.example.ssmpdemo.entity.TestD;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.type.AnnotationMetadata;

public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {

    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        RootBeanDefinition root = new RootBeanDefinition(TestD.class);
        registry.registerBeanDefinition("testD", root);
    }
}

@ConfigurationProperties

  • 支持常見的下劃線、中劃線和駝峰的轉(zhuǎn)換。支持對(duì)象引導(dǎo)。比如:user.friend.name 代表的是user對(duì)象中的friend對(duì)象中的name
  • 需要有set()方法
  • 只添加 @ConfigurationProperties(prefix = "xxx") 并不會(huì)生效,需要配合 @Configuration 讓容器識(shí)別到。
  • @EnableConfigurationProperties(value = ConfigData.class ) 會(huì)將value中指定的類注冊(cè)為Bean,可直接用 @AutoWired 引用。

1.定義一個(gè)類用來記錄所有字段,并使用@ConfigurationProperties(prefix = "xxx")將數(shù)據(jù)注入到ConfigData中。

package com.example.ssmpdemo.entity;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;

/**
 * 用來記錄Configuration的數(shù)據(jù)
 * @author wangc
 */
@Data
@ConfigurationProperties(value = "spring.datasource.druid")
public class ConfigData {
    private String driverClassName;
    private String url;
    private String username;
    private String password;
}


# 對(duì)應(yīng)的yml文件
spring:
  datasource:
    druid:
      driver-class-name: com.mysql.cj.jdbc.Driver
      url: jdbc:mysql://localhost:5506/ssmpdemo?serverTimezone=UTC
      username: root
      password: xxxx

2.使用@EnableConfigurationProperties(JDBCProperties.class) 將 ConfigData 注冊(cè)為Bean,并提供給ConfigurationTest使用 ??蓪onfigData作為參數(shù)注入到構(gòu)造函數(shù)和普通函數(shù)中。

3.可以用以下方式引用被@ConfigurationProperties(value = "spring.datasource.druid")修飾的ConfigData

可以直接把 ConfigData 當(dāng)成Bean使用

    /**
     * 可直接被注入
     */
    @Autowired
    private ConfigData configData;

可以用構(gòu)造函數(shù)傳入進(jìn)來

@Data
@Configuration
@EnableConfigurationProperties(value = ConfigData.class )
public class ConfigurationTest {
    private ConfigData configData2;
    /**
     * 作為構(gòu)造函數(shù)的參數(shù)注入
     * @param data
     */
    ConfigurationTest(ConfigData data){
        this.configData2 = data;
    }

也可以作為@Bean的方法函數(shù)的參數(shù)。只有當(dāng)前類(ConfigurationTest)才可

    /**
     * 直接作為函數(shù)的參數(shù)
     * @param data
     * @return
     */
    @Bean(name = "configData2")
    HashMap<String, String> getBean(ConfigData data){
        return new HashMap<>(0);
    }

可以省略ConfigData直接將字段注入到返回結(jié)果中。

@Bean
@ConfigurationProperties(value = "spring.datasource.druid")
HashMap<String, String> getBean2(ConfigData data){
    // 會(huì)自動(dòng)為hashMap賦值,或使用set方法為對(duì)象賦值
    return new HashMap<>();
}

EnableConfigurationProperties注解的內(nèi)部如下,它導(dǎo)入了一個(gè)實(shí)現(xiàn)了 ImportBeanDefinitionRegistrar 接口的類。

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(EnableConfigurationPropertiesRegistrar.class)
class EnableConfigurationPropertiesRegistrar implements ImportBeanDefinitionRegistrar {

    @Override
    public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
        registerInfrastructureBeans(registry);
        ConfigurationPropertiesBeanRegistrar beanRegistrar = new ConfigurationPropertiesBeanRegistrar(registry);
        // 獲得@EnableConfigurationProperties的value指向的對(duì)象,并注冊(cè)。
        getTypes(metadata).forEach(beanRegistrar::register);
    }

到此這篇關(guān)于一文帶你了解SpringBoot中常用注解的原理和使用的文章就介紹到這了,更多相關(guān)SpringBoot注解內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • springboot-啟動(dòng)bean沖突的解決

    springboot-啟動(dòng)bean沖突的解決

    這篇文章主要介紹了springboot-啟動(dòng)bean沖突的解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-03-03
  • java實(shí)現(xiàn)后臺(tái)圖片跨域上傳功能

    java實(shí)現(xiàn)后臺(tái)圖片跨域上傳功能

    這篇文章主要給大家介紹了關(guān)于java實(shí)現(xiàn)后臺(tái)圖片跨域上傳功能的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用java具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-07-07
  • IntelliJ?IDEA教程之clean或者install?Maven項(xiàng)目的操作方法

    IntelliJ?IDEA教程之clean或者install?Maven項(xiàng)目的操作方法

    這篇文章主要介紹了IntelliJ?IDEA教程之clean或者install?Maven項(xiàng)目的操作方法,本文分步驟給大家介紹兩種方式講解如何調(diào)試出窗口,需要的朋友可以參考下
    2023-04-04
  • SpringBoot+Vue+Flowable模擬實(shí)現(xiàn)請(qǐng)假審批流程

    SpringBoot+Vue+Flowable模擬實(shí)現(xiàn)請(qǐng)假審批流程

    這篇文章主要為大家詳細(xì)介紹了如何利用SpringBoot+Vue+Flowable模擬實(shí)現(xiàn)一個(gè)請(qǐng)假審批流程,文中的示例代碼講解詳細(xì),需要的可以參考一下
    2022-08-08
  • Java實(shí)現(xiàn)超市會(huì)員管理系統(tǒng)

    Java實(shí)現(xiàn)超市會(huì)員管理系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)超市會(huì)員管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • SpringBoot解析指定Yaml配置文件的實(shí)現(xiàn)過程

    SpringBoot解析指定Yaml配置文件的實(shí)現(xiàn)過程

    這篇文章主要介紹了SpringBoot解析指定Yaml配置文件,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-03-03
  • java中Lamda表達(dá)式講解

    java中Lamda表達(dá)式講解

    本文詳細(xì)講解了java中的Lamda表達(dá)式,文中通過示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-12-12
  • 解析Java圖形化編程中的文本框和文本區(qū)

    解析Java圖形化編程中的文本框和文本區(qū)

    這篇文章主要介紹了Java圖形化編程中的文本框和文本區(qū),是Java入門學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下
    2015-10-10
  • SpringBoot之RestTemplate在URL中轉(zhuǎn)義字符的問題

    SpringBoot之RestTemplate在URL中轉(zhuǎn)義字符的問題

    這篇文章主要介紹了SpringBoot之RestTemplate在URL中轉(zhuǎn)義字符的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-06-06
  • springsecurity中http.permitall與web.ignoring的區(qū)別說明

    springsecurity中http.permitall與web.ignoring的區(qū)別說明

    這篇文章主要介紹了springsecurity中http.permitall與web.ignoring的區(qū)別說明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-08-08

最新評(píng)論

宁德市| 西宁市| 日照市| 华坪县| 福海县| 柳州市| 成安县| 彭水| 新化县| 南郑县| 得荣县| 周口市| 海宁市| 高阳县| 昂仁县| 阳信县| 黄骅市| 巫溪县| 嵊州市| 志丹县| 保康县| 长治县| 钟山县| 沁水县| 德昌县| 准格尔旗| 镇坪县| 突泉县| 安丘市| 阿坝县| 罗城| 洛南县| 固阳县| 广饶县| 北流市| 新闻| 克山县| 会同县| 乌海市| 如皋市| 无棣县|