请考虑以下两个选项:
选项#1:在控制器中自动装配所需的服务
@Controller
@RequestMapping(value="/foo")
public class FooController {
@Autowired
private FooService fooService;
@Autowired
private BarService barService;
@Autowired
private BazService bazService;
@RequestMapping(method=RequestMethod.GET)
public String getFoo(...) {
Foo foo = fooService.getFooInstance(...);
List<Foo> foos = fooService.getFooList(foo);
List<Bar> bars = barService.getBarList(foo);
Baz baz = bazService.getBaz(foo);
...
return "view/foo/index.jsp";
}
}
选项#2:特定服务中的UoW自动连接相关服务
@Controller
@RequestMapping(value="/foo")
public class FooController {
@Autowired
private FooService fooService;
@RequestMapping(method=RequestMethod.GET)
public String getFoo(...) {
Foo foo = fooService.getFooInstance(...);
FooDTO fooInfo = fooService.getFooAllInformation(foo);
List<Foo> foos = fooInfo.getFoos();
List<Bar> bars = fooInfo.getBars();
Baz baz = fooInfo.getBaz();
...
return "view/foo/index.jsp";
}
}
@Service
public class FooServiceImpl implements FooService {
@Autowired
private FooRepository fooRepository;
@Autowired
private BarService barService;
@Autowired
private BazService bazService;
...
@Override
@Transactional
public FooDTO getFooAllInformation(Foo foo) {
List<Foo> foos = getFooList(foo);
List<Bar> bars = barService.getBarList(foo);
Baz baz = bazService.getBaz(foo);
...
}
}
好吧,目前我正在使用选项#1,一切正常。但我想知道这种方法是否足够好。它们中的任何一个都比另一个有任何明显的优势吗?我应该提一下,我知道服务的@Transactional
部分INSERT
(我在这里省略了)。但是读取数据呢。
答案 0 :(得分:4)
第二种选择更清洁,更快速,更安全。它基本上使用了外观模式。
清理,因为它将代码业务代码移动到UI层之外,在服务层中,它所属的位置。
更快,因为,因为所有内容都在同一个事务中完成,所以您将保存事务开放和关闭,并从事务缓存中受益(假设您使用ORM来获取所需的数据)。如果UI和服务层位于独立的JVM上,它当然会更快。
更安全因为,由于所有内容都在同一个事务中,因此每个服务都将从同一个一致的数据库“快照”中获取数据。在第一个选项中,您可以让第一个方法返回一个foo,当调用第二个服务时,该foo不再存在。当然,这取决于数据库的事务隔离级别,但它总是比在多个事务中执行它更安全。