Skip to content

注解

约 494 字大约 2 分钟

2025-01-03

Bean

由 Spring 容器管理的对象实例其可能是

  • @Component@Controller@Service等标记的类的实例(Spring 默认为单例模式,因此具有状态的 Bean 线程不安全)
  • @Bean注解在一个方法上,则表明将这个方法的返回示例交由 IOC 管理,此外该注解所在的类需要被@Configure标记

@Bean

@Configuration  
public class FileUploadAutoConfig {  
    @Bean  
    public FileUploadUtil fileUploadUtil(){  
        System.out.println("开始进行自动配置操作");  
        return new FileUploadUtil();  
    }  
}

在配置类中,fileUploadUtil()方法被@Bean标记,且该方法返回一个FileUploadUtil类,此时就能够将FileUploadUtil类加入 IOC 中管理

作用

能够将一些第三方的类加入 IOC 容器管理,并通过@Autowire@Resource

@Import

只能使用在类上,能够快速将示例添加至 Spring IOC 容器中 image

@Import({类名.class})

将指定的 bean 加入 IOC 容器中

// 没有使用注释加入 IOC 的类
public class ResultUtil {}

// 使用 Import 手动导入类
@Import(ResultUtil.class)  
public class ProductTraceSystemApplication {  
    // ....方法调用
}

public class test {
	// 可以自动配置
	@Autowired  
	ResultUtil resultUtil;

	void test() {
		System.out.println(resultUtil);
	}
}

在以上代码中,通过@Import手动将一个类加入 Spring IOC 管理

与@Bean的区别

@Import导入的beanName默认为类全限定名,而@Bean默认为方法名

实现 ImportSelector 接口

public class MyImportSelector implements ImportSelector {
    @Override
    public String[] selectImports(AnnotationMetadata importingClassMetadata) {
        return new String[]{"com.shepherd.common.config.Student",
        "com.shepherd.common.config.Person"};
    }
}

实现方法selectImports(),返回一个类全限定名数组,通过@Import导入MyImportSelector即可将数组内的所有类一并导入,而MyImportSelector本身并不算作一个 Bean

@Configuration
@Import({MyImportSelector.class})
public class MyConfig {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MyConfig.class);
        String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();
        // 遍历Spring容器中的beanName
        for (String beanDefinitionName : beanDefinitionNames) {
            System.out.println(beanDefinitionName);
        }
    }
}
// springframework
myConfig
com.shepherd.common.config.Student
com.shepherd.common.config.Person

实现 ImportBeanDefinitionRegistrar 接口

public interface ImportBeanDefinitionRegistrar {
    default void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry, BeanNameGenerator importBeanNameGenerator) {
        registerBeanDefinitions(importingClassMetadata, registry);
    }

    default void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
    }
}

该方式一次只能注入一个 bean,且只有第一个实现生效