2013-07-24 43 views
0

我有一个接收数据对象的Web服务(让我们称之为Student类)。在Web服务,我使用StudentWrapper对象把它包装成如下在春天管理动态创建对象的事务

new StudentWrapper(student)

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

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

如果还有其他建议可以帮助我解决这个问题,请分享它们。

回答

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'}'} [email protected] 
StudentWrapper{student='Student{name='student 2'}'} [email protected] 

你可以从StudentWrapper的对象引用看到,他们是不同的原型豆类。 @Transactional方法应该在StudentWrapper中按预期工作。

+0

感谢您的帮助艾默生!在阅读你提到的答案和春季文档后,我能够实现我想要的。 –