AEM 6.3 :使用OSGi R6注释创建调度程序



我已经使用OSGi R6注释编写了一个调度程序,但它似乎没有运行:

package com.aem.sites.interfaces;
import org.osgi.service.metatype.annotations.AttributeDefinition;
import org.osgi.service.metatype.annotations.AttributeType;
import org.osgi.service.metatype.annotations.ObjectClassDefinition;
@ObjectClassDefinition(name = "Scheduler Configuration for Weather", description = "Configuration file for Scheduler")
public @interface SchedulerConfiguration {
@AttributeDefinition(
name = "sample parameter",
description="Sample String parameter",
type = AttributeType.STRING
)
public String parameter() default "scheduler";
@AttributeDefinition(
name = "Concurrent",
description = "Schedule task concurrently",
type = AttributeType.BOOLEAN
)
boolean scheduler_concurrent() default true;
@AttributeDefinition(
name = "Expression",
description = "Cron-job expression. Default: run every minute.",
type = AttributeType.STRING
)
String scheduler_expression() default "0 * * * * ?";
}

package com.aem.sites.schedulers;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.metatype.annotations.Designate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.aem.sites.interfaces.SchedulerConfiguration;
@Component(immediate = true,
configurationPid = "com.aem.sites.schedulers.WeatherServiceScheduler")
@Designate(ocd=SchedulerConfiguration.class)
public class WeatherServiceScheduler implements Runnable {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
private String myParameter;
@Override
public void run() {
logger.info("*******************************************Sample OSGi Scheduler is now running", myParameter);
}
@Activate
public void activate(SchedulerConfiguration config) {
logger.info("*******************************************weather service scheduler"+ myParameter);
myParameter = config.parameter();
}
}

我正在关注这个 https://github.com/nateyolles/aem-osgi-annotation-demo/blob/master/core/src/main/java/com/nateyolles/aem/osgiannotationdemo/core/schedulers/SampleOsgiScheduledTask.java 但看起来我在这里做错了什么。不知道是什么。

提前致谢

WeatherSchedulerService类中,您没有将其注册为服务。你可以像这样service = Runnable.class做,而不是配置Pid

使用 OSGi R6 注解创建 SlingScheduler 的正确方法如下:

  1. 创建 OSGi 配置类
import org.osgi.service.metatype.annotations.AttributeDefinition;
import org.osgi.service.metatype.annotations.AttributeType;
import org.osgi.service.metatype.annotations.ObjectClassDefinition;
@ObjectClassDefinition(name = "Sling Scheduler Configuration", description = "This configuration is used to demonstrates a sling scheduler in action")
public @interface SchedulerConfiguration {
@AttributeDefinition(
name = "Scheduler name", 
description = "Name of the scheduler", 
type = AttributeType.STRING)
public String name() default "Custom Sling Scheduler";
@AttributeDefinition(
name = "Enabled", 
description = "Flag to enable/disable a scheduler", 
type = AttributeType.STRING)
public boolean enabled() default false;
@AttributeDefinition(
name = "Cron expression", 
description = "Cron expression used by the scheduler", 
type = AttributeType.STRING)
public String cronExpression() default "0 * * * * ?";
@AttributeDefinition(
name = "Custom parameter", 
description = "Custom parameter to showcase the usage of a sling scheduler", 
type = AttributeType.STRING)
public String customParameter();
}
  1. 将调度程序类创建为服务。为了使用 R6 注释创建 OSGi 服务,我们使用@Component(service=<your-interface>.class,...). 因此,按如下方式创建服务
import org.apache.sling.commons.scheduler.ScheduleOptions;
import org.apache.sling.commons.scheduler.Scheduler;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Deactivate;
import org.osgi.service.component.annotations.Modified;
import org.osgi.service.component.annotations.Reference;
import org.osgi.service.metatype.annotations.Designate;
import org.redquark.aem.learning.core.configurations.SchedulerConfiguration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@Component(immediate = true, service = Runnable.class)
@Designate(ocd = SchedulerConfiguration.class)
public class CustomScheduler implements Runnable {
// Logger
private final Logger log = LoggerFactory.getLogger(this.getClass());
// Custom parameter that is to be read from the configuration
private String customParameter;
// Id of the scheduler based on its name
private int schedulerId;
// Scheduler instance injected
@Reference
private Scheduler scheduler;
/**
* Activate method to initialize stuff
* 
* @param schedulerConfiguration
*/
@Activate
protected void activate(SchedulerConfiguration schedulerConfiguration) {
schedulerId = schedulerConfiguration.name().hashCode();
customParameter = schedulerConfiguration.customParameter();
}
/**
* Modifies the scheduler id on modification
* 
* @param schedulerConfiguration
*/
@Modified
protected void modified(SchedulerConfiguration schedulerConfiguration) {
// Removing scheduler
removeScheduler();
// Updating the scheduler id
schedulerId = schedulerConfiguration.name().hashCode();
// Again adding the scheduler
addScheduler(schedulerConfiguration);
}
/**
* This method deactivates the scheduler and removes it
* 
* @param schedulerConfiguration
*/
@Deactivate
protected void deactivate(SchedulerConfiguration schedulerConfiguration) {
// Removing the scheduler
removeScheduler();
}
/**
* This method removes the scheduler
*/
private void removeScheduler() {
log.info("Removing scheduler: {}", schedulerId);
// Unscheduling/removing the scheduler
scheduler.unschedule(String.valueOf(schedulerId));
}
/**
* This method adds the scheduler
* 
* @param schedulerConfiguration
*/
private void addScheduler(SchedulerConfiguration schedulerConfiguration) {
// Check if the scheduler is enabled
if (schedulerConfiguration.enabled()) {
// Scheduler option takes the cron expression as a parameter and run accordingly
ScheduleOptions scheduleOptions = scheduler.EXPR(schedulerConfiguration.cronExpression());
// Adding some parameters
scheduleOptions.name(schedulerConfiguration.name());
scheduleOptions.canRunConcurrently(false);
// Scheduling the job
scheduler.schedule(this, scheduleOptions);
log.info("Scheduler added");
} else {
log.info("Scheduler is disabled");
}
}
/**
* Overridden run method to execute Job
*/
@Override
public void run() {
log.info("Custom Scheduler is now running using the passed custom paratmeter, customParameter {}",
customParameter);
}
  • 在 activate() 方法中,我们正在读取所需的值。然后,我们从调度程序名称中获取调度程序 ID。
  • modified() 方法在 OSGi 配置被修改的情况下重新计算调度程序 ID。
  • 在 addScheduler() 方法中,我们使用 Scheduler API 注册调度器。

有关详细信息和分步执行,您还可以查看我的博客文章 - 第13天:AEM中的计划程序

我希望这有所帮助。祝您编码愉快!

类注解中不需要configurationPid,而且你也缺少service=Runnable.class应该跟在immediate=true后面,即类声明应该看起来像:

@Component(immediate = true, service=Runnable.class)
@Designate(ocd=SchedulerConfiguration.class)
public class WeatherServiceScheduler implements Runnable {

最新更新