spring 学习 22 @Import注解的使用

@Import注解的简介

 @Import注解的作用:把类注册进spring IOC容器,采用的方式构造注入(默认构造器)

在spring 4.2以前,Import注解中的可以导入的类只有三种 

一、被@Configuration注解标注的类

二、ImportBeanDefinitionRegistrar接口的实现类

三、ImportSelector接口的实现类

 

在spring 4.2之后,普通的java类也可以被@Import注解导入到Spring IOC容器,现在@Import注解可以导入任何的类了,具体做分类就可以分成具体四种

一、普通java类

二、被@Configuration注解标注的类

三、ImportBeanDefinitionRegistrar接口的实现类

四、ImportSelector接口的实现类

在这篇博客中,只介绍前两种。

一、普通java类

下面是普通的java类

package com.spring.learn.bean;

import org.springframework.beans.factory.annotation.Value;

import lombok.Data;

@Data
public class DataSource {
    @Value("${username}")
    private String user;
    
    @Value("${password}")
    private String password;
    @Value("${url}")
    private String url;
    
    public DataSource() {
        System.out.println("DataSource的默认初始化器");

    }

}

 

 

 

package com.spring.learn.config;

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

import com.spring.learn.bean.DataSource;

@Configuration
@Import(value= {DataSource.class})//导入DataSource
@PropertySource("classpath:application.properties")
public class ImportTestConfig {

}

 

 

在Spring IOC容器中发现DataSource被注入了

package com.spring.learn.importMain;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;

import com.spring.learn.bean.DataSource;
import com.spring.learn.config.ImportTestConfig;

public class ImportAnnotationMain {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext applicationContext2 = new AnnotationConfigApplicationContext(
                ImportTestConfig.class);
        String[] definitionNames = applicationContext2.getBeanDefinitionNames();
        for (String name : definitionNames) {
            System.out.println(name);
        }
        
        DataSource dataSource=applicationContext2.getBean(DataSource.class);
        System.out.println(dataSource);
    }
}

运行结果

 

二、@Configuration注解标注的类

如果@Import类中的是被@Configuration注解标注的类(配置类),配置类会被注入到Spring IOC容器中的,同时配置类中的配置信息也会被加入到Spring容器中

下面配置类的信息:这个配置类会扫描com.zhang包及其子包

package com.spring.learn.config;

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

@Configuration
@ComponentScan("com.zhang")
public class ScanConfig3 {

}

 

导入@Configuration类

package com.spring.learn.config;

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

@Configuration
@Import(value= {ScanConfig3.class})//导入配置类
public class ImportTestConfig {

}

 

运行测试

package com.spring.learn.importMain;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;

import com.spring.learn.config.ImportTestConfig;

public class ImportAnnotationMain {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext applicationContext2 = new AnnotationConfigApplicationContext(
                ImportTestConfig.class);
        String[] definitionNames = applicationContext2.getBeanDefinitionNames();
        for (String name : definitionNames) {
            System.out.println(name);
        }
        
        
    }
}

运行结果

 

 

userController、userDao、userService这三个bean就是在ScanConfig3配置类中的要扫描的包下的类注入的

 

三、ImportBeanDefinitionRegistrar接口

指定要扫描的包,

把useDefaultFilters设置成false,则在com.personal.spring.bean包下的被@Service|@Componet|@Controller|@Repository标注的类都不会被注入容器
@Import(MyImportBeanDefinitionRegistrar.class),通过MyImportBeanDefinitionRegistrar的方法向spring容器注入bean
package com.personal.spring.config;

import com.personal.spring.registrar.MyImportBeanDefinitionRegistrar;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;

@Configuration
@ComponentScan(value = "com.personal.spring.bean",useDefaultFilters = false
)
@Import(MyImportBeanDefinitionRegistrar.class)
public class SpringConfig {
}

MyImportBeanDefinitionRegistrar的代码

package com.personal.spring.registrar;

import com.personal.spring.bean.RainBow;
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;

public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {

    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        BeanDefinition beanDefinition=new RootBeanDefinition(RainBow.class) ;

        registry.registerBeanDefinition("rainBow",beanDefinition);

    }

}

 

测试代码

package com.personal.spring.main;

import com.personal.spring.config.SpringConfig;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

import java.util.Arrays;

public class Main {

    public static void main(String[] args) {
        AnnotationConfigApplicationContext context=new AnnotationConfigApplicationContext(SpringConfig.class);
        String[] beanDefinitionNames = context.getBeanDefinitionNames();

        Arrays.stream(beanDefinitionNames).forEach(x-> System.out.println(x));
    }
}

 

运行结果

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
springConfig
rainBow

可以看到名字为rainBow bean被注入到spring容器中了



 

posted @ 2020-03-20 21:26  阿瞒123  阅读(234)  评论(0编辑  收藏  举报