依赖服务应该在哪里@Autowired(控制器或服务)?

时间:2013-03-10 09:21:28

标签: spring service architecture autowired

请考虑以下两个选项:

选项#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(我在这里省略了)。但是读取数据呢。

1 个答案:

答案 0 :(得分:4)

第二种选择更清洁,更快速,更安全。它基本上使用了外观模式。

清理,因为它将代码业务代码移动到UI层之外,在服务层中,它所属的位置。

更快,因为,因为所有内容都在同一个事务中完成,所以您将保存事务开放和关闭,并从事务缓存中受益(假设您使用ORM来获取所需的数据)。如果UI和服务层位于独立的JVM上,它当然会更快。

更安全因为,由于所有内容都在同一个事务中,因此每个服务都将从同一个一致的数据库“快照”中获取数据。在第一个选项中,您可以让第一个方法返回一个foo,当调用第二个服务时,该foo不再存在。当然,这取决于数据库的事务隔离级别,但它总是比在多个事务中执行它更安全。