Spring的@Import使用详解(干货)

@Import注解可以用在@Configuration注解的类上,也可以用在普通的类上。它作为一个元注解,可以标记其他注解。@Import注解支持多种方式把Bean导入到IOC容器中:

  • 普通类 或 @Configuration 注解的类
  • ImportSelector的实现类
  • ImportBeanDefinitionRegistrar的实现类

Spring4.2 版本之前只可以导入配置类,之后就可以导入普通类了。

使用形式:

@Import(A.class)                               // 普通类导入
@Import(MyImportSelector.class)                // 需实现 ImportSelector 接口
@Import(MyImportBeanDefinitionRegister.class)  // 需实现 ImportBeanDefinitionRegistrar 接口

@Import导入普通类

public class User {
    private String name;
}

/**
    直接使用 @Import 导入User类到IOC容器中
*/
@Import(User.class)
public class Demo {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext annCtx = new AnnotationConfigApplicationContext(Demo.class);
        // 这种方式由于未定义 Bean的别名, getBean时只能用类的class去拿
        User bean = annCtx.getBean(User.class);
        System.out.println(bean);
    }
}

@Import(User.class) 这种是直接导入普通类的模式,我们的User类上就不需要任何注解(它就是一个最普通的Java类)

@Import+ImportSelector的实现

定义一个 MyImportSelector类,实现 ImportSelector接口,重写 selectImports方法。

public class MyImportSelector implements ImportSelector {
    @Override
    public String[] selectImports(AnnotationMetadata importingClassMetadata) {
        // 也可以配置 @Configuration 注解的配置类, 实现多个bean的加载
        return new String[]{"com.bean.User"};
    }
}

@Import(MyImportSelector.class)
public class Demo {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext annCtx = new AnnotationConfigApplicationContext(Demo.class);
        User bean = annCtx.getBean(User.class);
        System.out.println(bean);
    }
}

ImportSelector 模式可以一次性配置多个类,而且代码也比较清晰,只需要配置类全名即可。
SpringBoot自动配置 就是基于 @Import 的 ImportSelector实现的

@Import+ImportBeanDefinitionRegistrar

这种方式需要我们实现 ImportBeanDefinitionRegistrar接口

// 实现 ImportBeanDefinitionRegistrar 接口, 主要对 BeanDefinition 进行操作
public class MyBeanDefinitionRegister implements ImportBeanDefinitionRegistrar {
    @Override
	public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        // 创建一个 BeanDefinition 类(即 Bean定义信息类), 用于接收 Java类
        AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(User.class).getBeanDefinition();
		// 把 User 注册为 Spring 的 <bean>, id 为 "user"
		registry.registerBeanDefinition("user", beanDefinition);
    }
}

@Import(MyBeanDefinitionRegister.class)
public class Demo {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext annCtx = new AnnotationConfigApplicationContext(Demo.class);
        User bean = annCtx.getBean(User.class);
        System.out.println(bean);
    }
}

有一个新的概念 BeanDefinition 简单理解就是 Bean的定义信息(Bean元数据),是需要IOC容器中进行管理的。总之,创建一个Bean,首先需要读取 BeanDefinition 类,然后才能去创建Bean

ImportBeanDefinitionRegistrar 使用案例

ImportBeanDefinitionRegistrar的案例非常多,Spring 集成AspectJ AOP 就是使用了 ImportBeanDefinitionRegistrar。

  • 定义一个 @EnableAspectJAutoProxy 注解
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {       // 开启Aop切面的注解
    boolean proxyTargetClass() default false;
    boolean exposeProxy() default false;
}

该注解核心代码:@Import(AspectJAutoProxyRegistrar.class),这也是Spring集成其他功能通用方式

  • 实现 AspectJAutoProxyRegistrar 接口
class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
    @Override
    public void registerBeanDefinitions( AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        // 注入 AspectJAnnotationAutoProxyCreator, 开启注解式AOP
        AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
        
        // 读取 @EnableAspectJAutoProxy注解的相关属性
        AnnotationAttributes enableAspectJAutoProxy = AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);
        if (enableAspectJAutoProxy != null) {
            if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
                AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
            }
            if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
                AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);  
            }
        }
    }
}
  • 代码中使用
@Configuration            //配置类
@EnableAspectJAutoProxy   //开启aop切面功能
public class AopConfig {
    
}

总结

@Import 使用非常广泛,我们经常看到的以 @Enable开头的注解,如 @EnableAspectJAutoProxy@EnableScheduling@EnableCaching等等,都是借助 @Import实现的。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Spring @Import注解用于引入其他配置类或者组件类到当前配置类中。当我们在一个配置类上使用@Import注解时,被引入的配置类或者组件类将会被Spring容器扫描并加载到容器中,使得我们可以在当前配置类中使用被引入类的bean。 通过@Import注解,我们可以将其他配置类引入到当前配置类中,以便于实现更复杂的配置。同时,@Import注解也可以用于引入普通的组件类,以便于在Spring容器中管理和使用这些组件类的实例。 @Import注解可以在JavaConfig中使用,通过将@Configuration注解的类标记为被引入的配置类,从而将其引入到当前配置类中。同时,@Import注解也可以直接在普通的组件类上使用,用于引入其他组件类。 总结来说,Spring @Import注解是一个用于引入其他配置类或者组件类的注解,通过该注解,我们可以方便地将其他类引入到当前配置类中,以便于在Spring容器中管理和使用这些类的实例。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [Spring注解之@Import用法](https://blog.csdn.net/qq_41378597/article/details/102799080)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值