当前位置: 首页 > 工具软件 > Hack-Night > 使用案例 >

注释嵌套注释_注释梦Night

燕星鹏
2023-12-01

注释嵌套注释



@XmlElementWrapper(name="orders")
@XmlJavaTypeAdapter(OrderJaxbAdapter.class)
@XmlElements({
   @XmlElement(name="order_2",type=Order2.class),
   @XmlElement(name="old_order",type=OldOrder.class)
})
@JsonIgnore
@JsonProperty
@NotNull
@ManyToMany
@Fetch(FetchMode.SUBSELECT)
@JoinTable(
    name = "customer_order",
    joinColumns = {
        @JoinColumn(name = "customer_id", referencedColumnName = "id")
    },
    inverseJoinColumns = {
        @JoinColumn(name = "order_id", referencedColumnName = "id")
    }
)
private List orders;

等待。 什么? 这真的是我们所要达成的目标吗? 我什至看不到这个膨胀下的该死的财产。 这怎么发生的? 是的-我们不得不以某种方式摆脱旧的xml配置恐怖。 但是这个? 这甚至更糟。 此类应该是一堆具有许多特性的真棒pojo。 简洁明了,易于阅读。 作为本案例的读者,我对数据库表如何将客户加入订单完全不感兴趣。 我对它的序列化都不感兴趣。 这只是实现细节。 阅读此课程,我生活在对象世界中,我想知道对象具有哪些数据和行为。 不多不少。 我暂时不在乎列名,fetchtypes或json序列化。 而且我不想为了更改表名而读取,更改或重新编译此类。 我也不想添加另一个用于将该实体存储在mongoDB中的注释。 实体不应对这些细节负责。 我们不仅在这里违反了单一责任原则,还在做责任方。

好吧好吧,足够的愤怒。 我们如何处理这个问题? 一些实体将实体复制到具有不同注释目的的各个层。 他们使用自动映射器(如Dozer)将实体映射到与下一层相关的实体。 有些人甚至自己写了那个映射。 但这绝不是解决方案。 它只是将一种代码气味替换为另一种:重复。

因此,请专注于不会强迫您使代码混乱的框架。 jOOQ是将数据库记录映射到没有注释的实体的不错的解决方案。 另外,hibernate允许您以XML定义映射。

专用场注入

@Inject
private MyService myService

这是很经常使用的,尽管它甚至是不可能的。 myService字段是私有的,因此无法从类外部访问。 然而,这是有可能的,人们会这样做。 实际上,这是一个hack。 DI框架使用setAccessible(true)进行反射来设置字段。 您不想在您的代码中被黑客入侵,对吗? 让我们来看看替代方案:

二传手注射

好吧,至少它比私有域注入更好,因为它使用公共方法而不是侵入私有域。 但是,仍然要问自己:“这个阶级是否应该在没有注入价值的情况下生活?” 因为如果不是这样,就没有理由在没有MyService实例的情况下构造该类。 您想在类级别和构造函数内部而不是在框架级别实现此约束。

构造函数注入

这通常是要走的路。 它可以让你

  • 使字段不变(通常无需更改)。
  • 实现约束,即在正确的位置没有给定的MyService ,该类不可实例化。

当然,这意味着您不能通过注解进行注入。 但是为什么要呢? 该类不需要知道,它是否通过DI容器或工厂类进行注入。 它应该对此一无所知。 没有@Autowired,没有@Qualifier。 它只需要知道自己的行为即可。 其他所有内容都应在课堂之外处理。

可以使用配置类或文件进行实际注入。

DI容器是有用的工具,可帮助您将类连接在一起。 为此,请使用它,但不要让它支配您的代码。 Bob叔叔写了一篇很棒的文章 ,他在其中解释了如何使用DI-Frameworks而不要求他们指定您的代码。

UnitTests中的@RunWith(SpringJUnit4ClassRunner.class)

为什么在单元测试中需要此功能? 因为它是由您的IDE /应用程序模板自动生成的? 没有! 您想测试一个类的行为,它孤立地存在于单元测试中。 如果DI-Conainer正在相应地注入字段,则不会。 只需将自己注入设置方法即可。 无需DI容器。 顺便说一下,这个testrunner所做的只是这三行代码。

private TestContextManager testContextManager;
//..
this.testContextManager = new TestContextManager(getClass());
this.testContextManager.prepareTestInstance(this);

它们不值得阻塞您唯一的TestRunner插槽。 您想免费使用它进行参数化@RunWith(JUnitParamsRunner.class)或并发@RunWith(ConcurrentJunitRunner.class)测试。

@Override

确实,我的IDE已经知道我是否正确覆盖了方法。 对我来说,这只是混乱。

@SuppressWarnings

…甚至不让我开始

tl; dr

这些天来,注释变得比有害有用。 我们应该回到pojos上,并专注于保持我们的代码尽可能整洁和与框架无关,以使其更具可读性和可重用性。 不要让框架支配您的代码库,因为它们应该是可交换的工具。 当心一个班级应该知道什么,什么不知道。 一些注释有用,而大多数却没有。

@DevNull({

 @SuppressWarnings

 @Autowired, 
 @Inject, 

 @Override,  

 @XmlElementWrapper,
 @XmlJavaTypeAdapter,
 @XmlElement,
 @JsonIgnore,
 @JsonProperty,
 @ManyToMany,
 @Fetch,
 @JoinTable
})

参考:成为更好的开发者”博客上来自我们JCG合作伙伴 Gregor Riegler 的注释梦 m。

翻译自: https://www.javacodegeeks.com/2014/01/an-annotation-nightmare.html

注释嵌套注释

 类似资料: