Clarify SchedulerFactoryBean's LocalDataSourceJobStore overriding
Includes clarification of interface-level cache annotations for target-class proxies. Closes gh-27709 See gh-27726
This commit is contained in:
parent
c44447f622
commit
d7b9270672
|
|
@ -39,6 +39,7 @@ import org.springframework.lang.Nullable;
|
|||
* Subclass of Quartz's {@link JobStoreCMT} class that delegates to a Spring-managed
|
||||
* {@link DataSource} instead of using a Quartz-managed JDBC connection pool.
|
||||
* This JobStore will be used if SchedulerFactoryBean's "dataSource" property is set.
|
||||
* You may also configure it explicitly, possibly as a custom subclass of this class.
|
||||
*
|
||||
* <p>Supports both transactional and non-transactional DataSource access.
|
||||
* With a non-XA DataSource and local Spring transactions, a single DataSource
|
||||
|
|
@ -58,6 +59,8 @@ import org.springframework.lang.Nullable;
|
|||
* @since 1.1
|
||||
* @see SchedulerFactoryBean#setDataSource
|
||||
* @see SchedulerFactoryBean#setNonTransactionalDataSource
|
||||
* @see SchedulerFactoryBean#getConfigTimeDataSource()
|
||||
* @see SchedulerFactoryBean#getConfigTimeNonTransactionalDataSource()
|
||||
* @see org.springframework.jdbc.datasource.DataSourceUtils#doGetConnection
|
||||
* @see org.springframework.jdbc.datasource.DataSourceUtils#releaseConnection
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -310,9 +310,11 @@ public class SchedulerFactoryBean extends SchedulerAccessor implements FactoryBe
|
|||
|
||||
/**
|
||||
* Set the default {@link DataSource} to be used by the Scheduler.
|
||||
* If set, this will override corresponding settings in Quartz properties.
|
||||
* <p>Note: If this is set, the Quartz settings should not define
|
||||
* a job store "dataSource" to avoid meaningless double configuration.
|
||||
* Also, do not define a "org.quartz.jobStore.class" property at all.
|
||||
* (You may explicitly define Spring's {@link LocalDataSourceJobStore}
|
||||
* but that's the default when using this method anyway.)
|
||||
* <p>A Spring-specific subclass of Quartz' JobStoreCMT will be used.
|
||||
* It is therefore strongly recommended to perform all operations on
|
||||
* the Scheduler within Spring-managed (or plain JTA) transactions.
|
||||
|
|
|
|||
|
|
@ -83,6 +83,19 @@ public class EnableCachingIntegrationTests {
|
|||
assertCacheHit(key, value, cache);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void barServiceWithCacheableInterfaceCglib() {
|
||||
this.context = new AnnotationConfigApplicationContext(BarConfigCglib.class);
|
||||
BarService service = this.context.getBean(BarService.class);
|
||||
Cache cache = getCache();
|
||||
|
||||
Object key = new Object();
|
||||
assertCacheMiss(key, cache);
|
||||
|
||||
Object value = service.getSimple(key);
|
||||
assertCacheHit(key, value, cache);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void beanConditionOff() {
|
||||
this.context = new AnnotationConfigApplicationContext(BeanConditionConfig.class);
|
||||
|
|
@ -185,6 +198,36 @@ public class EnableCachingIntegrationTests {
|
|||
}
|
||||
|
||||
|
||||
@Configuration
|
||||
@Import(SharedConfig.class)
|
||||
@EnableCaching(proxyTargetClass = true)
|
||||
static class BarConfigCglib {
|
||||
|
||||
@Bean
|
||||
public BarService barService() {
|
||||
return new BarServiceImpl();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
interface BarService {
|
||||
|
||||
@Cacheable(cacheNames = "testCache")
|
||||
Object getSimple(Object key);
|
||||
}
|
||||
|
||||
|
||||
static class BarServiceImpl implements BarService {
|
||||
|
||||
private final AtomicLong counter = new AtomicLong();
|
||||
|
||||
@Override
|
||||
public Object getSimple(Object key) {
|
||||
return this.counter.getAndIncrement();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Configuration
|
||||
@Import(FooConfig.class)
|
||||
@EnableCaching
|
||||
|
|
|
|||
|
|
@ -5396,6 +5396,7 @@ You can use these macros instead of the six-digit value, thus: `@Scheduled(cron
|
|||
|===
|
||||
|
||||
|
||||
|
||||
[[scheduling-quartz]]
|
||||
=== Using the Quartz Scheduler
|
||||
|
||||
|
|
@ -5451,7 +5452,6 @@ has it applied automatically:
|
|||
protected void executeInternal(JobExecutionContext ctx) throws JobExecutionException {
|
||||
// do the actual work
|
||||
}
|
||||
|
||||
}
|
||||
----
|
||||
|
||||
|
|
@ -5571,11 +5571,19 @@ seconds and one running every morning at 6 AM. To finalize everything, we need t
|
|||
</bean>
|
||||
----
|
||||
|
||||
More properties are available for the `SchedulerFactoryBean`, such as the calendars
|
||||
used by the job details, properties to customize Quartz with, and others. See the
|
||||
{api-spring-framework}/scheduling/quartz/SchedulerFactoryBean.html[`SchedulerFactoryBean`]
|
||||
More properties are available for the `SchedulerFactoryBean`, such as the calendars used by the
|
||||
job details, properties to customize Quartz with, and a Spring-provided JDBC DataSource. See
|
||||
the {api-spring-framework}/scheduling/quartz/SchedulerFactoryBean.html[`SchedulerFactoryBean`]
|
||||
javadoc for more information.
|
||||
|
||||
NOTE: `SchedulerFactoryBean` also recognizes a `quartz.properties` file in the classpath,
|
||||
based on Quartz property keys, as with regular Quartz configuration. Please note that many
|
||||
`SchedulerFactoryBean` settings interact with common Quartz settings in the properties file;
|
||||
it is therefore not recommended to specify values at both levels. For example, do not set
|
||||
an "org.quartz.jobStore.class" property if you mean to rely on a Spring-provided DataSource,
|
||||
or specify an `org.springframework.scheduling.quartz.LocalDataSourceJobStore` variant which
|
||||
is a full-fledged replacement for the standard `org.quartz.impl.jdbcjobstore.JobStoreTX`.
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -5877,7 +5885,6 @@ is updated in the cache. The following example shows how to use the `sync` attri
|
|||
----
|
||||
<1> Using the `sync` attribute.
|
||||
|
||||
|
||||
NOTE: This is an optional feature, and your favorite cache library may not support it.
|
||||
All `CacheManager` implementations provided by the core framework support it. See the
|
||||
documentation of your cache provider for more details.
|
||||
|
|
@ -6035,7 +6042,6 @@ all entries from the `books` cache:
|
|||
----
|
||||
<1> Using the `allEntries` attribute to evict all entries from the cache.
|
||||
|
||||
|
||||
This option comes in handy when an entire cache region needs to be cleared out.
|
||||
Rather than evicting each entry (which would take a long time, since it is inefficient),
|
||||
all the entries are removed in one operation, as the preceding example shows.
|
||||
|
|
@ -6094,7 +6100,6 @@ comes into play. The following examples uses `@CacheConfig` to set the name of t
|
|||
----
|
||||
<1> Using `@CacheConfig` to set the name of the cache.
|
||||
|
||||
|
||||
`@CacheConfig` is a class-level annotation that allows sharing the cache names,
|
||||
the custom `KeyGenerator`, the custom `CacheManager`, and the custom `CacheResolver`.
|
||||
Placing this annotation on the class does not turn on any caching operation.
|
||||
|
|
@ -6235,13 +6240,11 @@ if you need to annotate non-public methods, as it changes the bytecode itself.
|
|||
****
|
||||
|
||||
TIP: Spring recommends that you only annotate concrete classes (and methods of concrete
|
||||
classes) with the `@Cache{asterisk}` annotation, as opposed to annotating interfaces.
|
||||
You certainly can place the `@Cache{asterisk}` annotation on an interface (or an interface
|
||||
method), but this works only as you would expect it to if you use interface-based proxies.
|
||||
The fact that Java annotations are not inherited from interfaces means that, if you use
|
||||
class-based proxies (`proxy-target-class="true"`) or the weaving-based aspect
|
||||
(`mode="aspectj"`), the caching settings are not recognized by the proxying and weaving
|
||||
infrastructure, and the object is not wrapped in a caching proxy.
|
||||
classes) with the `@Cache{asterisk}` annotations, as opposed to annotating interfaces.
|
||||
You certainly can place an `@Cache{asterisk}` annotation on an interface (or an interface
|
||||
method), but this works only if you use the proxy mode (`mode="proxy"`). If you use the
|
||||
weaving-based aspect (`mode="aspectj"`), the caching settings are not recognized on
|
||||
interface-level declarations by the weaving infrastructure.
|
||||
|
||||
NOTE: In proxy mode (the default), only external method calls coming in through the
|
||||
proxy are intercepted. This means that self-invocation (in effect, a method within the
|
||||
|
|
@ -6378,7 +6381,6 @@ to customize the factory for each cache operation, as the following example show
|
|||
----
|
||||
<1> Customizing the factory for this operation.
|
||||
|
||||
|
||||
NOTE: For all referenced classes, Spring tries to locate a bean with the given type.
|
||||
If more than one match exists, a new instance is created and can use the regular
|
||||
bean lifecycle callbacks, such as dependency injection.
|
||||
|
|
|
|||
Loading…
Reference in New Issue