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导入的类有四种情形,每种情形大家酌情使用即可;

以上,完了!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
@EnableScheduling 是 Spring 框架中提供的一个注解,用于开启基于注解的定时任务。其主要作用是扫描带有 @Scheduled 注解的方法,并在指定的时间间隔内执行这些方法。 该注解的源码如下: ```java @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Import(SchedulingConfiguration.class) public @interface EnableScheduling { } ``` 可以看到,该注解使用了 @Import 注解,导入了 SchedulingConfiguration 类。这个类是 Spring 中的一个配置类,它实现了 SchedulingConfigurer 接口,用于配置任务调度器。 SchedulingConfiguration 类的源码如下: ```java @Configuration @Role(BeanDefinition.ROLE_INFRASTRUCTURE) public class SchedulingConfiguration implements SchedulingConfigurer { private volatile ScheduledTaskRegistrar taskRegistrar; @Override public void configureTasks(ScheduledTaskRegistrar taskRegistrar) { Assert.notNull(taskRegistrar, "ScheduledTaskRegistrar must not be null"); if (this.taskRegistrar != null && taskRegistrar != this.taskRegistrar) { throw new IllegalStateException("Only one ScheduledTaskRegistrar may exist"); } this.taskRegistrar = taskRegistrar; } @Bean(destroyMethod = "destroy") @Role(BeanDefinition.ROLE_INFRASTRUCTURE) public TaskScheduler taskScheduler() { return createDefaultTaskScheduler(); } @Bean @Role(BeanDefinition.ROLE_INFRASTRUCTURE) public AnnotationAsyncExecutionAspect asyncExecutionAspect() { return AnnotationAsyncExecutionAspect.aspectOf(); } private TaskScheduler createDefaultTaskScheduler() { ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler(); scheduler.setThreadNamePrefix("spring-task-scheduler-"); return scheduler; } } ``` 可以看到,该类中定义了一个 taskScheduler() 方法,用于创建默认的任务调度器。同时,它还实现了 SchedulingConfigurer 接口,重写了 configureTasks() 方法,用于配置任务调度器。 总的来说,@EnableScheduling 注解的作用就是开启 Spring 的定时任务功能,通过扫描带有 @Scheduled 注解的方法,自动创建定时任务并执行。同时,它还提供了一些默认的配置,例如默认的任务调度器等。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值