天天看點

Springboot中@Ehable**學習 原

    Springboot版本是1.5.release.

    Springboot中使用EnableAutoConfiguration注解,如下所示:

    List-1

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(EnableAutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {

	String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";

	/**
	 * Exclude specific auto-configuration classes such that they will never be applied.
	 * @return the classes to exclude
	 */
	Class<?>[] exclude() default {};

	/**
	 * Exclude specific auto-configuration class names such that they will never be
	 * applied.
	 * @return the class names to exclude
	 * @since 1.3.0
	 */
	String[] excludeName() default {};

}           

複制

    主要是那個EnableAutoConfigurationImportSelector,繼承了接口ImportSelector,方法String[] selectImports(AnnotationMetadata var1)傳回的類都會注入到Sping容器中。

    我們來實作一個自己的ImportSelector。

Springboot中@Ehable**學習 原

                  圖1

    如圖1所示,我們定義自己的類SelectorA、SelectorB、SelectorC,定義MyImportSelector如下所示:

List-2

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

public class MyImportSelector implements ImportSelector {
    //會将這個方法傳回的數組,放到容器中
    @Override
    public String[] selectImports(AnnotationMetadata annotationMetadata) {
        return new String[]{"com.mjduan.project.springbootlearn.selector.SelectorA",
                "com.mjduan.project.springbootlearn.selector.SelectorB"};
    }
}           

複制

    之後定義自己的EnableMyX,如下List-3

List-3

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import({MyImportSelector.class})
public @interface EnableMyX {
}           

複制

    在main方法的類上加上注解EnableMyX,如下所示:

List-4

import com.mjduan.project.springbootlearn.enable.EnableEcho;
import com.mjduan.project.springbootlearn.selector.EnableMyX;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
@EnableMyX
public class SpringbootLearnApplication {

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

複制

    我們通過BeanPostProcessor來驗證SelectorA和SelectorB加入到容器中了,如下

List-5

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component;

@Component
public class MyImportSelectorBeanPostProcessor implements BeanPostProcessor {
    private String[] classess={
            "com.mjduan.project.springbootlearn.selector.SelectorA",
        "com.mjduan.project.springbootlearn.selector.SelectorB"};

    @Override
    public Object postProcessBeforeInitialization(Object o, String s) throws BeansException {
        return o;
    }

    @Override
    public Object postProcessAfterInitialization(Object o, String s) throws BeansException {
        for (String str : classess) {
            if (o.getClass().getName().equals(str)) {
                System.out.println(o.getClass().getName());
            }
        }
        return o;
    }
}           

複制

    之後啟動應用,在控制台就可以看到列印出的SelectorA和SelectorB了。

    ImportSelector傳回的String[]會被注入到Spring容器中,EnableAutoConfiguration中EnableAutoConfigurationImportSelector傳回的是META-INF/spring.factories中org.springframework.boot.autoconfigure.EnableAutoConfiguration的值,這些值都是些類名,這些類上都有@Configuration注解,這樣就将這個配置類中的bean加入到容器中。

思考

  1. 問題1,ImportSelector傳回的String[]是怎麼加入到Spring容器中的,在Springboot啟動流程中的哪個步驟呢?

Reference

  1. https://www.jianshu.com/p/3da069bd865c

(adsbygoogle = window.adsbygoogle || []).push({});