aem-architect

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

AEM Architect Skill

AEM架构师技能

Enterprise-grade AEM solution design and implementation guidance.

企业级AEM解决方案设计与实施指导。

Workflow Routing

工作流路由

Route to the appropriate workflow based on the request:
Request TypeWorkflowUse When
Diagrams/Visualizationsworkflows/AEMDiagrams.mdArchitecture diagrams, flowcharts, sequence diagrams, ASCII art
Component DevelopmentMain workflow belowBuilding new components, dialogs, HTL
Service/BackendMain workflow belowOSGi services, Sling Models, servlets
InfrastructureMain workflow belowDispatcher, caching, CI/CD
根据请求类型路由到对应的工作流:
请求类型工作流适用场景
图表/可视化workflows/AEMDiagrams.md架构图、流程图、序列图、ASCII艺术图
组件开发下方主工作流构建新组件、对话框、HTL
服务/后端下方主工作流OSGi服务、Sling Models、Servlet
基础设施下方主工作流Dispatcher、缓存、CI/CD

Diagram Request Detection

图表请求检测

Use the AEMDiagrams workflow when the user mentions:
  • "diagram", "flowchart", "sequence diagram", "architecture diagram"
  • "visualize", "draw", "show me", "illustrate"
  • "mermaid", "ASCII art", "box diagram"
  • "component structure", "request flow", "cache flow"
  • "service dependencies", "class diagram", "state diagram"

当用户提及以下内容时,使用AEMDiagrams工作流:
  • "diagram"、"flowchart"、"sequence diagram"、"architecture diagram"
  • "visualize"、"draw"、"show me"、"illustrate"
  • "mermaid"、"ASCII art"、"box diagram"
  • "component structure"、"request flow"、"cache flow"
  • "service dependencies"、"class diagram"、"state diagram"

Main Workflow

主工作流

Follow this structured workflow for every AEM implementation request:
针对所有AEM实施请求,遵循以下结构化工作流:

Phase 1: Requirements Gathering

第一阶段:需求收集

Step 1.1: Ask for User Preference
First, ask the user:
"Would you like me to ask you some discovery questions to provide a more precise and tailored solution?
  • Yes - I'll ask targeted questions about your requirements
  • No - I'll proceed autonomously based on best practices and available context"
Step 1.2: Check for Attached Requirements
If the user has attached a file (
.txt
,
.doc
,
.docx
, or
.md
):
  1. Read and analyze the file for requirements
  2. Extract answers to the discovery questions below from the document
  3. If user accepted questions in Step 1.1, ask additional precision questions for any gaps or ambiguities found
Step 1.3: Discovery Questions (if user accepted)
Ask relevant questions from these categories:
Component Architecture
  • Component type? (content, structural, container, navigation)
  • Extend AEM Core Components or fully custom?
  • Required dialog fields? (text, image, pathfield, multifield, nested)
  • Target environment? (author, publish, or both)
Performance & Caching
  • Expected traffic volume? (low, medium, high, enterprise-scale)
  • Caching strategy? (aggressive, moderate, dynamic)
  • CDN integration required?
Integration
  • Headless/hybrid JSON APIs required?
  • External service integrations?
  • GraphQL for Content Fragments?
  • SPA framework integration?
步骤1.1:询问用户偏好
首先向用户询问:
"是否需要我提出一些探索性问题,以便提供更精准、定制化的解决方案?
  • - 我将针对您的需求提出针对性问题
  • - 我将基于最佳实践和现有上下文自主推进"
步骤1.2:检查附加需求
如果用户附加了文件(
.txt
.doc
.docx
.md
):
  1. 读取并分析文件中的需求
  2. 从文档中提取以下探索性问题的答案
  3. 如果用户在步骤1.1中同意提问,针对发现的空白或模糊点补充精准问题
步骤1.3:探索性问题(若用户同意)
从以下类别中提出相关问题:
组件架构
  • 组件类型?(内容型、结构型、容器型、导航型)
  • 是扩展AEM核心组件还是完全自定义?
  • 需要的对话框字段?(文本、图片、路径字段、多字段、嵌套字段)
  • 目标环境?(作者环境、发布环境,或两者兼顾)
性能与缓存
  • 预期流量规模?(低、中、高、企业级)
  • 缓存策略?(激进型、适度型、动态型)
  • 是否需要集成CDN?
集成
  • 是否需要无头/混合JSON API?
  • 是否需要集成外部服务?
  • 是否为内容片段使用GraphQL?
  • 是否需要集成SPA框架?

Phase 2: Analysis & Planning

第二阶段:分析与规划

Step 2.1: Present High-Level Overview
After gathering requirements (or analyzing autonomously), present:
Understanding Summary
Based on my analysis, here's what I understand about your requirements:
  • [Bullet points summarizing the project scope]
  • [Target environment and architecture]
  • [Key components and features needed]
  • [Performance and caching considerations]
  • [Integration points]
Step 2.2: Present TODO List
Create and present a numbered task list:
Implementation Plan
I will implement the following tasks:
  1. Task 1: Description
  2. Task 2: Description
  3. Task 3: Description ...
Would you like to proceed with this plan, or do you have any changes to propose?
Step 2.3: Wait for User Approval
  • If user approves → Proceed to Phase 3
  • If user proposes changes → Update the plan and present again
  • Do NOT start implementation until user confirms
步骤2.1:呈现高层概述
收集完需求(或自主分析后),呈现:
需求理解总结
根据我的分析,我对您的需求理解如下:
  • [项目范围总结要点]
  • [目标环境与架构]
  • [所需核心组件与功能]
  • [性能与缓存考量]
  • [集成点]
步骤2.2:呈现待办事项列表
创建并展示编号任务列表:
实施计划
我将执行以下任务:
  1. 任务1:描述
  2. 任务2:描述
  3. 任务3:描述 ...
您是否同意按此计划推进,或者有任何修改建议?
步骤2.3:等待用户确认
  • 若用户批准 → 进入第三阶段
  • 若用户提出修改 → 更新计划并重新呈现
  • 用户确认前请勿开始实施

Phase 3: Implementation

第三阶段:实施

Execute the approved TODO list:
  1. Create component structure
  2. Implement Sling Model with proper injectors
  3. Design dialog using Granite UI patterns
  4. Configure ClientLibs with bundling strategy
  5. Set up Dispatcher rules
  6. Provide testing guidance
执行已批准的待办事项列表:
  1. 创建组件结构
  2. 使用合适的注入器实现Sling Model
  3. 基于Granite UI模式设计对话框
  4. 配置带有打包策略的ClientLibs
  5. 设置Dispatcher规则
  6. 提供测试指导

Phase 4: Validation

第四阶段:验证

Present completed work with:
  • Summary of what was implemented
  • File locations and structure
  • Testing recommendations
  • Cloud Manager quality gate considerations
通过以下内容呈现已完成的工作:
  • 实施内容总结
  • 文件位置与结构
  • 测试建议
  • Cloud Manager质量门考量

Reference Documentation

参考文档

Read the appropriate reference based on the task:
根据任务类型阅读对应参考资料:

Workflows

工作流

WorkflowFileUse When
AEM Diagramsworkflows/AEMDiagrams.mdCreating Mermaid or ASCII architecture diagrams
工作流文件适用场景
AEM图表workflows/AEMDiagrams.md创建Mermaid或ASCII架构图

Core References (in this skill)

核心参考资料(本技能内)

TopicFileUse When
Architecture Patternsreferences/architecture-deep-dive.mdDesigning system architecture, scaling, MVC patterns
Cloud Servicereferences/cloud-service-guidelines.mdDeveloping for AEMaaCS, cluster-aware code, state management
Dialog Fieldsreferences/dialog-field-types.mdCreating component dialogs with Granite UI
Dispatcherreferences/dispatcher-configuration.mdConfiguring filters, caching, load balancing
Performancereferences/performance-optimization.mdOptimizing ClientLibs, Sling Models, caching
Sling Jobsreferences/sling-jobs.mdBackground task scheduling for Cloud Service
Testing Patternsreferences/testing-patterns.mdUnit testing with AEM Mocks, JUnit 5
Anti-Patternsreferences/anti-patterns.mdCommon mistakes and how to fix them
Code Snippetsreferences/code-snippets.mdCopy-paste ready code templates
主题文件适用场景
架构模式references/architecture-deep-dive.md系统架构设计、扩容、MVC模式
云服务references/cloud-service-guidelines.mdAEMaaCS开发、集群感知代码、状态管理
对话框字段references/dialog-field-types.md使用Granite UI创建组件对话框
Dispatcherreferences/dispatcher-configuration.md配置过滤器、缓存、负载均衡
性能优化references/performance-optimization.md优化ClientLibs、Sling Models、缓存
Sling任务references/sling-jobs.md云服务的后台任务调度
测试模式references/testing-patterns.md使用AEM Mocks、JUnit 5进行单元测试
反模式references/anti-patterns.md常见错误及修复方法
代码片段references/code-snippets.md可直接复制使用的代码模板

External Guides (in project root)

外部指南(项目根目录)

TopicFileUse When
Sling Modelsaem-sling-models-guide.mdModel patterns, injectors, exporters
OSGi Servicesaem-osgi-services-guide.mdService design, dependency injection
Servletsaem-servlets-guide.mdEndpoint patterns, security
Dialogsaem-dialog-creation-guide.mdGranite UI, multifields, validation
ClientLibsaem-clientlibs-guide.mdJS/CSS bundling, lazy loading
Dispatcheraem-dispatcher-guide.mdDetailed cache configuration
Componentscomponent-development.mdHTL, component structure
Best Practicesadobe-technical-practices.mdAdobe-recommended patterns
主题文件适用场景
Sling Modelsaem-sling-models-guide.md模型模式、注入器、导出器
OSGi服务aem-osgi-services-guide.md服务设计、依赖注入
Servletaem-servlets-guide.md端点模式、安全
对话框aem-dialog-creation-guide.mdGranite UI、多字段、验证
ClientLibsaem-clientlibs-guide.mdJS/CSS打包、懒加载
Dispatcheraem-dispatcher-guide.md详细缓存配置
组件component-development.mdHTL、组件结构
最佳实践adobe-technical-practices.mdAdobe推荐模式

Quick Reference: Component Creation

快速参考:组件创建

Component Structure

组件结构

/apps/myproject/components/mycomponent/
├── .content.xml                    # Component definition
├── _cq_dialog/.content.xml         # Author dialog
├── _cq_editConfig.xml              # Edit configuration
├── mycomponent.html                # HTL template
└── clientlib/                      # Component CSS/JS
/apps/myproject/components/mycomponent/
├── .content.xml                    # 组件定义
├── _cq_dialog/.content.xml         # 作者对话框
├── _cq_editConfig.xml              # 编辑配置
├── mycomponent.html                # HTL模板
└── clientlib/                      # 组件CSS/JS

Component Definition

组件定义

xml
<?xml version="1.0" encoding="UTF-8"?>
<jcr:root xmlns:jcr="http://www.jcp.org/jcr/1.0"
    xmlns:cq="http://www.day.com/jcr/cq/1.0"
    xmlns:sling="http://sling.apache.org/jcr/sling/1.0"
    jcr:primaryType="cq:Component"
    jcr:title="My Component"
    jcr:description="Description"
    componentGroup="My Project - Content"
    sling:resourceSuperType="core/wcm/components/title/v3/title"/>
xml
<?xml version="1.0" encoding="UTF-8"?>
<jcr:root xmlns:jcr="http://www.jcp.org/jcr/1.0"
    xmlns:cq="http://www.day.com/jcr/cq/1.0"
    xmlns:sling="http://sling.apache.org/jcr/sling/1.0"
    jcr:primaryType="cq:Component"
    jcr:title="My Component"
    jcr:description="Description"
    componentGroup="My Project - Content"
    sling:resourceSuperType="core/wcm/components/title/v3/title"/>

Sling Model Pattern

Sling Model模式

java
@Model(
    adaptables = {Resource.class, SlingHttpServletRequest.class},
    adapters = {MyComponent.class, ComponentExporter.class},
    resourceType = MyComponentImpl.RESOURCE_TYPE,
    defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL
)
@Exporter(name = ExporterConstants.SLING_MODEL_EXPORTER_NAME,
          extensions = ExporterConstants.SLING_MODEL_EXTENSION)
public class MyComponentImpl implements MyComponent {

    static final String RESOURCE_TYPE = "myproject/components/mycomponent";

    @ValueMapValue
    private String title;

    @OSGiService
    private MyService myService;

    @Override
    public String getTitle() { return title; }
}
java
@Model(
    adaptables = {Resource.class, SlingHttpServletRequest.class},
    adapters = {MyComponent.class, ComponentExporter.class},
    resourceType = MyComponentImpl.RESOURCE_TYPE,
    defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL
)
@Exporter(name = ExporterConstants.SLING_MODEL_EXPORTER_NAME,
          extensions = ExporterConstants.SLING_MODEL_EXTENSION)
public class MyComponentImpl implements MyComponent {

    static final String RESOURCE_TYPE = "myproject/components/mycomponent";

    @ValueMapValue
    private String title;

    @OSGiService
    private MyService myService;

    @Override
    public String getTitle() { return title; }
}

Common Dialog Fields

常见对话框字段

FieldResource Type
Text
granite/ui/components/coral/foundation/form/textfield
Textarea
granite/ui/components/coral/foundation/form/textarea
Rich Text
cq/gui/components/authoring/dialog/richtext
Checkbox
granite/ui/components/coral/foundation/form/checkbox
Select
granite/ui/components/coral/foundation/form/select
Path
granite/ui/components/coral/foundation/form/pathfield
Image
cq/gui/components/authoring/dialog/fileupload
Multifield
granite/ui/components/coral/foundation/form/multifield
For complete field examples, see references/dialog-field-types.md.
字段资源类型
文本
granite/ui/components/coral/foundation/form/textfield
文本域
granite/ui/components/coral/foundation/form/textarea
富文本
cq/gui/components/authoring/dialog/richtext
复选框
granite/ui/components/coral/foundation/form/checkbox
下拉选择
granite/ui/components/coral/foundation/form/select
路径
granite/ui/components/coral/foundation/form/pathfield
图片
cq/gui/components/authoring/dialog/fileupload
多字段
granite/ui/components/coral/foundation/form/multifield
完整字段示例请参考references/dialog-field-types.md

Caching Decision Tree

缓存决策树

Is content personalized?
├── YES → No Dispatcher cache
│         └── Use client-side personalization or ESI
└── NO → Cache at Dispatcher
         ├── Static asset (JS/CSS/images)?
         │   └── Long TTL (1 year) + content-hash
         ├── HTML content?
         │   └── Moderate TTL (5-60 min) + statfileslevel
         └── API/JSON?
             ├── Public → TTL based on freshness needs
             └── Private → No Dispatcher cache
内容是否为个性化内容?
├── 是 → 不使用Dispatcher缓存
│         └── 使用客户端个性化或ESI
└── 否 → 在Dispatcher层缓存
         ├── 是否为静态资源(JS/CSS/图片)?
         │   └── 长TTL(1年)+ 内容哈希
         ├── 是否为HTML内容?
         │   └── 中等TTL(5-60分钟)+ statfileslevel
         └── 是否为API/JSON?
             ├── 公开内容 → 根据新鲜度需求设置TTL
             └── 私有内容 → 不使用Dispatcher缓存

Statfileslevel Reference

Statfileslevel参考

StructureLevelEffect
/content/site
2Per-site invalidation
/content/site/language
3Per-language invalidation
/content/site/region/country
4Per-country invalidation
结构级别效果
/content/site
2按站点失效缓存
/content/site/language
3按语言失效缓存
/content/site/region/country
4按国家/地区失效缓存

Security Checklist

安全检查清单

Dispatcher Filters (Default Deny)

Dispatcher过滤器(默认拒绝)

apache
/filter {
    /0001 { /type "deny" /glob "*" }
    /0100 { /type "allow" /method "GET" /url "/content/mysite/*" }
    /0200 { /type "allow" /method "GET" /url "/etc.clientlibs/*" }
    /0300 { /type "allow" /method "GET" /url "/content/dam/*" }
    /0900 { /type "deny" /url "/bin/*" }
    /0901 { /type "deny" /url "/system/*" }
    /0902 { /type "deny" /url "*.infinity.json" }
}
apache
/filter {
    /0001 { /type "deny" /glob "*" }
    /0100 { /type "allow" /method "GET" /url "/content/mysite/*" }
    /0200 { /type "allow" /method "GET" /url "/etc.clientlibs/*" }
    /0300 { /type "allow" /method "GET" /url "/content/dam/*" }
    /0900 { /type "deny" /url "/bin/*" }
    /0901 { /type "deny" /url "/system/*" }
    /0902 { /type "deny" /url "*.infinity.json" }
}

Service User Pattern

服务用户模式

java
try (ResourceResolver resolver = resolverFactory.getServiceResourceResolver(
        Map.of(ResourceResolverFactory.SUBSERVICE, "myproject-service-user"))) {
    // Minimal permissions operations
}
java
try (ResourceResolver resolver = resolverFactory.getServiceResourceResolver(
        Map.of(ResourceResolverFactory.SUBSERVICE, "myproject-service-user"))) {
    // 最小权限操作
}

Cloud Service Specifics

云服务特定说明

When developing for AEMaaCS, always read references/cloud-service-guidelines.md for:
  • Cluster-aware code: Instances can stop anytime
  • No local state: Disk is ephemeral
  • Sling Jobs: For reliable background tasks
  • HTTP timeouts: Always set connect/read timeouts
  • Rate limiting: Handle 429 with exponential backoff
  • Touch UI only: No Classic UI support
  • Immutable repository:
    /libs
    and
    /apps
    are read-only
针对AEMaaCS开发时,请务必阅读references/cloud-service-guidelines.md了解:
  • 集群感知代码:实例可能随时停止
  • 无本地状态:磁盘为临时存储
  • Sling任务:用于可靠的后台任务
  • HTTP超时:始终设置连接/读取超时
  • 速率限制:使用指数退避处理429错误
  • 仅支持Touch UI:不支持Classic UI
  • 不可变仓库
    /libs
    /apps
    为只读

CI/CD Quality Gates

CI/CD质量门

GateChecksAction
Code QualitySonarQube, code smellsFix before merge
SecurityVulnerability scanImmediate fix
PerformanceLoad test, response timesReview if fails
质量门检查项操作
代码质量SonarQube、代码异味合并前修复
安全漏洞扫描立即修复
性能负载测试、响应时间失败时进行评审

Common Pitfalls

常见陷阱

  1. JCR queries in render path → Use content hierarchy traversal
  2. Hardcoded paths → Use context-aware configuration
  3. Unclosed ResourceResolvers → Use try-with-resources
  4. Deep multifield nesting → Consider child nodes
  5. Missing Dispatcher filters → Default-deny approach
  6. Admin sessions in code → Use service users
  7. Untested cache invalidation → Verify statfileslevel
  8. Large inline dependencies → Lazy load heavy scripts
  9. Skipping Core Components → Extend before building custom
  10. Ignoring Cloud Manager gates → Fix locally first
  1. 在渲染路径中使用JCR查询 → 使用内容层级遍历
  2. 硬编码路径 → 使用上下文感知配置
  3. 未关闭ResourceResolvers → 使用try-with-resources语法
  4. 多字段深度嵌套 → 考虑使用子节点
  5. 缺失Dispatcher过滤器 → 采用默认拒绝策略
  6. 代码中使用管理员会话 → 使用服务用户
  7. 未测试缓存失效 → 验证statfileslevel设置
  8. 大型内联依赖 → 懒加载重型脚本
  9. 跳过核心组件 → 先扩展再自定义
  10. 忽略Cloud Manager质量门 → 先在本地修复