在spring中管理动态创建的对象的事务

时间:2013-07-24 16:20:58

标签: spring oop

我有一个接收数据对象的Web服务(让我们称之为Student类)。在Web服务中,我使用StudentWrapper对象将其包装如下

new StudentWrapper(student)

我希望StudentWrapper类具有save等可以将数据保存到数据库的方法。我想使用spring框架来注释save方法,以便它在事务中运行。但是,StudendWrapper对象必须是一个spring bean(用XML定义)。如果它是一个spring bean,那么我将不会像上面所示那样实例化它。

我的问题是如何让StudentWrapper成为一个Spring bean(以便我可以使用Spring注释来管理事务),但是将Student对象(我通过Web服务接收)传递给StudentWrapper?

如果有任何其他建议可以帮助我解决此问题,请分享它们。

1 个答案:

答案 0 :(得分:1)

如果您真的想使用构造函数创建对象,请创建StudentWrapper @Configurable并阅读有关使用AspectJ为域对象创建原型bean定义的信息(参考手册的第9.8节)。

更简单的替代方法,如果您不想使用AspectJ但不希望直接依赖Spring,则将原型bean创建封装在工厂中。我将向您展示使用JavaConfig,尽管您可以在XML中执行类似的操作。

首先是学生对象......

package internal;

public class Student {

    private String name;

    public Student(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    @Override
    public String toString() {
        return "Student{name='" + name + "'}";
    }
}

现在是包装器对象......

package internal;

public class StudentWrapper {

    private Student student;

    public StudentWrapper(Student student) {
        this.student = student;
    }

    public Student getStudent() {
        return student;
    }

    @Override
    public String toString() {
        return "StudentWrapper{student='" + student + "'} " + super.toString();
    }
}

现在是工厂,

package internal;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;

@Component
public class StudentWrapperFactory {

    @Autowired
    private ApplicationContext applicationContext;

    public StudentWrapper newStudentWrapper(Student student) {

        return (StudentWrapper) this.applicationContext.getBean("studentWrapper", student);
    }
}

现在是JavaConfig,相当于XML配置

package internal;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;

@Configuration
@ComponentScan(basePackages = "internal")
public class FooConfig {

    @Bean
    @Scope("prototype")
    public StudentWrapper studentWrapper(Student student) {
        return new StudentWrapper(student);
    }
}

最后是单元测试...

package internal;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {FooConfig.class})
public class FooIntegrationTest {

    @Autowired
    private StudentWrapperFactory studentWrapperFactory;

    @Test
    public void foo() {

        Student student1 = new Student("student 1");
        Student student2 = new Student("student 2");

        StudentWrapper bean1 = this.studentWrapperFactory.newStudentWrapper(student1);
        StudentWrapper bean2 = this.studentWrapperFactory.newStudentWrapper(student2);

        System.out.println(bean1);
        System.out.println(bean2);

    }
}

产生

StudentWrapper{student='Student{name='student 1'}'} internal.StudentWrapper@1b0fa7ff
StudentWrapper{student='Student{name='student 2'}'} internal.StudentWrapper@20de643a

从StudentWrapper的对象引用中可以看出,它们是不同的原型bean。 @Transactional方法应该按预期在StudentWrapper

中运行