天天看点

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({});