我有一个接收数据对象的Web服务(让我们称之为Student类)。在Web服务中,我使用StudentWrapper对象将其包装如下
new StudentWrapper(student)
我希望StudentWrapper
类具有save
等可以将数据保存到数据库的方法。我想使用spring框架来注释save
方法,以便它在事务中运行。但是,StudendWrapper对象必须是一个spring bean(用XML定义)。如果它是一个spring bean,那么我将不会像上面所示那样实例化它。
我的问题是如何让StudentWrapper成为一个Spring bean(以便我可以使用Spring注释来管理事务),但是将Student对象(我通过Web服务接收)传递给StudentWrapper?
如果有任何其他建议可以帮助我解决此问题,请分享它们。
答案 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
。