Apex中如何处理元数据API变更?以ApexClass增删改为例
因为ApexClass属于元数据对象,确实无法直接创建触发器,以下是几个实用的实现方案:
方案1:Change Data Capture (CDC) 实时监听变更
Salesforce的Change Data Capture支持监听元数据对象(包括ApexClass)的增删改事件,这是最接近实时触发的方案:
启用CDC:
- 进入Setup → Change Data Capture
- 在Available Entities中找到
ApexClass,添加到Selected Entities并保存配置
编写CDC订阅Apex类:
创建继承ChangeEventSubscriber的类,监听ApexClass变更事件,直接获取Body并调用服务方法:public class ApexClassChangeSubscriber implements ChangeEventSubscriber { public static List<ChangeEvent> deliver(List<ChangeEvent> events) { for (ChangeEvent event : events) { ApexClassChangeEvent classEvent = (ApexClassChangeEvent) event; Id classId = classEvent.Id; String classBody = classEvent.Body; EventBus.ChangeEventType eventType = classEvent.ChangeEventHeader.changeType; // 替换为你的服务方法调用 YourServiceClass.processApexClassChange(classId, classBody, eventType); } return events; } }注意:删除事件中
Body字段为空,需提前处理该场景。
方案2:定时轮询对比变更(适合无CDC权限的场景)
如果无法启用CDC,可以用Scheduled Apex定期查询ApexClass的LastModifiedDate,对比上次轮询时间戳找出变更类:
存储上次轮询时间:
创建名为LastPollTime__c的Hierarchy类型Custom Setting,添加LastModifiedTimestamp__c(DateTime类型)字段,用于记录上次执行时间。编写调度类:
global class ApexClassPollScheduler implements Schedulable { global void execute(SchedulableContext sc) { LastPollTime__c pollSetting = LastPollTime__c.getOrgDefaults(); DateTime lastPollTime = pollSetting != null ? pollSetting.LastModifiedTimestamp__c : DateTime.newInstance(1970, 1, 1); List<ApexClass> changedClasses = [ SELECT Id, Name, Body, LastModifiedDate FROM ApexClass WHERE LastModifiedDate > :lastPollTime ]; for (ApexClass cls : changedClasses) { // 替换为你的服务方法调用 YourServiceClass.processApexClassChange(cls.Id, cls.Body, 'UPDATE'); } if (pollSetting == null) pollSetting = new LastPollTime__c(); pollSetting.LastModifiedTimestamp__c = DateTime.now(); upsert pollSetting; } }执行
System.schedule('ApexClass Poll Job', '0 0 * * * ?', new ApexClassPollScheduler());设置每小时轮询(可调整cron表达式)。
方案3:DevOps部署钩子(针对部署触发的变更)
如果ApexClass变更是通过DevOps Center等部署工具触发的,可设置Post-Deployment钩子调用Apex REST服务:
编写Apex REST服务:
@RestResource(urlMapping='/ApexClassChange/*') global class ApexClassChangeRestService { @HttpPost global static void processChange() { RestRequest req = RestContext.request; ApexClassChangeRequest changeReq = (ApexClassChangeRequest) JSON.deserialize(req.requestBody.toString(), ApexClassChangeRequest.class); // 替换为你的服务方法调用 YourServiceClass.processApexClassChange(changeReq.ClassId, changeReq.ClassBody, changeReq.ChangeType); } global class ApexClassChangeRequest { global Id ClassId; global String ClassBody; global String ChangeType; // 'CREATE'/'UPDATE'/'DELETE' } }配置部署钩子:
在DevOps流水线的Post-Deployment步骤中,调用上述REST接口,传入部署的ApexClass相关数据。
内容的提问来源于stack exchange,提问作者Velerii Artemenko

