Modify rule S7180: improve description (#4777)
This commit is contained in:
parent
5b2ef9ae42
commit
6507098d55
@ -1,11 +1,17 @@
|
||||
== Why is this an issue?
|
||||
|
||||
Annotating interfaces or interface methods with ``++@Cache*++`` annotations is not recommended by the official Spring documentation.
|
||||
If you use the weaving-based aspect (mode="aspectj"), the ``++@Cache*++`` annotations will be ignored, and no caching proxy will be created.
|
||||
Annotating interfaces or interface methods with ``++@Cache*++`` annotations is not recommended by the official Spring documentation:
|
||||
----
|
||||
Spring recommends that you only annotate concrete classes (and methods of concrete classes) with the @Cache* annotations, as opposed to annotating interfaces. You certainly can place an @Cache* 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.
|
||||
----
|
||||
|
||||
Also, when a method is annotated as cacheable inside an interface, if two different implementations of that method exist, the first one to be invoked will populate the cache.
|
||||
Subsequent calls will always return the cached value, even if it's the other implementation being called.
|
||||
|
||||
=== What is the potential impact?
|
||||
|
||||
* *Confusing Code*: Developers may mistakenly believe that caching is in effect, leading to confusion and incorrect assumptions about application performance.
|
||||
* *Unreliable Code*: Annotating interface methods as ``++@Cacheable++`` hides the cache name from the implementing classes, making it hard to detect where a conflict of names might occur, causing unexpected results at runtime.
|
||||
|
||||
This rule raises an issue when an interface or an interface method is annotated with a ``++@Cache*++`` annotation.
|
||||
|
||||
@ -26,6 +32,32 @@ public interface ExampleService {
|
||||
}
|
||||
----
|
||||
|
||||
In the following example, if our application has two different rest APIs to query the most popular animal in two different zoos, the first zoo to be queried will populate the cache.
|
||||
|
||||
Calls to a different API to query the other zoo will produce the same cached output, invalidating our application's business logic.
|
||||
|
||||
[source,java,diff-id=2,diff-type=noncompliant]
|
||||
----
|
||||
public interface Zoo {
|
||||
@Cacheable("popAnimal") //non compliant, interface method is annotated with @Cacheable
|
||||
Animal getMostPopularAnimal();
|
||||
}
|
||||
|
||||
public class SanDiegoZoo implements Zoo {
|
||||
@Override
|
||||
public Animal getMostPopularAnimal() {
|
||||
return new Lion();
|
||||
}
|
||||
}
|
||||
|
||||
public class RomeBioparc implements Zoo {
|
||||
@Override
|
||||
public Animal getMostPopularAnimal() {
|
||||
return new Pantegana();
|
||||
}
|
||||
}
|
||||
----
|
||||
|
||||
==== Compliant solution
|
||||
|
||||
[source,java,diff-id=1,diff-type=compliant]
|
||||
@ -41,6 +73,31 @@ public class ExampleServiceImpl implements ExampleService {
|
||||
}
|
||||
----
|
||||
|
||||
With the following solution, we are granted that the two implementations will have separate caches.
|
||||
|
||||
[source,java,diff-id=2,diff-type=compliant]
|
||||
----
|
||||
public interface Zoo {
|
||||
Animal getMostPopularAnimal();
|
||||
}
|
||||
|
||||
public class SanDiegoZoo implements Zoo {
|
||||
@Override
|
||||
@Cacheable("sanDiegoPopAnimal")
|
||||
public Animal getMostPopularAnimal() {
|
||||
return new Lion();
|
||||
}
|
||||
}
|
||||
|
||||
public class RomeBioparc implements Zoo {
|
||||
@Override
|
||||
@Cacheable("romePopAnimal")
|
||||
public Animal getMostPopularAnimal() {
|
||||
return new Pantegana();
|
||||
}
|
||||
}
|
||||
----
|
||||
|
||||
== Resources
|
||||
=== Documentation
|
||||
* Spring - https://docs.spring.io/spring-framework/reference/integration/cache/annotations.html#cache-annotation-enable[Declarative Annotation-based Caching]
|
||||
|
Loading…
x
Reference in New Issue
Block a user