SpringBoot交给IOC管理对象的几种方式

@Component

  • 第一种方式是@Component方式,标志这个类是一个Bean对象
  • 要放在启动类的目录或者子目录下,不然需要在加上@ComponentScan来扫描
  • 通过加在类上实现
@Component
class Test{

}
  • 还有同等注解@Controller加在控制层,@Service服务层,@Repository持久层,@Configuration配置类,因为他们都使用了@Component
    在这里插入图片描述

@Bean

  • 第二种@Bean,这个注解要加在方法上,然后返回值是要实例化的类
//必须先让这个类被springboot扫描到@Bean才会起作用
@Configuration
class Test{

	@Autowired
	TestClass testClass;

	//返回了实例那么这个实例会被springboot所管理
	@Bean
	public TestClass getTestClass(){
		return new TestClass();
	}

	@PostConstruct
	public void print(){
		System.out.println(testClass);
	}
}

class TestClass{

}

@Import

  • 第三种@Import注解,可以直接导入想要被springboot管理的类
@Configuration
//value是一个数组,可以写多个class。比如a.class,b.class
@Import(TestClass.class)
class Test{

	@Autowired
	TestClass testClass;

	@PostConstruct
	public void print(){
		System.out.println(testClass);
	}
}

class TestClass{

}

@Import搭配ImportSelector

  • 第四种@Import搭配ImportSelector,实现ImportSelector的方法实例化多个bean
@Configuration
@Import(TestClass.class)
class Test{

	@Autowired
	TestSelectImports testSelectImports;

	@PostConstruct
	public void print(){
		System.out.println(testSelectImports);
	}
}
//TestClass类似于一个实例化类的工具类,自身不会被springboot所管理
class TestClass implements ImportSelector {
	//返回值是一个字符串数组,也是需要类的全类名
	@Override
	public String[] selectImports(AnnotationMetadata importingClassMetadata) {
		return new String[]{TestSelectImports.class.getName()};
	}
}

class TestSelectImports{

}
  • 输出:
    在这里插入图片描述

@Import搭配ImportBeanDefinitionRegistrar

  • 第五种是@Import搭配ImportBeanDefinitionRegistrar,实现这个接口的方法会交给我们一个BeanDefinitionRegistry,实现这个接口的都是工厂类,所以就是我们可以直接通过这个接口的方法把bean直接注册到工厂中
@Configuration
@Import(TestClass.class)
class Test{

	@Autowired
	TestSelectImports testSelectImports;

	@PostConstruct
	public void print(){
		System.out.println(testSelectImports);
	}
}

class TestClass implements ImportBeanDefinitionRegistrar {
	//AnnotationMetadata是谁导入了这个类也就是Test类
	//BeanDefinitionRegistry可以简单理解成Bean工厂,然后可以直接注册Bean
	//每个Bean都会被转换成BeanDefinition,里边包含了Bean的所有元数据信息
	@Override
	public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
		registry.registerBeanDefinition("testSelectImports",new RootBeanDefinition(TestSelectImports.class));
	}
}

class TestSelectImports{

}
  • 输出:
    在这里插入图片描述

BeanFactoryPostProcessor

  • 第六种我们可以实现BeanFactoryPostProcessor接口,他会返回给我们一个BeanFactory,我们可以任意操作,这是spring的一个扩展点,可以让我们在实例化Bean之前对元数据信息进行任意修改
@Component
class TestBeanFactory implements BeanFactoryPostProcessor {

	@Override
	public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
		//这个接口只有两个实现类,一个XmlFactory现实了DefaultListableBeanFactory并且被标记为废弃了
		//所以把它转换成子类,功能更多
		DefaultListableBeanFactory defaultListableBeanFactory = (DefaultListableBeanFactory) beanFactory;
		//直接向工厂注册Bean
		defaultListableBeanFactory.registerBeanDefinition("testSelectImports",new RootBeanDefinition(TestSelectImports.class));
	}
}

class TestSelectImports{

}

BeanDefinitionRegistryPostProcessor

  • 第七种是实现BeanDefinitionRegistryPostProcessor,它实现了上边的BeanFactoryPostProcessor,所以也有这个接口的功能
@Component
class TestBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor{

    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanDefinitionRegistry) throws BeansException {
        beanDefinitionRegistry.registerBeanDefinition("test",new RootBeanDefinition(TestBeanDefinitionRegistry.class));
    }

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
	//跟上边一样就不演示了
    }
}

class TestBeanDefinitionRegistry{

    public TestBeanDefinitionRegistry(){
        System.out.println("实例化TestBeanDefinitionRegistry");
    }
}
  • 输入:
    在这里插入图片描述

FactoryBean

  • 第八种是实现FactoryBean接口,这是一个工厂,也是一个Bean,可以用来生产对象,但也会被IOC所管理
@Component
//可以指定泛型
class MyFactoryBean implements FactoryBean<Object>{

    @Override
    public Object getObject() throws Exception {
    	//返回的就是要交给IOC管理的Bean
        return new Object();
    }
	
    @Override
    public Class<?> getObjectType() {
    	//Class对象
        return Object.class;
    }
}

@SpringBootApplication
public class DemoApplication {

	public static void main(String[] args) {
		ConfigurableApplicationContext run = SpringApplication.run(Demo123Application.class, args);
		//获取对象,通过名字获取的是返回的对象
		//通过&名字获取的是FactoryBean的对象		
		System.out.println(run.getBean("myFactoryBean"));
		System.out.println(run.getBean("&myFactoryBean"));
	}

}
  • 输出:
    在这里插入图片描述

总结

  • 这些方式中有的只能帮我们创建Bean对象,但有的会返回给我们一个Bean工厂或者其他,我们拿到以后可以进行很多操作,不止是创建Bean,比如给了我们一个BeanFactory,我们都拿到了BeanFactory那么是不是很多功能都可以实现,所以可以做很多自己想做的事情
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值