给容器中注册组件(bean)的几种方式
目录
(一)包扫描+组件标注注解(@Controller/@Service/@Repository/@Component)
有局限,只能给自己写的类加注解
【使用方式】
- 直接在类上加注解即可
(二)@Bean【导入的第三方包里面的组件】
Person.java
public class Person {
private String name;
private Integer age;
public Person() {
}
public Person(String name, Integer age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
使用@Bean()
方式注入
@Bean("bill")
public Person person01(){
return new Person("Bill Gates",62);
}
(三)@Import【快速给容器中导入一个组件】
【优势】
- 每次都是用
@Bean()
注解,无参构造器创建一个对象有点麻烦 - 使用这个注解可以直接快速给容器中导入一个组件
【使用方式】
1. @Import(要导入到容器中的组件):容器中就会自动注册这个组件,id默认是全类名
@Import({Red.class,Color.class})
public class MainConfig2 {
}
测试
public class IOCTest {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig2.class);
@Test
public void testImport(){
printBeans(applicationContext);
}
private void printBeans(AnnotationConfigApplicationContext applicationContext) {
String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();
for (String beanDefinitionName : beanDefinitionNames) {
System.out.println(beanDefinitionName);
}
}
}
结果
2. ImportSelector:返回需要导入的组件的全类名数组
MyImportSelector.java
需要导入的组件的全类名
public class MyImportSelector implements ImportSelector {
@Override
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
return new String[]{"com.example.study.bean.Blue","com.example.study.bean.Pink"};
}
}
配置类
@Import({MyImportSelector.class})
public class MainConfig2 {
}
结果
3. ImportBeanDefinitionRegistrar 手动注册bean到容器中
可以自己设置注册条件
当容器中有Pink.class
和Blue.class
才将RainBow.class
放到容器
public class MyImportBeanDefinitionRegistrer implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
boolean definition = registry.containsBeanDefinition("com.example.study.bean.Pink");
boolean definition1 = registry.containsBeanDefinition("com.example.study.bean.Blue");
if (definition && definition1){
RootBeanDefinition rootBeanDefinition = new RootBeanDefinition(RainBow.class);
registry.registerBeanDefinition("rainBow",rootBeanDefinition);
}
}
}
配置类
@Import({Pink.class,Blue.class,MyImportBeanDefinitionRegistrer.class})
public class MainConfig2 {
}
结果
(四)使用Spring提供的FactoryBean(工厂bean)
- 默认获取到的是工厂bean调用getObject创建的对象
- 要获取工厂Bean本身,我们需要给id前加一个
&
ColorFactoryBean .class
public class ColorFactoryBean implements FactoryBean<Color> {
@Override
public Color getObject() throws Exception {
return new Color();
}
@Override
public Class<?> getObjectType() {
return Color.class;
}
@Override
public boolean isSingleton() {
return true;
}
}
配置类MainConfig2 .java
,注入bean工厂
public class MainConfig2 {
@Bean
private ColorFactoryBean colorFactoryBean(){
return new ColorFactoryBean();
}
}
IOCTest.java
测试
public class IOCTest {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig2.class);
@Test
public void testImport(){
Object colorFactoryBean = applicationContext.getBean("colorFactoryBean");
System.out.println("工厂类getObject创建的对象====="+colorFactoryBean.getClass());
Object colorFactoryBean2 = applicationContext.getBean("&colorFactoryBean");
System.out.println("获取工厂Bean本身====="+colorFactoryBean2.getClass());
}
}
结果