Spring注解之@Import用法解析

Posted 于大圣

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring注解之@Import用法解析相关的知识,希望对你有一定的参考价值。

前言:最近在回顾阅读Springboot源码时发现框架层面大量使用@Import注解,特别是Springboot自动装配机制更是大量使用该注解,搜索部分结果图如下。简单来说就是Springboot中用到了Spring中的@Import注解来帮助实现自动装配。那么本篇博客就来结合@Import注解源码,学习下该注解的日常使用以便进一步理解Springboot自动装配原理。

Spring中@Import注解的出现是Spring迈向注解化道路上重要的一步,一般结合@Configuration注解来使用来导入配置类或者一些特殊用途的类到IOC容器中,传统Springmvc项目会出现如下大量的*.xml配置文件,有了@Import之后一定程度上会减少xml配置文件数目或者xml中配置的内容;

有兴趣的话可以先阅读下@Import中的文档注释,注释中对@Import的用法做了完整描述,下面内容是我对文档注释的总结,通过第2条我们可以得出@Import的四个用法,下面将针对这四个用法进行讲解。

  1. 设计目的就是用来导入一个或多个配置类;
  2. 功能同SpringXML文件中的import元素一致,用来导入被@Configuration注解的类、ImportSelector和ImportBeanDefinitionRegistrar的实现类以及Spring4.2起的普通component;
  3. 被@Import注解所导入的类可以作为IOC容器中正常的Component来使用;
  4. 在导入像XML或者没有被@Configuration所注解类定义资源文件时,使用@ImportResource代替;

注意:以下代码可以新建一个java项目,然后引入Spring必要jar包即可,本文为了方便还是在Springboot项目基础上演示,只是为了用Spring必要jar而已;

1、新建一个Springboot项目,项目结构如下

2、base包下类就是普通类,只包含一个重写的toString()方法。base包下类的作用就是为了演示可以被导入,仅此而异。下面只贴出JdbcConfig类的实现,类中注释已删除,其它类只是类名不一样,大家复制粘贴改名即可:

package com.dongnao.base;

public class JdbcConfig 

    @Override
    public String toString() 
        return this.getClass().getName() + "实例化成功!";
    


3、下面贴出config包下类的实现,只保留有用注释,大家参照注释理解用法;

package com.dongnao.config;

/**
 * @description: 没有被@Configuration所修饰的普通BEAN
 */
public class ComponentWithoutConfigAnnotation 

    @Override
    public String toString() 
        return this.getClass().getName() + "实例化成功!";
    


package com.dongnao.config;

import com.dongnao.base.RedisConfig;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @description: 被@Configuration所修饰的配置类
 */
@Configuration
public class ComponentWithConfigAnnotation 

    @Bean
    public RedisConfig instanceRedisTemplate() 
        return new RedisConfig();
    

package com.dongnao.config;

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

/**
 * @description: ImportSelector实现类, 通过提供selectImports方法的实现来提供
 * 被导入类(一般为配置类)的全路径名称列表
 */
public class ImportSelectorImpl implements ImportSelector 

    @Override
    public String[] selectImports(AnnotationMetadata importingClassMetadata) 
        return new String[]"com.dongnao.base.OssConfig";
    

package com.dongnao.config;

import com.dongnao.base.JdbcConfig;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.type.AnnotationMetadata;

/**
 * @description: ImportBeanDefinitionRegistrar实现类, 来实现直接注册BEAN
 */
public class ImportBeanDefinitionRegistrarImpl implements ImportBeanDefinitionRegistrar 
    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) 
        BeanDefinition jdbcConfig = new RootBeanDefinition(JdbcConfig.class);
        registry.registerBeanDefinition("jdbcConfig", jdbcConfig);
    

4、编写配置导入类,该类中对配置类通过@Import注解进行导入:

package com.dongnao.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;

/**
 * @description: 配置导入类
 */
@Configuration
@Import(ComponentWithoutConfigAnnotation.class, ComponentWithConfigAnnotation.class, ImportSelectorImpl.class, ImportBeanDefinitionRegistrarImpl.class)
public class ImportConfiguration 

    @Override
    public String toString() 
        return this.getClass().getName() + "实例化成功!";
    


5、编写简单测试类,测试后发现均能从ApplicationContext中获取实例化对象。

package com.dongnao;

import com.dongnao.base.JdbcConfig;
import com.dongnao.base.OssConfig;
import com.dongnao.base.RedisConfig;
import com.dongnao.config.ComponentWithoutConfigAnnotation;
import com.dongnao.config.ImportConfiguration;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class FirstAppByGuiApplication 
    public static void main(String[] args) 
        // 利用ImportConfiguration配置类来实例化ApplicationContext
        ApplicationContext applicationContext = new AnnotationConfigApplicationContext(ImportConfiguration.class);
        // 测试能否从ApplicationContext获取实例对象
        System.out.println(applicationContext.getBean(ImportConfiguration.class));
        System.out.println(applicationContext.getBean(ComponentWithoutConfigAnnotation.class));
        System.out.println(applicationContext.getBean(JdbcConfig.class));
        System.out.println(applicationContext.getBean(RedisConfig.class));
        System.out.println(applicationContext.getBean(OssConfig.class));
    

总结:Spring框架提供了@Import,一般结合@Configuration使用,来导入一些配置或者特殊用途的类纳入到Spring容器中。Spring框架包含方方面面,简单来说你只要这么配置了,Spring容器在初始化装在Bean时就会读取到。一般采用@Import导入的类有四种情形,每种情形大家酌情使用即可;

以上,完了!

以上是关于Spring注解之@Import用法解析的主要内容,如果未能解决你的问题,请参考以下文章

spring注解之@Import注解的三种使用方式

spring注解之@Import注解的三种使用方式

spring4.1.8扩展实战之八:Import注解

dubbo起停之注解

Java注解及其原理以及分析spring注解解析源码

spring源码之@Import