【问题标题】:Spring set a property using a runtime object?Spring使用运行时对象设置属性?
【发布时间】:2011-09-08 11:25:52
【问题描述】:

我很难弄清楚如何借助 spring 注释来设置属性。

我有一个抽象基类。

abstract class AbstractTest{
 private static Session session;

 @BeforeClass
 public static void initApplication() throws Exception {
  session = new Session();
  ...
 }

 public Session getSession(){

我有一个扩展我的 AbstractTest 的测试类。

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
public class RealTest extends AbstractTest{

 @Autowired
 Service service;

我有一个需要使用会话对象的服务,我希望它“自动设置”到会话对象。

public class ServiceImpl implements Service {

// @AutoSomething how to make this work?
private Session session;

由于@ContextConfiguration 注解,自动用于我的 RealTest 的 spring 文件

<bean id="Service" class="...ServiceImpl" >
 <property name="session">
  getSession()?? // What's the syntax or how to do this?
 </property>

【问题讨论】:

    标签: java spring dependency-injection annotations instantiation


    【解决方案1】:
    1. 了解bean scopes。它并没有真正有意义的那种注射你正在尝试做的。您不应将会话本身注入业务服务类。您应该改用 session 范围的 bean。

    2. 测试类本身不是测试 ApplicationContext 的一部分,因此您不能将测试类中创建的值自动连接到测试类。无论如何,你为什么要这样做?您已经在测试类中中拥有它,那么为什么不在@Before public void setUp() {} 方法中使用简单的setter 呢?或者看下一点。

    3. 如果您的类在测试类中创建了依赖项,那么@ContextConfiguration 在这里将无济于事。您可以通过在测试类内部创建一个内部@Configuration 类并使用Spring Java Config 配置服务类来使用AnnotationConfigApplicationContext

    即:

    @ContextConfiguration
    public class RealTest extends AbstractTest {
    
        @Autowired
        private ApplicationContext appCtx;
    
        private Service service;
    
        @Before
        public void setUp() {
            AnnotationConfigApplicationContext testCtx = new AnnotationConfigApplicationContext();
            testCtx.setParent(this.appCtx);
            testCtx.register(RealTestCfg.class);
            testCtx.refresh();
    
            this.service = BeanFactoryUtils.beanOfType(testCtx, Service.class);
        }
    
        @Configuration
        public static class RealTestCfg {
    
            @Bean
            public Session session() {
                return AbstractTest.session;
            }
    
            @Bean
            public Service service() {
                return new Service();
            }
        }
    }
    

    如果您没有任何其他依赖项,@ContextConfiguration 和父 ApplicationContext 是可选的。而AbstractTest.session 需要是protected static,或者有protected static 访问器。

    【讨论】:

    • 1.我有一个用于在测试框架中进行测试的会话并希望注入到我的业务服务中,这确实是有道理的。 2.我认为你误解了我想转移会话而不是从 Test->Test 而是从 Test->Session 的问题,我当然可以在服务中声明一个 setter 并从我的 Test 调用 setSession() 但我想Spring 来处理我的依赖关系。
    • 据我了解,您想将SessionTest 转移到Service,这是Test 依赖项之一,对吧?
    • 这不能使用@ContextConfiguration 完成。时期。因为测试类不是以这种方式创建的ApplicationContext 的一部分。我将扩展我的答案以澄清这一点,以及我在 3 中给出的替代解决方案。
    • 我扩展了答案。你明白我现在的意思了吗?
    • 我已经快速浏览了一下,虽然它可能是正确的,但我正在寻找更好的方法。我不想从我的测试类中以编程方式摆弄上下文,我当然也不想创建一个新类 RealTestCfg。所有这一切使我的代码比我想要避免的简单设置器更糟糕。要么我找到一个很好的注释,XML sn-p 或者没有太多锅炉代码的东西,否则我会用一个 setter 解决。
    猜你喜欢
    • 2015-03-11
    • 1970-01-01
    • 1970-01-01
    • 2020-07-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-11
    相关资源
    最近更新 更多