Five, Spring in @Import comment

First, the components used to import annotations @Import

@Import annotation function is introduced to the container assembly, we import the review mode to the container assembly, may be configured by a Spring xm, by annotation, such as @Componentand the like, may be introduced to the container by way of the configuration classes java Notes, today to introduce another comment, its role is to import components to the container.


Its usage is very simple, we give a small example,

Configuration class MainConfig2

@Configuration
@Import({Color.class,Red.class})//将这两个类导入到容器中
//@Import导入组件,id默认是组件的全类名
public class MainConfig2 {


}

Which Color.class and Red.class are two very common java class, you do not care what these two classes of special.

We write a test method for the name of the vessel under traversal bean components

@Test
public void printBeans(AnnotationConfigApplicationContext applicationContext){
    AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig2.class);
        String[] definitionNames = applicationContext.getBeanDefinitionNames();
        for (String name : definitionNames) {
            System.out.println(name);
        }
    }

We are concerned about the results of the next print:

mainConfig2
com.atguigu.bean.Color //@Import导入组件,id默认是组件的全类名
com.atguigu.bean.Red

Two, @ Import Import ImportSelector

Can be seen above, this approach to import it? Or a little trouble spots, if a lot of components, is more troublesome, so, we can also be used in conjunction with ImportSelector

First, we write two classes called Bule.javaand Yellow.javawhat kind does not have to be concerned about there, even if it is an empty class is possible, we only care about whether it can be injected into the correct assembly

How then to use ImportSelectorit?

This is an interface, inherited and can achieve.

//自定义逻辑返回需要导入的组件
public class MyImportSelector implements ImportSelector {

    //返回值,就是到导入到容器中的组件全类名
    //AnnotationMetadata:当前标注@Import注解的类的所有注解信息
    @Override
    public String[] selectImports(AnnotationMetadata importingClassMetadata) {
        //方法不要返回null值
        return new String[]{"com.atguigu.bean.Blue","com.atguigu.bean.Yellow"};
    }
}

Introduced for this selector, the name of this method selectImportscan be seen ,, selective introduction means, so that in this method, we can write different logic to return the components we need to import, and that from above select introducer defined, only to demonstrate, there is no specific condition judgment, self-expansion, to return the component to import BlueandYellow

Then this class is added to the @Importannotation parameters, like so

@Configuration
@Import({Color.class,Red.class,MyImportSelector.class})//将这两个类导入到容器中
//@Import导入组件,id默认是组件的全类名
public class MainConfig2 {
}

We still print under the results of the test method used earlier:

mainConfig2
com.atguigu.bean.Color
com.atguigu.bean.Red
com.atguigu.bean.Blue //Blue被注册进了容器中
com.atguigu.bean.Yellow // Yellow被注册进了容器中

These are the use ImportSelector interface is relatively simple.

Three, @ Import Import ImportBeanDefinitionRegistrar

ImportBeanDefinitionRegistrarAnd ImportSelectorusing roughly the same, it is the interface, we only need to implement it, and it as a parameter, you can put in @Import.

Custom implementation classMyImportBeanDefinitionRegistrar

public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {

    /**
     * AnnotationMetadata:当前类的注解信息
     * BeanDefinitionRegistry:BeanDefinition注册类;
     *      把所有需要添加到容器中的bean;调用
     *      BeanDefinitionRegistry.registerBeanDefinition手工注册进来
     */
    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        
        boolean definition = registry.containsBeanDefinition("com.atguigu.bean.Red");
        boolean definition2 = registry.containsBeanDefinition("com.atguigu.bean.Blue");
        if(definition && definition2){
            //指定Bean定义信息;(Bean的类型,Bean。。。)
            RootBeanDefinition beanDefinition = new RootBeanDefinition(RainBow.class);
            //注册一个Bean,指定bean名
            registry.registerBeanDefinition("rainBow", beanDefinition);
        }
    }

}

Add this custom class in the configuration class annotation @Import

@Configuration
@Import({Color.class,Red.class,MyImportSelector.class,MyImportBeanDefinitionRegistrar.class})//将这两个类导入到容器中
//@Import导入组件,id默认是组件的全类名
public class MainConfig2 {
}

Still use it just to test methods for printing

mainConfig2
com.atguigu.bean.Color
com.atguigu.bean.Red
com.atguigu.bean.Blue
com.atguigu.bean.Yellow
rainBow // 自定义MyImportBeanDefinitionRegistrar的注册组件

After registering comparison of the two methods, we find that, ImportBeanDefinitionRegistrar is no return value, in addition to its more than one parameter BeanDefinitionRegistry, that is, you can register directly in the bean methods.

Fourth, detailed analysis

We look at ImportBeanDefinitionRegistrar source,

package org.springframework.context.annotation;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.core.type.AnnotationMetadata;
public interface ImportBeanDefinitionRegistrar {
    /**
     * Register bean definitions as necessary based on the given annotation metadata of
     * the importing {@code @Configuration} class.
     * <p>Note that {@link BeanDefinitionRegistryPostProcessor} types may <em>not</em> be
     * registered here, due to lifecycle constraints related to {@code @Configuration}
     * class processing.
     * @param importingClassMetadata annotation metadata of the importing class
     * @param registry current bean definition registry
     */
    public void registerBeanDefinitions(
            AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry);

}

We look at the first parameter method AnnotationMetadata importingClassMetadata, which is annotated meta-information, information that is configured on all notes of the class, then you can MyImportBeanDefinitionRegistrardefine the logic of our own needs from dynamic registration bean,

The difference is that this category by BeanDefinitionRegistryitself can be registered components.

Guess you like

Origin www.cnblogs.com/heliusKing/p/11372014.html