如何以编程方式创建 Spring 上下文?
有谁知道我是否可以通过编程方式创建 bean 上下文?
Does anyone know if there any way that I can programmatically create a bean context?
我希望能够执行以下操作:
I want to be able to do something like:
ConfigurableApplicationContext c = new ConfigurableApplicationContext();
BeanDefinition bd = new BeanDefinition();
bd.setId("id");
bd.setClassName("classname");
bd.setProperty("propertyName", propertyValue");
...etc...
或者更好的是能够将现成的 bean 注入应用程序上下文:
or better still be able to inject a ready made bean into the application context:
c.addBean("beanId", beanObject);
或者如果我使用注释:
c.setAnnotationAware(true);
c.setAnnotationScanBasePackage("packagename");
或
c.addAnnotatedSpringClass("classnamethatisannotated");
这样做的基本原理是为了测试目的,我希望能够覆盖 bean 定义 - 在我的测试中,我创建了这个新的应用程序上下文,在测试中配置了代码(而不是在 xml 中),然后制作这个测试应用程序context 将 SUT 应用程序上下文作为父级.
The rationale for this is that I want to be able override bean definitions for the purpose of testing - In my test I create this new application context, configured with code in the test (not in xml) and then make this test application context have as a parent the SUT application context.
我在 spring 库中没有找到任何可以做到这一点的代码.有没有人建造过这样的东西?有可能建造这样的东西吗?我知道前一种方法是可行的,但我不能 100% 确定后一种方法会在没有条件的情况下工作.
I haven't found any code in the spring libraries that can do this. Has anyone built something like this? Would it be possible to build something like this? I know the former approach is doable, I'm not 100% sure the latter approaches will work without conditions.
尝试:
@Configuration
public class AppConfig {
@Bean
public TransferService transferService() {
return new TransferServiceImpl();
}
}
BeanBuilder 代码示例
def bb = new grails.spring.BeanBuilder()
bb.beans {
dataSource(BasicDataSource) {
driverClassName = "org.hsqldb.jdbcDriver"
url = "jdbc:hsqldb:mem:grailsDB"
username = "sa"
password = ""
}
sessionFactory(ConfigurableLocalSessionFactoryBean) {
dataSource = dataSource
hibernateProperties = [ "hibernate.hbm2ddl.auto":"create-drop", "hibernate.show_sql":true ]
}
}
AtUnit 代码示例
单元测试
@RunWith(AtUnit.class)
@Container(Container.Option.SPRING)
@MockFramework(MockFramework.Option.EASYMOCK)
public class ExampleSpringEasyMockTest {
@Bean @Unit UserManagerImpl manager;
@Bean("fred") User fred;
@Bean("userDao") @Mock UserDao dao;
@Bean("log") @Stub Logger log;
@Test
public void testGetUser() {
expect(dao.load(1)).andReturn(fred);
replay(dao);
assertSame(fred, manager.getUser(1));
verify(dao);
}
}
上下文文件(测试专用)
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
<bean id="userManager" class="atunit.example.subjects.UserManagerImpl">
<constructor-arg ref="log"/>
<property name="userDao" ref="userDao"/>
</bean>
<bean id="fred" class="atunit.example.subjects.User">
<property name="id" value="500"/>
<property name="username" value="fred"/>
</bean>
</beans>