温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

Spring Framework中@Import组件如何使用

发布时间:2021-08-12 14:29:45 来源:亿速云 阅读:124 作者:Leah 栏目:开发技术

Spring Framework中@Import组件如何使用,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。

@Import 注册普通Bean

使用@Import注册一个普通Bean,只需要在@Import注解中指定待注册Bean的class即可

/**
 * 使用Import注解,注册一个普通的Bean
 */
@Data
public class TestImport {
    private String id = "@Import";
}

在spring启动引导类中,添加@Import注解

/**
 * spring 容器启动引导类
 */
@Import(TestImport.class)
public class TestImportBootstrap {

    public static void main(String[] args) {
        AnnotationConfigApplicationContext applicationContext =
                new AnnotationConfigApplicationContext(TestImportBootstrap.class);
        System.out.println("context id : " + applicationContext.getId());
        String[] beanNames = applicationContext.getBeanNamesForType(TestImport.class);
        System.out.println("Bean Name is : " + Arrays.toString(beanNames));
        TestImport bean = applicationContext.getBean(TestImport.class);
        System.out.println("TestImport bean : " + bean);
        applicationContext.close();
    }
}

spring容器启动后,控制台打印的结果:

context id : org.springframework.context.annotation.AnnotationConfigApplicationContext@21b8d17c
Bean Name is : [com.spring.study.ioc.register.TestImport]
TestImport bean : TestImport(id=@Import)

通过简单使用@Import注解,便可以将一个普通的javaBean注册到spring容器中。并且我们可以看到,通过@Import注解默认注册的组件名称为该javaBean的全类名

@Import 导入 配置类

使用@Import注解导入配置类,就会将配置类中的所有组件注册到spring容器中。在spring中,并不是@Configuration标注的类才是配置类,但是被@Configuration标注的类会被生成代理对象,spring注入时与不使用@Configuration注解有很大区别,后续会单独说明此处内容,本文不在赘述。

/**
 * spring组件配置类
 */
//@Configuration 使用@Import导入时,此注解可以不加
public class TestConfiguration {
    @Bean
    public TestImport testImport() {
        return new TestImport();
    }

    @Bean
    public TestImport testImport2() {
        return new TestImport();
    }
}

@Import注解中指定待导入的配置类

/**
 * spring 容器启动引导类
 */
@Import(TestConfiguration.class)
public class TestImportBootstrap {

    public static void main(String[] args) {
        AnnotationConfigApplicationContext applicationContext =
                new AnnotationConfigApplicationContext(TestImportBootstrap.class);
        System.out.println("context id : " + applicationContext.getId());
        String[] beanNames = applicationContext.getBeanNamesForType(TestImport.class);
        System.out.println("Bean Name is : " + Arrays.toString(beanNames));
        TestImport bean = (TestImport) applicationContext.getBean("testImport");
        System.out.println("TestImport bean : " + bean);
        applicationContext.close();
    }
}

spring容器启动后,配置类中的注解同样会被注册到spring容器中:

context id : org.springframework.context.annotation.AnnotationConfigApplicationContext@21b8d17c
Bean Name is : [testImport, testImport2]
TestImport bean : TestImport(id=@Import)

由结果可以看出,此时注册的组件名称即为配置类中指定的组件名称,并且通过配置类,可以一次导入多个组件。

@Import 通过ImportSelector 注册

ImportSelector接口中只定义了一个接口selectImports,通过此接口返回需要注册的JavaBean的全类名数组,在使用@Import导入时,会将接口返回的所有类注册到spring容器中

/**
 * 通过 ImportSelector 接口注册组件
 */
@Data
public class TestSelector {
    private String id = "@Import:ImportSelector";
}

自定义实现ImportSelector接口

/**
 * 自定义组件选择器,通过返回需要注册的bean的全类名,进行快速的在IOC容器中注册组件
 */
public class CustomImportSelector implements ImportSelector {

    /**
     * @param importingClassMetadata 标注了@Import配置类上面所有的注解信息
     */
    public String[] selectImports(AnnotationMetadata importingClassMetadata) {
        return new String[]{TestSelector.class.getName()};
    }
}

@Import注解中指定ImportSelector实现类

/**
 * spring 容器启动引导类
 */
@Import(CustomImportSelector.class)
public class TestImportBootstrap {

    public static void main(String[] args) {
        AnnotationConfigApplicationContext applicationContext =
                new AnnotationConfigApplicationContext(TestImportBootstrap.class);
        System.out.println("context id : " + applicationContext.getId());
        TestSelector bean = applicationContext.getBean(TestSelector.class);
        System.out.println("TestSelector bean : " + bean);
        String[] beanNames = applicationContext.getBeanNamesForType(TestSelector.class);
        System.out.println("bean names:" + Arrays.asList(beanNames));
        applicationContext.close();
    }
}

spring容器启动后,控制台打印的结果:

context id : org.springframework.context.annotation.AnnotationConfigApplicationContext@238e0d81
TestSelector bean : TestSelector(id=@Import:ImportSelector)
bean names:[com.spring.study.ioc.register.TestSelector]

由结果可以看出,TestSelector被注册到了spring容器中。与前面的直接注册相比,并没有看出ImportSelector接口的突出特性。本文只是简单的说明ImportSelector接口具有注册组件的功能,对于spring容器在启动时,如何执行BeanDefinitionRegistryPostProcessor来调用selectImports方法;如何使用ImportSelector接口实现更复杂的注册功能,将在后续文章中深入理解。

@Import 通过ImportBeanDefinitionRegistrar 注册

ImportBeanDefinitionRegistrar接口中只定义了一个registerBeanDefinitions方法,在此方法中,可以获取到BeanDefinitionRegistry对象,利用此对象,即可手动将需要的组件注册的spring容器中。在使用BeanDefinitionRegistry对象时,还可以指定组件在spring容器中注册的bean名称。

/**
 * 通过 ImportBeanDefinitionRegistrar 接口手动注册组件
 */
@Data
public class TestRegistrar {
    private String id = "@Import:TestRegistrar";
}

自定义实现ImportBeanDefinitionRegistrar接口

/**
 * 手动注册组件到IOC容器中
 */
public class CustomImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
    /**
     * @param importingClassMetadata 标注了@Import配置类上面所有的注解信息
     * @param registry               BeanDefinition注册器,可以通过此registry手动的向容器中注册指定的组件
     */
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        if (!registry.containsBeanDefinition("testRegistrar")) {
            BeanDefinition definition = new RootBeanDefinition(TestRegistrar.class);
            registry.registerBeanDefinition("testRegistrar", definition);
        }
    }
}

@Import 注解中指定ImportBeanDefinitionRegistrar实现类

/**
 * spring 容器启动引导类
 */
@Import(CustomImportBeanDefinitionRegistrar.class)
public class TestImportBootstrap {

    public static void main(String[] args) {
        AnnotationConfigApplicationContext applicationContext =
                new AnnotationConfigApplicationContext(TestImportBootstrap.class);
        System.out.println("context id : " + applicationContext.getId());
        TestRegistrar bean = applicationContext.getBean(TestRegistrar.class);
        System.out.println("TestRegistrar bean : " + bean);
        String[] beanNames = applicationContext.getBeanNamesForType(TestSelector.class);
        System.out.println("bean names:" + Arrays.asList(beanNames));
        applicationContext.close();
    }
}

spring容器启动后,控制台打印的结果:

context id : org.springframework.context.annotation.AnnotationConfigApplicationContext@238e0d81
TestRegistrar bean : TestRegistrar(id=@Import:TestRegistrar)
bean names:[testRegistrar]

由此可以看出,TestRegistrar被注册到了spring容器中。与ImportSelector接口一样,在spring容器启动时,通过BeanDefinitionRegistryPostProcessor来执行接口方法。

@Import同时指定多种接口注册

上面的例子中分别说明了使用@Import,通过直接导入Bean class,配置类,ImportSelector接口,ImportBeanDefinitionRegistrar接口来向spring容器中注册组件。当然在使用@Import注解时,可以同时指定上面的任意几种方式进行注册

/**
 * spring 容器启动引导类
 *
 * @author TangFD
 * @since 2019/6/25.
 */
@Import({
        TestComponent.class,
        TestConfiguration.class,
        CustomImportSelector.class,
        CustomImportBeanDefinitionRegistrar.class
})
public class TestImportBootstrap {

    public static void main(String[] args) {
        AnnotationConfigApplicationContext applicationContext =
                new AnnotationConfigApplicationContext(TestImportBootstrap.class);
        System.out.println("context id : " + applicationContext.getId());
        String[] beanNames = applicationContext.getBeanDefinitionNames();
        System.out.println("bean names:" + Arrays.asList(beanNames));
        applicationContext.close();
    }
}

spring容器启动后,控制台打印的结果:

context id : org.springframework.context.annotation.AnnotationConfigApplicationContext@238e0d81
bean names:[org.springframework.context.annotation.internalConfigurationAnnotationProcessor, org.springframework.context.annotation.internalAutowiredAnnotationProcessor, org.springframework.context.annotation.internalCommonAnnotationProcessor, org.springframework.context.event.internalEventListenerProcessor, org.springframework.context.event.internalEventListenerFactory, testImportBootstrap, com.spring.study.ioc.register.TestComponent, com.spring.study.ioc.register.TestConfiguration, testImport, testImport2, com.spring.study.ioc.register.TestSelector, testRegistrar]

看完上述内容是否对您有帮助呢?如果还想对相关知识有进一步的了解或阅读更多相关文章,请关注亿速云行业资讯频道,感谢您对亿速云的支持。

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI