@Import-给容器中导入组件

@Import-给容器中导入组件

英文学习:

  1. definition : 定义

给容器中添加组件:

  1. 包扫描 + 组件标注注解(@Controller, @Service, @Repository, @Component)
    • 只能导入自己写的类
  2. @Bean注解导入
    • 可以导入自己写的类, 也可以导入第三方包里面的组件
  3. @Import快速的给容器中导入一个组件
    • 如果使用第二种方式导入一个第三方包中的组件会比较麻烦, 使用@Import方式会比较简单

@Import注解源码:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Import {

	/**
	 * {@link Configuration @Configuration}, {@link ImportSelector},
	 * {@link ImportBeanDefinitionRegistrar}, or regular component classes to import.
	 */
	Class<?>[] value();

}

@Import基础用法: 给容器中快速导入一个组件

1.创建一个实体类

package com.ffyc.spring.model;

public class Red {
}

2.创建一个配置类, 在配置类上使用@Import注解导入实体类

package com.ffyc.spring.config;

import com.ffyc.spring.condition.LinuxCondition;
import com.ffyc.spring.condition.WindowsCondition;
import com.ffyc.spring.controller.MyTypeFilter;
import com.ffyc.spring.model.Person;
import com.ffyc.spring.model.Red;
import org.springframework.context.annotation.*;

import javax.swing.*;

@Configuration
@ComponentScan(value = "com.ffyc.spring")
@Import(Red.class)
public class PersonConfig {
    
}

3.测试:

package com.ffyc.spring.test;

import com.ffyc.spring.config.PersonConfig;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class Test5 {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(PersonConfig.class);
        String[] beanDefinitionNames = annotationConfigApplicationContext.getBeanDefinitionNames();
        for(String name : beanDefinitionNames) {
            System.out.println(name);
        }
    }
}

可以看到确实是将我们的Red实体类对象注册(创建)到了IOC容器中

使用@Import(“要导入到容器中的组件”)的方式, 容器中就会自动注册这个组件, id默认是全类名

@Import高级 : 使用ImportSelector

1. 创建实体类:

package com.ffyc.spring.model;

public class Black {
}
package com.ffyc.spring.model;

public class Color {
}

2. 创建一个MyImportSelector(实现ImportSelector接口)

  • 要重写其中的selectImports()抽象方法
package com.ffyc.spring.condition;

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

public class MyImportSelector implements ImportSelector {
    public String[] selectImports(AnnotationMetadata importingClassMetadata) {
        return new String[] {"com.ffyc.spring.model.Color", "com.ffyc.spring.model.black"};
    }
}

selectImports()方法最终会返回一个String[], 该String[]中的内容就是要注册到IOC容器中的类的全类名

AnnotationMetadata : 当前标注@Import注解的类的所有注解信息

3.创建一个配置类, 使用@Import注解

package com.ffyc.spring.config;

import com.ffyc.spring.condition.LinuxCondition;
import com.ffyc.spring.condition.MyImportSelector;
import com.ffyc.spring.condition.WindowsCondition;
import com.ffyc.spring.controller.MyTypeFilter;
import com.ffyc.spring.model.Person;
import com.ffyc.spring.model.Red;
import org.springframework.context.annotation.*;

@Configuration
@ComponentScan(value = "com.ffyc.spring")
@Import({Red.class, MyImportSelector.class})
public class PersonConfig {

}

一定要注意: @Import({Red.class, MyImportSelector.class}), 对于第一个Red.class, 确实表示的是要加载Red.class类型的实例到IOC容器中

但是第二个却不是表示要加载MyImportSelector.class类型的实例到IOC容器中, 因为此时的MyImportSelector类实现了ImportSelector接口, 这是一种@Import注解的高级用法, 底层会通过反射的方式调用其中的selectImports()方法获取到对应的返回值作为要导入的Bean实例

@Import高级 : 使用@ImportBeanDefinitionRegister

1. 创建实体类:

package com.ffyc.spring.model;

public class RainBow {
}

2.创建MyImportBeanDefinitionRegister类实现ImportBeanDefinitionRegister接口

package com.ffyc.spring.condition;

import com.ffyc.spring.model.RainBow;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanNameGenerator;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.type.AnnotationMetadata;

public class MyImportBeanDefinitionRegister implements ImportBeanDefinitionRegistrar {

    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        
        boolean b = registry.containsBeanDefinition("com.ffyc.spring.model.Red");
        boolean b1 = registry.containsBeanDefinition("com.ffyc.spring.model.Black");
        if(b && b1) {
            RootBeanDefinition rootBeanDefinition = new RootBeanDefinition(RainBow.class);
            registry.registerBeanDefinition("rainBow", rootBeanDefinition);
        }
    }
}

重写registerBeanDefinitions()方法

AnnotationMetadata : 当前类的注解信息

BeanDefinitionRegistry : BeanDefinition注册类

把所有需要添加到IOC容器中的bean, 调用beanDefinitionRegistry.registerBeanDefinition手工注册进来

创建的RootBeanDefinition对象表示Bean定义信息(Bean的类型, Bean的作用域等等)

调用registerBeanDefinition()方法的时候的第一个参数是给bean起名, 也就是bean的id值

  • 前两种方式的时候bean的id值都是默认的全类名, 但是对于这种方式中我们可以指定bean的id值

3.创建一个配置类, 使用@Import

package com.ffyc.spring.config;

import com.ffyc.spring.condition.LinuxCondition;
import com.ffyc.spring.condition.MyImportBeanDefinitionRegister;
import com.ffyc.spring.condition.MyImportSelector;
import com.ffyc.spring.condition.WindowsCondition;
import com.ffyc.spring.controller.MyTypeFilter;
import com.ffyc.spring.model.Person;
import com.ffyc.spring.model.Red;
import org.springframework.context.annotation.*;

@Configuration
@ComponentScan(value = "com.ffyc.spring")
@Import({Red.class, MyImportSelector.class, MyImportBeanDefinitionRegister.class})
public class PersonConfig {

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值