diff --git a/spring-context-support/src/main/java/org/springframework/scheduling/quartz/LocalDataSourceJobStore.java b/spring-context-support/src/main/java/org/springframework/scheduling/quartz/LocalDataSourceJobStore.java index e0b12f443f..4543f95b0d 100644 --- a/spring-context-support/src/main/java/org/springframework/scheduling/quartz/LocalDataSourceJobStore.java +++ b/spring-context-support/src/main/java/org/springframework/scheduling/quartz/LocalDataSourceJobStore.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -58,6 +58,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 */ diff --git a/spring-context-support/src/main/java/org/springframework/scheduling/quartz/SchedulerFactoryBean.java b/spring-context-support/src/main/java/org/springframework/scheduling/quartz/SchedulerFactoryBean.java index 50ef456cfc..9136111d9e 100644 --- a/spring-context-support/src/main/java/org/springframework/scheduling/quartz/SchedulerFactoryBean.java +++ b/spring-context-support/src/main/java/org/springframework/scheduling/quartz/SchedulerFactoryBean.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -313,6 +313,7 @@ public class SchedulerFactoryBean extends SchedulerAccessor implements FactoryBe * If set, this will override corresponding settings in Quartz properties. *

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. *

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. diff --git a/src/docs/asciidoc/integration.adoc b/src/docs/asciidoc/integration.adoc index d8d346633e..a199c93cd1 100644 --- a/src/docs/asciidoc/integration.adoc +++ b/src/docs/asciidoc/integration.adoc @@ -6615,7 +6615,6 @@ has it applied automatically: protected void executeInternal(JobExecutionContext ctx) throws JobExecutionException { // do the actual work } - } ---- @@ -6740,11 +6739,17 @@ seconds and one running every morning at 6 AM. To finalize everything, we need t ---- -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. + @@ -6756,8 +6761,8 @@ an existing Spring application. Similar to the <> and more customization options. +In Spring Framework 4.1, the cache abstraction was significantly extended with support +for <> and more customization options. @@ -6815,15 +6820,16 @@ compliant caches (such as Ehcache 3.x). See <> for more information plugging in other cache stores and providers. IMPORTANT: The caching abstraction has no special handling for multi-threaded and -multi-process environments, as such features are handled by the cache implementation. . +multi-process environments, as such features are handled by the cache implementation. If you have a multi-process environment (that is, an application deployed on several nodes), you need to configure your cache provider accordingly. Depending on your use cases, a copy of the same data on several nodes can be enough. However, if you change the data during the course of the application, you may need to enable other propagation mechanisms. -Caching a particular item is a direct equivalent of the typical get-if-not-found-then- -proceed-and-put-eventually code blocks found with programmatic cache interaction. +Caching a particular item is a direct equivalent of the typical +get-if-not-found-then-proceed-and-put-eventually code blocks +found with programmatic cache interaction. No locks are applied, and several threads may try to load the same item concurrently. The same applies to eviction. If several threads are trying to update or evict data concurrently, you may use stale data. Certain cache providers offer advanced features @@ -6875,7 +6881,7 @@ method -- if at least one cache is hit, the associated value is returned. NOTE: All the other caches that do not contain the value are also updated, even though the cached method was not actually invoked. -The following example uses `@Cacheable` on the `findBook` method: +The following example uses `@Cacheable` on the `findBook` method with multiple caches: [source,java,indent=0] [subs="verbatim,quotes"] @@ -7028,7 +7034,7 @@ regardless of the content of the annotation. Similarly to `key` and `keyGenerator`, the `cacheManager` and `cacheResolver` parameters are mutually exclusive, and an operation specifying both -results in an exception. as a custom `CacheManager` is ignored by the +results in an exception, as a custom `CacheManager` is ignored by the `CacheResolver` implementation. This is probably not what you expect. ==== @@ -7053,7 +7059,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. @@ -7092,9 +7097,11 @@ want to cache paperback books, as the following example does: <1> Using the `unless` attribute to block hardbacks. -The cache abstraction supports `java.util.Optional`, using its content as the cached value -only if it is present. `#result` always refers to the business entity and never a -supported wrapper, so the previous example can be rewritten as follows: +The cache abstraction supports `java.util.Optional` return types. If an `Optional` value +is _present_, it will be stored in the associated cache. If an `Optional` value is not +present, `null` will be stored in the associated cache. `#result` always refers to the +business entity and never a supported wrapper, so the previous example can be rewritten +as follows: [source,java,indent=0] [subs="verbatim,quotes"] @@ -7103,8 +7110,8 @@ supported wrapper, so the previous example can be rewritten as follows: public Optional findBook(String name) ---- -Note that `result` still refers to `Book` and not `Optional`. As it might be `null`, we -should use the safe navigation operator. +Note that `#result` still refers to `Book` and not `Optional`. Since it might be +`null`, we use SpEL's <>. [[cache-spel-context]] ===== Available Caching SpEL Evaluation Context @@ -7214,7 +7221,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. @@ -7275,7 +7281,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. @@ -7418,13 +7423,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 @@ -7499,7 +7502,7 @@ up its declaration at runtime and understands its meaning. Note that, as mention === JCache (JSR-107) Annotations Since version 4.1, Spring's caching abstraction fully supports the JCache standard -annotations: `@CacheResult`, `@CachePut`, `@CacheRemove`, and `@CacheRemoveAll` +(JSR-107) annotations: `@CacheResult`, `@CachePut`, `@CacheRemove`, and `@CacheRemoveAll` as well as the `@CacheDefaults`, `@CacheKey`, and `@CacheValue` companions. You can use these annotations even without migrating your cache store to JSR-107. The internal implementation uses Spring's caching abstraction and provides default @@ -7513,8 +7516,8 @@ you can switch to these standard annotations without changing your cache storage ==== Feature Summary For those who are familiar with Spring's caching annotations, the following table -describes the main differences between the Spring annotations and the JSR-107 -counterpart: +describes the main differences between the Spring annotations and their JSR-107 +counterparts: .Spring vs. JSR-107 caching annotations [cols="1,1,3"] @@ -7565,7 +7568,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. @@ -7609,16 +7611,15 @@ invoking the method again: ==== Enabling JSR-107 Support -You need do nothing specific to enable the JSR-107 support alongside Spring's -declarative annotation support. Both `@EnableCaching` and the -`cache:annotation-driven` element automatically enable the JCache support -if both the JSR-107 API and the `spring-context-support` module are present -in the classpath. +You do not need to do anything specific to enable the JSR-107 support alongside Spring's +declarative annotation support. Both `@EnableCaching` and the `cache:annotation-driven` +XML element automatically enable the JCache support if both the JSR-107 API and the +`spring-context-support` module are present in the classpath. -NOTE: Depending on your use case, the choice is basically yours. You can even -mix and match services by using the JSR-107 API on some and using Spring's own -annotations on others. However, if these services impact the same caches, -you should use a consistent and identical key generation implementation. +NOTE: Depending on your use case, the choice is basically yours. You can even mix and +match services by using the JSR-107 API on some and using Spring's own annotations on +others. However, if these services impact the same caches, you should use a consistent +and identical key generation implementation. @@ -7848,15 +7849,13 @@ invoked every time. === Plugging-in Different Back-end Caches Clearly, there are plenty of caching products out there that you can use as a backing -store. To plug them in, you need to provide a `CacheManager` and a `Cache` implementation, -since, unfortunately, there is no available standard that we can use instead. -This may sound harder than it is, since, in practice, the classes tend to be simple -https://en.wikipedia.org/wiki/Adapter_pattern[adapters] that map the caching abstraction -framework on top of the storage API, as the `ehcache` classes do. Most `CacheManager` -classes can use the classes in the `org.springframework.cache.support` package -(such as `AbstractCacheManager` which takes care of the boiler-plate code, -leaving only the actual mapping to be completed). We hope that, in time, the libraries -that provide integration with Spring can fill in this small configuration gap. +store. For those that do not support JSR-107 you need to provide a `CacheManager` and a +`Cache` implementation. This may sound harder than it is, since, in practice, the classes +tend to be simple https://en.wikipedia.org/wiki/Adapter_pattern[adapters] that map the +caching abstraction framework on top of the storage API, as the `ehcache` classes do. +Most `CacheManager` classes can use the classes in the +`org.springframework.cache.support` package (such as `AbstractCacheManager` which takes +care of the boiler-plate code, leaving only the actual mapping to be completed).