平时开发我们可以使用 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 {
@Autowired
private ApplicationContext applicationContext;
@Test
public 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;
}