手动向Spring容器中注入对象的方法有很多,本文将简单阐述其中的四种
1. beanFactory的registerSingleton方法
我们可以实现一个BeanFactory的后置处理器,在其中就可以获得BeanFactory,这样就可以调用registerSingleton方法。
注:此处bean的名字可以自定义,如这里就定义为sherlock。
@Component
public class SherlockBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
beanFactory.registerSingleton("sherlock", new User("sherlock", 18));
}
}
如果在容器中获取该类
@Test
public void test() {
ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
User sherlock = context.getBean("sherlock", User.class);
System.out.println(sherlock.toString());
}
控制台输出:
对象就已成功注入到Spring容器中了。
注:其实在context中也有registerBean方法,可以实现一样的效果。(ApplicationContext其实继承了BeanFactory,所以它也拥有Bean工厂的功能,除此之外ApplicationContext还继承了很多其他的类,拥有一些辅助功能。总的来说,ApplicationContext其实包括了BeanFactory)
2. @Bean注解
在配置类中,使用@Bean注解,返回一个想要注入的对象。@Bean括号中是bean的名字,默认为类名的小写形式。
@Configuration
@ComponentScan("com.sherlock")
public class AppConfig {
@Bean("sherlock")
public User user() {
return new User("sherlock", 19);
}
}
控制台输出:
3. 使用Factory‘Bean
既然提到了Factory‘Bean,就不得不提到BeanFactory。关于这两个的区别,可以看下我的另一篇文章。https://www.jianshu.com/p/91d21128d2a9
我们可以创建一个类去实现FactoryBean接口
@Component
public class SherlockFactoryBean implements FactoryBean {
@Override
public Object getObject() throws Exception {
return new User("sherlock", 20);
}
@Override
public Class<?> getObjectType() {
return User.class;
}
}
//注意:这个bean的名字是sherlockFactoryBean,但返回的是User类
User user = context.getBean("sherlockFactoryBean", User.class);
控制台输出:
4. 使用@Import注解
@Import只能用在类上 ,@Import通过快速导入的方式实现把实例加入spring的IOC容器中
@Import的三种用法主要包括:
- 直接填class数组
@Import({User.class, Order.class})
User user = context.getBean("com.sherlock.pojo.User", User.class);
注意:这样注入的类名为类的全限定名。
- ImportSelector方式
使用这种方式的这个类必须实现ImportSelector接口
public class SherlockImportSelector implements ImportSelector {
@Override
public String[] selectImports(AnnotationMetadata annotationMetadata) {
//前面可以是和业务相关的逻辑
//返回需要导入的组件的全类名数组
return new String[]{"com.sherlock.pojo.User"};
}
}
- ImportBeanDefintionRegister方式手动注册bean
public class SherlockImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
//需要的业务逻辑
//指定bean定义信息(包括bean的类型、作用域...)
RootBeanDefinition beanDefinition = new RootBeanDefinition();
beanDefinition.setBeanClass(User.class);
registry.registerBeanDefinition("user",beanDefinition);
}
}
@Import三种方式的总结
第一种用法:@Import({ 要导入的容器中的组件 } ):容器会自动注册这个组件,id默认是全类名
第二种用法:ImportSelector:返回需要导入的组件的全类名数组,springboot底层用的特别多。
第三种用法:ImportBeanDefinitionRegistrar:手动注册bean到容器
好了,以上就是四种手动向Spring容器中注入对象的方法。总结一下吧,分别是:
- beanFactory的registerSingleton方法
- @Bean注解
- FactoryBean
- @Import