平时开发我们可以使用 Autowired,Resource 注入 spring 容器。
如何使用编程的方式将一个 bean 注入spring 容器 ?
1.set 方法注入
2.构造方法注入
3.指定构造方法参数顺序注入
4.通过 BeanDefinitionBuilder 注入
1.定义一个基础配置类
public class DataSourceConfig {private String dataSourceName;private String url;private String password;public String getDataSourceName() {return dataSourceName;}public void setDataSourceName(String dataSourceName) {this.dataSourceName = dataSourceName;}public String getUrl() {return url;}public void setUrl(String url) {this.url = url;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}}
2.注入spring容器
@SpringBootTest@RunWith(SpringRunner.class)public class DatasourceTest {@Autowiredprivate ApplicationContext applicationContext;@Testpublic void testInject() {BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(DataSourceConfig.class);beanDefinitionBuilder.addPropertyValue("dataSourceName", "busi");beanDefinitionBuilder.addPropertyValue("url", "xxx");beanDefinitionBuilder.addPropertyValue("password", "123456");DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) applicationContext.getAutowireCapableBeanFactory();beanFactory.registerBeanDefinition("busiDatasourceConfig", beanDefinitionBuilder.getBeanDefinition());Assert.assertNotNull(applicationContext.getBean(DataSourceConfig.class));Assert.assertEquals(applicationContext.getBean(DataSourceConfig.class).getDataSourceName(), "busi");Assert.assertEquals(applicationContext.getBean(DataSourceConfig.class).getPassword(), "123456");Assert.assertEquals(applicationContext.getBean(DataSourceConfig.class).getUrl(), "xxx");}}
5.ObjectProvider
实现宽松的依赖注入,当 spring 容器没有该 Bean 时也不会报错。
什么时候使用ObjectProvider接口?
如果待注入参数的Bean为空或有多个时,便是ObjectProvider发挥作用的时候了。
如果注入实例为空时,使用ObjectProvider则避免了强依赖导致的依赖对象不存在异常;如果有多个实例,ObjectProvider的方法会根据Bean实现的Ordered接口或@Order注解指定的先后顺序获取一个Bean。从而了提供了一个更加宽松的依赖注入方式。
/*** A variant of {@link ObjectFactory} designed specifically for injection points,* allowing for programmatic optionality and lenient not-unique handling.** @author Juergen Hoeller* @since 4.3*/public interface ObjectProvider<T> extends ObjectFactory<T> {/*** Return an instance (possibly shared or independent) of the object* managed by this factory.* <p>Allows for specifying explicit construction arguments, along the* lines of {@link BeanFactory#getBean(String, Object...)}.* @param args arguments to use when creating a corresponding instance* @return an instance of the bean* @throws BeansException in case of creation errors* @see #getObject()*/T getObject(Object... args) throws BeansException;}
