adobe.

使用Sling Models&Lombok在AEM中编写更少的Java代码

AEM是一个充满有用的API和框架的强大平台。了解框中的内容将有助于我们编写更少的代码。在我的以前的博客文章,我涵盖了最常用的框架之一,吊索模型。此外,我展示了一个具有多场的真实榜样。对于此博客文章,我们将继续利用代码生成器中添加帮助的吊带模型。

代码生成器

代码生成器保存我们不得不编写单调的Java管道代码。像豆子这样的东西Getter和Setter,记录器,等于()ToString()hashcode().我们需要自由自己来编写和维护这种管道。这样做,我们可以专注于高级业务逻辑。

一些更好的发电机是不可变的autovalue.龙目岛.我不会进入每个人的细节。我的个人偏好几年后,我的个人偏好是龙目的。与其他两个一样,它可以生成值对象。但它比这更重要。

javac., Java编译器,执行代码生成器。像Java中的所有东西一样,也有一个JSR。在这种情况下JSR 269:可插拔注释处理API.由于我们使用Maven,我们需要做的就是添加maven依赖

<依赖>  org.projectLombok  龙目像  1.18.20  提供 

仿佛通过魔法,您的所有LOMBOK注释类都将获得生成的代码。好吧......不是魔法。javac会发现和加载Meta-Inf / Services / Javax.Annotation.Processing.Processor.此文件驻留在Lombok.jar.并指向适当的注释处理器。您可以阅读更详细的解释这里.它是如此无缝,以至于当我第一次使用Lombok构建一个项目时,我甚至都没有意识到它的存在。直到我遇到一个带注释的类。这是在编译器方面。在IDE方面,最新版本的IntelliJ已经发布了兼容的与龙目岛。Eclipse需要一些设置。

一个真实的例子

在某些时候,每个AEM开发人员都必须为此添加课程标签。听起来很简单吗?我们将添加一个约束:正确扩展WCM核心页面模板组件.Kneejerk反应将是覆盖Page.html.文件在哪里标签是。我确实说“适当地延伸”吗?该文件有很多东西可以支持Adobe的平台和功能。如果我们覆盖,那么我们将负责将其保持升级之间的升级。

类来自页面模型com.adobe.cq.wcm.core.components.models.page.page..扩展核心模型的正确方法是通过roomaticsupertype., 一个通过提供商类型这里是一个更详细的例子是如何扩展核心组件。

让我们开火一个新的原型项目:

mvn -b原型:生成\ -d archetypegroupid = com.adobe.aem \ -d archetypeartifactid = aem-project-archetype \ -d archetypeversion = 26 \ -d apptitle =“我的网站”\ -d appid =“mysite”\-d groupid =“com.mysite”\ -d aemversion = 6.5.5

我们将创建的第一堂课是com.mysite.core.models.mypageModel.

@Model(adaptables = {SlingHttpServletRequest.class},适配器= {page .class, containerexport .class}, resourceType = "mysite/components/page")SLING_MODEL_EXPORTER_NAME, extensions = ExporterConstants.SLING_MODEL_EXTENSION)公共最终类MyPageModel实现Page, containerexport{私有静态最终Logger log = LoggerFactory.getLogger(MyPageModel.class);@Self @Via(type = ResourceSuperType.class) private页面委托;@Override public String getCssClassNames() {log.info(“这是唯一的相关更改”);返回字符串。join(" ", "foo", "bar", this.delegate.getCssClassNames());} /**下面的每一个都是管道。*/ @Override public String getLanguage() {return this.delegate.getLanguage();} @Override public Calendar getLastModifiedDate() {return this.delegate.getLastModifiedDate();} @Override public String[] getKeywords() {return this.delegate.getKeywords(); } @Override public String getDesignPath() { return this.delegate.getDesignPath(); } @Override public String getStaticDesignPath() { return this.delegate.getStaticDesignPath(); } @Override public String getTitle() { return this.delegate.getTitle(); } @Override public String[] getClientLibCategories() { return this.delegate.getClientLibCategories(); } @Override public String[] getClientLibCategoriesJsBody() { return this.delegate.getClientLibCategoriesJsBody(); } @Override public String[] getClientLibCategoriesJsHead() { return this.delegate.getClientLibCategoriesJsHead(); } @Override public String getTemplateName() { return this.delegate.getTemplateName(); } @Override public String getAppResourcesPath() { return this.delegate.getAppResourcesPath(); } @Override public NavigationItem getRedirectTarget() { return this.delegate.getRedirectTarget(); } @Override public boolean hasCloudconfigSupport() { return this.delegate.hasCloudconfigSupport(); } @Override public Set getComponentsResourceTypes() { return this.delegate.getComponentsResourceTypes(); } @Override public String[] getExportedItemsOrder() { return this.delegate.getExportedItemsOrder(); } @Override public Map getExportedItems() { return this.delegate.getExportedItems(); } @Override public String getExportedType() { return this.delegate.getExportedType(); } @Override public String getMainContentSelector() { return this.delegate.getMainContentSelector(); } @Override public List getHtmlPageItems() { return this.delegate.getHtmlPageItems(); } @Override public String getId() { return this.delegate.getId(); } @Override public ComponentData getData() { return this.delegate.getData(); } }
然后我们导航到 en.html. 我们看到了现在存在课程。 最重要的是,我们没有像页面一样破坏任何开箱功能 JSON模型
这个代表团模式有几个缺点。首先,我们必须编写单调的管道代码来委派核心模型。如果代码覆盖率是规则,我们负责21行!其次,它是出错的。这 com.adobe.cq.wcm.core.components.models.page.page. 接口使用 默认方法 .您可以从实现类中省略其中任何一个。如果你省略getData()然后你打破了 数据层集成

摆脱样板代码

/**静态日志自动生成。*/ @Slf4j @Model(adaptables = {SlingHttpServletRequest.class},适配器= {page .class, ContainerExporter.class}, resourceType = "mysite/组件/页面")@ exports (name = ExporterConstants. class .class .class .class .class) @ exports (name = ExporterConstants. class .class .class .class)SLING_MODEL_EXPORTER_NAME, extensions = ExporterConstants.SLING_MODEL_EXTENSION)公共最终类MyPageModel实现Page, containerexports {/** getter自动生成。*/ @Getter私有字符串cssClassNames;/**委托核心页面模型与排除。*/ @Delegate(exclude = MyDelegateExclusions.class) @Self @Via(type = ResourceSuperType.class) private Page delegate;@PostConstruct public void activate();跟踪(“组件激活”);这一点。cssClassNames =字符串。join(" ", "lombok", "foo", "bar", this.delegate.getCssClassNames());} /**签名被排除在授权之外。 */ private interface MyDelegateExclusions { /** we don't want this to get delegated. */ String getCssClassNames(); } }

和代码(或缺乏)几乎是为了自己说话。我们通过添加来摆脱无处不在的记录器@ SLF4J.在课堂上。然而我们的私人静态日志仍然可用。我们注释了csscscassnames.@getter.从而实施page.getcssclassnames()当然,我们摆脱了所有的委托方法通过注释代表领域@代表

我们学到了什么

对于初学者来说,我希望您了解到延长核心组件和模型的正确方法。其次,我们了解到,吊索模型和代码生成器不互斥。代码生成器可以与吊索模型配合使用。您还可以在您的应用程序中沿OSGI服务和任何Java类中使用它们。看看龙目岛的稳定的特点然后然后是实验那些。

关于作者

Juan Ayala是一家在Adobe Implication,Inc。的领先开发人员,专注于Adobe经验平台和围绕它的东西。

更多来自这个作者

留下一个回复

本网站使用AkisMet减少垃圾邮件。了解如何处理评论数据

订阅每周博客摘要:

报名