反对注解的参数

vohkndzv  于 2021-06-30  发布在  Java
关注(0)|答案(8)|浏览(329)

我的团队正在迁移到Spring3.0,有些人希望开始将所有内容都迁移到注解中。当我看到一个类有这样的方法时,我就有一种非常不好的感觉(代码味道?):(只是一个例子-不是所有真正的注解)

@Transaction
@Method("GET")
@PathElement("time")
@PathElement("date")
@Autowired
@Secure("ROLE_ADMIN")
public void manage(@Qualifier('time')int time) {
...
}

我只是落后于时代,还是这对其他人来说都是个可怕的想法?而不是使用像继承和多态性这样的oo概念,现在一切都是通过约定或注解实现的。我只是不喜欢。不得不重新编译所有的代码来改变imo正在配置的东西似乎是错误的。但似乎一切都是这样(尤其是Spring)。我是应该“克服它”,还是应该退一步,尽可能地保持代码的无注解性?

w7t8yxp5

w7t8yxp51#

可能您对代码中的冗余注解有问题。使用元注解可以替换多余的注解,并且您的注解至少是干的。
来自spring博客:

@Service
@Scope("request")
@Transactional(rollbackFor=Exception.class)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyService {
}

@MyService
public class RewardsService {
…
}

由于java的发展如此缓慢,人们正在将更多语言中缺少的特性放入注解中。这是一件好事,java可以以某种形式扩展,这是一件坏事,因为大多数注解都是一些变通方法,增加了复杂性。

ntjbwcob

ntjbwcob2#

事实上,我认为你内心的不好感觉更多地与注解有关,比如将配置与代码混合在一起。
我个人的感觉和你一样,我更喜欢把配置(比如事务定义、路径元素、控制器应该Map到的url等等)放在代码库本身和外部springxml上下文文件之外。
我认为正确的方法取决于你的观点和你喜欢哪种方法-我预测一半的社区会同意注解方法,另一半会同意外部配置方法。

ki1q1bka

ki1q1bka3#

像很多事情一样,有优点也有缺点。在我看来,有些注解是好的,尽管有时感觉有一种过度使用注解的倾向,当一个简单的旧函数调用方法可能是优越的,并且作为一个整体,这可能会无意中增加认知负荷,因为它们增加了“做事情”的方法的数量
让我解释一下。例如,我很高兴您提到@transactional注解。大多数spring开发人员可能会了解并使用@transactional。但是有多少开发人员知道@transactional实际上是如何工作的呢?他们会不会知道如何在不使用@transactional注解的情况下创建和管理事务?在大多数情况下,使用@transactional使我更容易使用事务,但在某些情况下,当我需要对事务进行更细粒度的控制时,它会对我隐藏这些细节。所以在某种程度上它是一把双刃剑。
另一个例子是spring配置类中的@profile。在一般情况下,可以更容易地指定要载入Spring组件的轮廓。但是,如果您需要更强大的逻辑,而不仅仅是指定要为其加载组件的概要文件列表,那么您必须自己获取环境对象并编写一个函数来实现这一点。同样,大多数spring开发人员可能对@profile很熟悉,但这样做的副作用是他们对它如何工作的细节不太熟悉,比如environment.acceptsprofiles(string。。。例如,profiles)函数。
最后,当注解不起作用时,很难理解原因,而且不能在注解上设置断点(例如,如果您忘记了配置中的@enabletransactionmanagement,会发生什么?)您必须找到注解处理器并进行调试。使用函数调用方法,您当然可以在函数中放置断点。

mkh04yzy

mkh04yzy4#

我最初也对注解持怀疑态度,但看到它们被使用,它们可能是一件很棒的事情。它们也可能被过度使用。
注解要记住的主要一点是它们是静态的。它们不能在运行时更改。任何其他配置方法(xml、代码中的自我描述等等)都不会受到这种影响。我在这里看到过一些人对spring有一些问题,比如在注入测试配置时有一个测试环境,并且不得不使用xml来完成测试。
xml既不是多态的,也不是继承的,所以从这个意义上说它不是倒退。
注解的优点是,它可以为您的配置提供更多的静态检查,并且可以避免xml配置中的大量冗长和协调困难(基本上保持干燥)。
就像xml一样,注解也可能被过度使用。主要的一点是平衡各方面的需要和优势。注解在某种程度上减少了代码的冗长和枯燥,是一种可以利用的工具。
编辑:关于注解替换接口或抽象类的评论,我认为这在框架边界是合理的。在一个计划被成百上千个项目使用的框架中,拥有一个接口或基类确实会使事情变得复杂(尤其是基类,尽管如果你可以用注解来完成,那么没有理由不能用常规接口来完成。
以junit4为例。以前,您必须扩展一个具有setup-and-down方法的基类。就我的观点而言,它们是在接口上还是在基类中并不重要。现在我有了一个完全独立的项目,它有自己的继承层次结构,它们都必须遵循这个方法。首先,它们不能有自己冲突的方法名(在测试框架中不是什么大问题,但你明白我的意思)。其次,你有一个调用super的链,因为所有方法都必须耦合。
现在使用junit4,您可以在层次结构中的不同类中拥有不同的@before方法,并且它们可以相互独立。如果没有注解,就没有同样枯燥的方法来实现这一点。
从junit开发人员的Angular 来看,这是一场灾难。最好有一个可以调用setup和teardown的已定义类型。但是框架的存在并不是为了方便框架开发者,而是为了方便框架用户。
如果您的代码不需要关心类型(也就是说,在您的示例中,没有什么真正使用控制器类型),那么所有这些都适用。然后您甚至可以说实现框架的接口比添加注解更容易泄漏。
但是,如果您要编写代码来读取您自己项目中的注解,请远离。

e3bfsja2

e3bfsja25#

注解必须谨慎使用。它们对某些人有好处,但不是对所有人都有好处。至少xml配置方法将配置保存在一个(或多个)文件中,而不是分散在所有地方。这将引入(我喜欢称之为)糟糕的代码组织。如果配置分布在数百个文件中,您将永远看不到它的全貌。

uqdfh47h

uqdfh47h6#

我个人觉得注解已经占据了太多的位置,已经从最初的超级有用的用途(例如,指示重写方法之类的小事情)扩展到了这个疯狂的元编程工具中。我觉得java机制不够健壮,无法处理每个方法前面的注解集群。例如,我最近一直在与junit注解作斗争,因为它们以我不喜欢的方式限制了我
也就是说,根据我的经验,基于xml的配置也不是很好。引用南方公园的话,你要在一个巨大的灌木丛和一个三明治之间做出选择。
我认为您必须做出的主要决定是,您是否更愿意对spring配置进行非定域化(即,维护两个文件而不是一个),以及是否使用从注解中获益的工具或ide插件。另一个重要的问题是,将使用或维护您的代码的开发人员是否真正理解注解。

omjgkv6w

omjgkv6w7#

我认为这在某种程度上取决于你什么时候开始编程。我个人认为他们很可怕。主要是因为他们有一些准“意义”,你不会理解,除非你碰巧意识到注解的问题。因此,它们自己形成了一种新的编程语言,使您远离pojo。与普通的旧oo代码相比。第二个原因-它们可以阻止编译器为您执行工作。如果我有一个很大的代码库,并且想要重构一些东西或者重命名一些东西,我希望编译器能够尽可能地抛出所有需要修改的东西。注解应该就是这样。注解。不是代码行为的核心。它们最初被设计为在编译时可以选择性地省略,这告诉了您需要知道的一切。
是的,我知道xml配置也会受到同样的影响。这并没有让事情变得更糟,只是同样糟糕。不过,至少我可以假装忽略这一点——它不会在每个方法或参数声明中都盯着我看。
考虑到这个选择,我实际上更喜欢可怕的旧j2ee远程/家庭接口等(最初受到spring的批评),因为这至少让我在不必研究@coolaidframeworkthingy及其缺点的情况下了解了正在发生的事情。框架人员的一个问题是,他们需要将您与他们的框架联系起来,以便使整个企业在财务上可行。这与设计框架不一致

yyyllmsg

yyyllmsg8#

请核对这些问题的答案
与xml配置文件相比,注解(非编译器)的优缺点是什么
xml配置与基于注解的配置
基本上可以归结为:两者兼用。它们都有用例。不要对那些不需要重新编译就可以配置的东西使用注解(特别是那些用户不需要重新编译就可以配置的东西)

相关问题