-
Notifications
You must be signed in to change notification settings - Fork 688
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
SONARJAVA-4681: Implement rule S6832: Non-singleton Spring beans shou…
…ld not be injected in a Singleton bean (#4511)
- Loading branch information
Showing
11 changed files
with
678 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
220 changes: 220 additions & 0 deletions
220
...test-sources/src/main/java/checks/spring/NonSingletonAutowiredInSingletonCheckSample.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,220 @@ | ||
package checks.spring; | ||
|
||
import javax.inject.Inject; | ||
import org.springframework.beans.factory.annotation.Autowired; | ||
import org.springframework.context.annotation.Scope; | ||
import org.springframework.context.annotation.ScopedProxyMode; | ||
import org.springframework.stereotype.Component; | ||
import org.springframework.web.context.WebApplicationContext; | ||
|
||
import static org.springframework.context.annotation.ScopedProxyMode.TARGET_CLASS; | ||
|
||
public class NonSingletonAutowiredInSingletonCheckSample { | ||
|
||
private static final String SINGLETON_SCOPE = "singleton"; | ||
private static final String PROTOTYPE_SCOPE = "prototype"; | ||
private static final String CUSTOM_SCOPE = "custom"; | ||
|
||
@Component | ||
@Scope(value = WebApplicationContext.SCOPE_REQUEST, proxyMode = TARGET_CLASS) | ||
public class RequestBean1 { } | ||
|
||
@Scope("prototype") | ||
public class PrototypeBean1 { } | ||
|
||
@Scope(value = "prototype") | ||
public class PrototypeBean2 { } | ||
|
||
|
||
@Scope(value = PROTOTYPE_SCOPE, scopeName = "prototype", proxyMode = ScopedProxyMode.TARGET_CLASS) | ||
public class PrototypeBean3 { } | ||
|
||
|
||
public class SingletonBean { | ||
@Autowired | ||
private RequestBean1 requestBean1; // Noncompliant, [[sc=13;ec=25]] {{Don't auto-wire this non-Singleton bean into a Singleton bean (autowired field).}} | ||
@Autowired | ||
private PrototypeBean1 prototypeBean1; // Noncompliant | ||
@Autowired | ||
private PrototypeBean2 prototypeBean2; // Noncompliant | ||
@Autowired | ||
private PrototypeBean3 prototypeBean3; // Noncompliant | ||
|
||
@Autowired // Noncompliant@+1 | ||
public SingletonBean(RequestBean1 requestBean1) { // Noncompliant, [[sc=26;ec=38]] {{Don't auto-wire this non-Singleton bean into a Singleton bean (autowired constructor).}} | ||
} | ||
|
||
@Autowired // Noncompliant@+1 | ||
public SingletonBean(PrototypeBean2 prototypeBean2) { // Noncompliant | ||
} | ||
|
||
@Autowired | ||
public SingletonBean(RequestBean1 requestBean1, // Noncompliant | ||
PrototypeBean1 prototypeBean1, // Noncompliant | ||
PrototypeBean2 prototypeBean2, // Noncompliant | ||
PrototypeBean3 prototypeBean3) { // Noncompliant | ||
} | ||
|
||
@Autowired | ||
public void setRequestBean1(RequestBean1 requestBean1) { // Noncompliant, [[sc=33;ec=45]] {{Don't auto-wire this non-Singleton bean into a Singleton bean (autowired setter method).}} | ||
this.requestBean1 = requestBean1; | ||
} | ||
|
||
public void setPrototypeBean1(@Autowired PrototypeBean1 prototypeBean1) { // Noncompliant, [[sc=46;ec=60]] {{Don't auto-wire this non-Singleton bean into a Singleton bean (autowired parameter).}} | ||
this.prototypeBean1 = prototypeBean1; | ||
} | ||
|
||
@Autowired | ||
private void setPrototypeBean2(@Autowired PrototypeBean2 prototypeBean2) { // Compliant | ||
this.prototypeBean2 = prototypeBean2; | ||
} | ||
|
||
public void method(@Autowired RequestBean1 requestBean1) { // Compliant, not a setter or constructor | ||
// ... | ||
} | ||
} | ||
|
||
@Scope(value = "singleton") | ||
public class SingletonBean2 { | ||
@Autowired | ||
private SingletonBean singletonBean; // Compliant, since scope is non-Singleton | ||
@Autowired | ||
private RequestBean1 requestBean1; // Noncompliant | ||
@Autowired | ||
private PrototypeBean1 prototypeBean1; // Noncompliant | ||
|
||
@Autowired | ||
private SingletonBean2(@Autowired SingletonBean singletonBean) {// Compliant, since scope is non-Singleton | ||
this.singletonBean = singletonBean; | ||
} | ||
|
||
@Autowired // Noncompliant@+1 | ||
public SingletonBean2(RequestBean1 requestBean1) { // Noncompliant | ||
this.requestBean1 = requestBean1; | ||
} | ||
} | ||
|
||
@Scope(scopeName = "singleton") | ||
public class SingletonBean3 { | ||
@Autowired | ||
private SingletonBean singletonBean; // Compliant, since scope is non-Singleton | ||
@Autowired | ||
private RequestBean1 requestBean1; // Noncompliant | ||
@Autowired | ||
private PrototypeBean1 prototypeBean1; // Noncompliant | ||
|
||
// Noncompliant@+2 Autowired constructor | ||
@Autowired // Noncompliant@+1 Autowired constructor parameter | ||
public SingletonBean3(@Autowired RequestBean1 requestBean1) { // Noncompliant, single parameter constructor | ||
} | ||
} | ||
|
||
@Scope(proxyMode = TARGET_CLASS) | ||
public class SingletonBean4 { | ||
@Autowired | ||
private SingletonBean singletonBean; // Compliant, since scope is non-Singleton | ||
@Autowired | ||
private RequestBean1 requestBean1; // Noncompliant | ||
@Autowired | ||
private PrototypeBean1 prototypeBean1; // Noncompliant | ||
} | ||
|
||
@Scope(value = SINGLETON_SCOPE, scopeName = "singleton") | ||
public class SingletonBean5 { | ||
@Autowired | ||
private SingletonBean singletonBean; // Compliant, since scope is non-Singleton | ||
@Autowired | ||
private RequestBean1 requestBean1; // Noncompliant | ||
@Autowired | ||
private PrototypeBean1 prototypeBean1; // Noncompliant | ||
} | ||
|
||
@Scope("singleton") | ||
public class SingletonBean6 { | ||
@Inject | ||
private SingletonBean5 singletonBean5; // Compliant, since scope is non-Singleton | ||
@Inject | ||
private RequestBean1 requestBean1; // Noncompliant | ||
private PrototypeBean1 prototypeBean1; | ||
private PrototypeBean2 prototypeBean2; | ||
|
||
public SingletonBean6(PrototypeBean1 prototypeBean1) { // Noncompliant | ||
this.prototypeBean1 = prototypeBean1; | ||
} | ||
|
||
@Inject | ||
public SingletonBean6(PrototypeBean1 prototypeBean1, // Noncompliant | ||
PrototypeBean2 prototypeBean2) { // Noncompliant | ||
this.prototypeBean1 = prototypeBean1; | ||
this.prototypeBean2 = prototypeBean2; | ||
} | ||
|
||
@Inject | ||
public void setPrototypeBean2(PrototypeBean2 prototypeBean2) { // Noncompliant | ||
this.prototypeBean2 = prototypeBean2; | ||
} | ||
} | ||
|
||
public class SingletonBean7 { | ||
@jakarta.inject.Inject | ||
private SingletonBean5 singletonBean5; // Compliant, since scope is non-Singleton | ||
@jakarta.inject.Inject | ||
private RequestBean1 requestBean1; // Noncompliant | ||
private PrototypeBean1 prototypeBean1; | ||
private PrototypeBean2 prototypeBean2; | ||
|
||
public SingletonBean7(PrototypeBean1 prototypeBean1) { // Noncompliant | ||
this.prototypeBean1 = prototypeBean1; | ||
} | ||
|
||
@jakarta.inject.Inject | ||
public SingletonBean7(PrototypeBean1 prototypeBean1, // Noncompliant | ||
PrototypeBean2 prototypeBean2) { // Noncompliant | ||
this.prototypeBean1 = prototypeBean1; | ||
this.prototypeBean2 = prototypeBean2; | ||
} | ||
|
||
@jakarta.inject.Inject | ||
public void setPrototypeBean2(PrototypeBean2 prototypeBean2) { // Noncompliant | ||
this.prototypeBean2 = prototypeBean2; | ||
} | ||
} | ||
|
||
@Scope(value = CUSTOM_SCOPE, scopeName = "custom", proxyMode = TARGET_CLASS) | ||
public class CustomBean { | ||
@Autowired | ||
private SingletonBean singletonBean; // Compliant, since scope is non-Singleton | ||
@Autowired | ||
private SingletonBean5 singletonBean5; // Compliant, since scope is non-Singleton | ||
@Autowired | ||
public PrototypeBean1 prototypeBean1; // Compliant, since scope is non-Singleton | ||
} | ||
|
||
public class SingletonBean11 { | ||
@Autowired | ||
private CustomBean customBean; // Noncompliant | ||
|
||
@Autowired // Noncompliant@+1 | ||
public SingletonBean11(CustomBean customBean) { // Noncompliant | ||
this.customBean = customBean; | ||
} | ||
|
||
@Autowired | ||
public void setCustomBean(CustomBean customBean) { // Noncompliant | ||
this.customBean = customBean; | ||
} | ||
|
||
@Autowired | ||
public void method(CustomBean customBean) { // Compliant, not a setter or constructor | ||
// ... | ||
} | ||
|
||
public void method2(@Autowired CustomBean customBean) { // Compliant, not a setter or constructor | ||
// ... | ||
} | ||
} | ||
|
||
@Autowired | ||
public @interface customAutowired { | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.