@Scheduled annotation does not require proxy creation. The mechanism is different. After bean initialization Spring called post-processor ScheduledAnnotationBeanPostProcessor. Post processor searches for all methods annotated with @Scheduled
and registers them to TaskScheduller for execution. Method execution will be performed via reflection.
See ScheduledAnnotationBeanPostProcessor source code.
@Scheduled
Processing of @Scheduled annotations is performed by registering a
ScheduledAnnotationBeanPostProcessor. This can be done manually or,
more conveniently, through the task:annotation-driven/ XML element
or @EnableScheduling annotation.
ScheduledAnnotationBeanPostProcessor
Bean post-processor that registers methods annotated with @Scheduled
to be invoked by a TaskScheduler according to the "fixedRate",
"fixedDelay", or "cron" expression provided via the annotation. This
post-processor is automatically registered by Spring's
task:annotation-driven XML element, and also by the
@EnableScheduling annotation.
Autodetects any SchedulingConfigurer instances in the container,
allowing for customization of the scheduler to be used or for
fine-grained control over task registration (e.g. registration of
Trigger tasks). See the @EnableScheduling javadocs for complete usage
details.
@PostConstruct also implemented via post-processor InitDestroyAnnotationBeanPostProcessor when dependency injection performed for bean, method which marked @PostConstruct
will be executed thru reflection without proxy.
See InitDestroyAnnotationBeanPostProcessor source code
Summary:
In your example, Spring will create bean without proxy.
In case you will add a proxy-specific annotation, for example, @Transactional
you will get an exception that proxy can not be created due to final class java.lang.IllegalArgumentException: Cannot subclass final class com.test.services.MyService
@Service
@EnableScheduling
public final class MyService {
@PostConstruct
public void init(){
System.out.println("MyService started");
}
@Scheduled(fixedDelay= 1000)
@Transactional
public void scheduleCall() {
System.out.println("scheduleCall");
}
}
But the current problem you also can solve to force use JDK dynamic proxy
. We need to create an interface for class and set property spring.aop.proxy-target-class = false
according to Proxying mechanisms