mirror of
https://github.com/spring-projects/spring-framework
synced 2026-06-08 17:33:33 +00:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| d045d40702 |
+1
-1
@@ -29,7 +29,7 @@ spring-test/test-output/
|
||||
|
||||
# Maven artifacts
|
||||
pom.xml
|
||||
/target/
|
||||
target/
|
||||
|
||||
# Eclipse artifacts, including WTP generated manifests
|
||||
bin
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# <img src="framework-docs/src/docs/spring-framework.png" width="80" height="80"> Spring Framework [](https://ci.spring.io/teams/spring-framework/pipelines/spring-framework-6.0.x?groups=Build") [](https://ge.spring.io/scans?search.rootProjectNames=spring)
|
||||
# <img src="framework-docs/src/docs/spring-framework.png" width="80" height="80"> Spring Framework [](https://ci.spring.io/teams/spring-framework/pipelines/spring-framework-5.3.x?groups=Build") [](https://ge.spring.io/scans?search.rootProjectNames=spring)
|
||||
|
||||
This is the home of the Spring Framework: the foundation for all [Spring projects](https://spring.io/projects). Collectively the Spring Framework and the family of Spring projects are often referred to simply as "Spring".
|
||||
|
||||
|
||||
@@ -1,10 +1,5 @@
|
||||
# Security Policy
|
||||
|
||||
## JAR signing
|
||||
|
||||
Spring Framework JARs released on Maven Central are signed.
|
||||
You'll find more information about the key here: https://spring.io/GPG-KEY-spring.txt
|
||||
|
||||
## Supported Versions
|
||||
|
||||
Please see the
|
||||
|
||||
+5
-3
@@ -78,7 +78,7 @@ configure([rootProject] + javaProjects) { project ->
|
||||
}
|
||||
|
||||
checkstyle {
|
||||
toolVersion = "10.9.1"
|
||||
toolVersion = "10.7.0"
|
||||
configDirectory.set(rootProject.file("src/checkstyle"))
|
||||
}
|
||||
|
||||
@@ -127,8 +127,10 @@ configure([rootProject] + javaProjects) { project ->
|
||||
"https://hc.apache.org/httpcomponents-client-5.2.x/current/httpclient5/apidocs/",
|
||||
"https://projectreactor.io/docs/test/release/api/",
|
||||
"https://junit.org/junit4/javadoc/4.13.2/",
|
||||
// TODO Uncomment link to JUnit 5 docs once we execute Gradle with Java 18+.
|
||||
// See https://github.com/spring-projects/spring-framework/issues/27497
|
||||
// TODO Uncomment link to JUnit 5 docs once we have sorted out
|
||||
// the following warning in the build.
|
||||
//
|
||||
// warning: The code being documented uses packages in the unnamed module, but the packages defined in https://junit.org/junit5/docs/5.9.2/api/ are in named modules.
|
||||
//
|
||||
// "https://junit.org/junit5/docs/5.9.2/api/",
|
||||
"https://www.reactive-streams.org/reactive-streams-1.0.3-javadoc/",
|
||||
|
||||
@@ -28,7 +28,7 @@ javadoc {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
asciidoctorExtensions "io.spring.asciidoctor.backends:spring-asciidoctor-backends:0.0.5"
|
||||
asciidoctorExtensions "io.spring.asciidoctor.backends:spring-asciidoctor-backends:0.0.4"
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
aot=core.aot
|
||||
aot-basics=core.aot.basics
|
||||
aot-refresh=core.aot.refresh
|
||||
aot-bean-factory-initialization-contributions=core.aot.bean-factory-initialization-contributions
|
||||
aot-bean-registration-contributions=core.aot.bean-registration-contributions
|
||||
aot-hints=core.aot.hints
|
||||
aot-hints-import-runtime-hints=core.aot.hints.import-runtime-hints
|
||||
aot-hints-reflective=core.aot.hints.reflective
|
||||
aot-hints-register-reflection-for-binding=core.aot.hints.register-reflection-for-binding
|
||||
@@ -1,11 +1,6 @@
|
||||
// Spring Portfolio
|
||||
:docs-site: https://docs.spring.io
|
||||
:docs-spring-boot: {docs-site}/spring-boot/docs/current/reference
|
||||
:docs-spring-gemfire: {docs-site}/spring-gemfire/docs/current/reference
|
||||
:docs-spring-security: {docs-site}/spring-security/reference
|
||||
// spring-asciidoctor-backends Settings
|
||||
:chomp: default headers packages
|
||||
:fold: all
|
||||
:docs-site: https://docs.spring.io
|
||||
// Spring Framework
|
||||
:docs-spring-framework: {docs-site}/spring-framework/docs/{spring-version}
|
||||
:api-spring-framework: {docs-spring-framework}/javadoc-api/org/springframework
|
||||
@@ -13,6 +8,10 @@
|
||||
:docs-kotlin: {docdir}/../../main/kotlin/org/springframework/docs
|
||||
:docs-resources: {docdir}/../../main/resources
|
||||
:spring-framework-main-code: https://github.com/spring-projects/spring-framework/tree/main
|
||||
// Spring portfolio Links
|
||||
:docs-spring-boot: {docs-site}/spring-boot/docs/current/reference
|
||||
:docs-spring-gemfire: {docs-site}/spring-gemfire/docs/current/reference
|
||||
:docs-spring-security: {docs-site}/spring-security/reference
|
||||
// Third-party Links
|
||||
:docs-graalvm: https://www.graalvm.org/22.3/reference-manual
|
||||
:gh-rsocket: https://github.com/rsocket
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -16,9 +16,9 @@ Applying such optimizations early implies the following restrictions:
|
||||
* The classpath is fixed and fully defined at build time.
|
||||
* The beans defined in your application cannot change at runtime, meaning:
|
||||
** `@Profile`, in particular profile-specific configuration needs to be chosen at build time.
|
||||
** `Environment` properties that impact the presence of a bean (`@Conditional`) are only considered at build time.
|
||||
* Bean definitions with instance suppliers (lambdas or method references) cannot be transformed ahead-of-time (see related https://github.com/spring-projects/spring-framework/issues/29555[spring-framework#29555] issue).
|
||||
* The return type of methods annotated with `@Bean` should be the most specific type possible (typically the concrete class, not an interface) in order to support proper type inference without invoking the corresponding `@Bean` method at build time.
|
||||
** Environment properties that impact the presence of a bean (`@Conditional`) are only considered at build time.
|
||||
* Bean definitions with instance suppliers (lambdas or method references) can't be transformed Ahead of Time (see https://github.com/spring-projects/spring-framework/issues/29555[spring-framework#29555] related issue)
|
||||
* The return type of methods annotated with `@Bean` should be the most specific one in order to allow proper hint inference (typically the concrete class, not an interface).
|
||||
|
||||
When these restrictions are in place, it becomes possible to perform ahead-of-time processing at build time and generate additional assets.
|
||||
A Spring AOT processed application typically generates:
|
||||
|
||||
@@ -123,7 +123,7 @@ easy to do in Spring. You do not actually have to do anything or know anything a
|
||||
the Spring internals (or even about classes such as the `FieldRetrievingFactoryBean`).
|
||||
The following example enumeration shows how easy injecting an enum value is:
|
||||
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary",chomp="-packages"]
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
|
||||
.Java
|
||||
----
|
||||
package jakarta.persistence;
|
||||
@@ -134,7 +134,7 @@ The following example enumeration shows how easy injecting an enum value is:
|
||||
EXTENDED
|
||||
}
|
||||
----
|
||||
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary",chomp="-packages"]
|
||||
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
|
||||
.Kotlin
|
||||
----
|
||||
package jakarta.persistence
|
||||
@@ -148,7 +148,7 @@ The following example enumeration shows how easy injecting an enum value is:
|
||||
|
||||
Now consider the following setter of type `PersistenceContextType` and the corresponding bean definition:
|
||||
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary",chomp="-packages"]
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
|
||||
.Java
|
||||
----
|
||||
package example;
|
||||
@@ -162,7 +162,7 @@ Now consider the following setter of type `PersistenceContextType` and the corre
|
||||
}
|
||||
}
|
||||
----
|
||||
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary",chomp="-packages"]
|
||||
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
|
||||
.Kotlin
|
||||
----
|
||||
package example
|
||||
@@ -796,7 +796,7 @@ element results in a single `SimpleDateFormat` bean definition). Spring features
|
||||
number of convenience classes that support this scenario. In the following example, we
|
||||
use the `NamespaceHandlerSupport` class:
|
||||
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary",chomp="-packages"]
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
|
||||
.Java
|
||||
----
|
||||
package org.springframework.samples.xml;
|
||||
@@ -810,7 +810,7 @@ use the `NamespaceHandlerSupport` class:
|
||||
}
|
||||
}
|
||||
----
|
||||
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary",chomp="-packages"]
|
||||
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
|
||||
.Kotlin
|
||||
----
|
||||
package org.springframework.samples.xml
|
||||
@@ -847,7 +847,7 @@ responsible for parsing one distinct top-level XML element defined in the schema
|
||||
the parser, we' have access to the XML element (and thus to its subelements, too) so that
|
||||
we can parse our custom XML content, as you can see in the following example:
|
||||
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary",chomp="-packages"]
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
|
||||
.Java
|
||||
----
|
||||
package org.springframework.samples.xml;
|
||||
@@ -884,7 +884,7 @@ the basic grunt work of creating a single `BeanDefinition`.
|
||||
<2> We supply the `AbstractSingleBeanDefinitionParser` superclass with the type that our
|
||||
single `BeanDefinition` represents.
|
||||
|
||||
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary",chomp="-packages"]
|
||||
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
|
||||
.Kotlin
|
||||
----
|
||||
package org.springframework.samples.xml
|
||||
@@ -1056,7 +1056,7 @@ setter method for the `components` property. This makes it hard (or rather impos
|
||||
to configure a bean definition for the `Component` class by using setter injection.
|
||||
The following listing shows the `Component` class:
|
||||
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary",chomp="-packages"]
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
|
||||
.Java
|
||||
----
|
||||
package com.foo;
|
||||
@@ -1087,7 +1087,7 @@ The following listing shows the `Component` class:
|
||||
}
|
||||
}
|
||||
----
|
||||
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary",chomp="-packages"]
|
||||
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
|
||||
.Kotlin
|
||||
----
|
||||
package com.foo
|
||||
@@ -1114,7 +1114,7 @@ The typical solution to this issue is to create a custom `FactoryBean` that expo
|
||||
setter property for the `components` property. The following listing shows such a custom
|
||||
`FactoryBean`:
|
||||
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary",chomp="-packages"]
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
|
||||
.Java
|
||||
----
|
||||
package com.foo;
|
||||
@@ -1154,7 +1154,7 @@ setter property for the `components` property. The following listing shows such
|
||||
}
|
||||
}
|
||||
----
|
||||
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary",chomp="-packages"]
|
||||
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
|
||||
.Kotlin
|
||||
----
|
||||
package com.foo
|
||||
@@ -1226,7 +1226,7 @@ listing shows:
|
||||
Again following <<core.appendix.xsd-custom-introduction, the process described earlier>>,
|
||||
we then create a custom `NamespaceHandler`:
|
||||
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary",chomp="-packages"]
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
|
||||
.Java
|
||||
----
|
||||
package com.foo;
|
||||
@@ -1240,7 +1240,7 @@ we then create a custom `NamespaceHandler`:
|
||||
}
|
||||
}
|
||||
----
|
||||
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary",chomp="-packages"]
|
||||
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
|
||||
.Kotlin
|
||||
----
|
||||
package com.foo
|
||||
@@ -1259,7 +1259,7 @@ Next up is the custom `BeanDefinitionParser`. Remember that we are creating
|
||||
a `BeanDefinition` that describes a `ComponentFactoryBean`. The following
|
||||
listing shows our custom `BeanDefinitionParser` implementation:
|
||||
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary",chomp="-packages"]
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
|
||||
.Java
|
||||
----
|
||||
package com.foo;
|
||||
@@ -1308,7 +1308,7 @@ listing shows our custom `BeanDefinitionParser` implementation:
|
||||
}
|
||||
}
|
||||
----
|
||||
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary",chomp="-packages"]
|
||||
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
|
||||
.Kotlin
|
||||
----
|
||||
package com.foo
|
||||
@@ -1403,14 +1403,14 @@ the named JCache for us. We can also modify the existing `BeanDefinition` for th
|
||||
`'checkingAccountService'` so that it has a dependency on this new
|
||||
JCache-initializing `BeanDefinition`. The following listing shows our `JCacheInitializer`:
|
||||
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary",chomp="-packages"]
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
|
||||
.Java
|
||||
----
|
||||
package com.foo;
|
||||
|
||||
public class JCacheInitializer {
|
||||
|
||||
private final String name;
|
||||
private String name;
|
||||
|
||||
public JCacheInitializer(String name) {
|
||||
this.name = name;
|
||||
@@ -1421,7 +1421,7 @@ JCache-initializing `BeanDefinition`. The following listing shows our `JCacheIni
|
||||
}
|
||||
}
|
||||
----
|
||||
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary",chomp="-packages"]
|
||||
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
|
||||
.Kotlin
|
||||
----
|
||||
package com.foo
|
||||
@@ -1453,7 +1453,7 @@ the XSD schema that describes the custom attribute, as follows:
|
||||
|
||||
Next, we need to create the associated `NamespaceHandler`, as follows:
|
||||
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary",chomp="-packages"]
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
|
||||
.Java
|
||||
----
|
||||
package com.foo;
|
||||
@@ -1469,7 +1469,7 @@ Next, we need to create the associated `NamespaceHandler`, as follows:
|
||||
|
||||
}
|
||||
----
|
||||
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary",chomp="-packages"]
|
||||
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
|
||||
.Kotlin
|
||||
----
|
||||
package com.foo
|
||||
@@ -1490,7 +1490,7 @@ Next, we need to create the parser. Note that, in this case, because we are goin
|
||||
an XML attribute, we write a `BeanDefinitionDecorator` rather than a `BeanDefinitionParser`.
|
||||
The following listing shows our `BeanDefinitionDecorator` implementation:
|
||||
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary",chomp="-packages"]
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
|
||||
.Java
|
||||
----
|
||||
package com.foo;
|
||||
@@ -1544,7 +1544,7 @@ The following listing shows our `BeanDefinitionDecorator` implementation:
|
||||
}
|
||||
}
|
||||
----
|
||||
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary",chomp="-packages"]
|
||||
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
|
||||
.Kotlin
|
||||
----
|
||||
package com.foo
|
||||
|
||||
@@ -949,7 +949,7 @@ order in which the constructor arguments are defined in a bean definition is the
|
||||
in which those arguments are supplied to the appropriate constructor when the bean is
|
||||
being instantiated. Consider the following class:
|
||||
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary",chomp="-packages"]
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
|
||||
.Java
|
||||
----
|
||||
package x.y;
|
||||
@@ -961,7 +961,7 @@ being instantiated. Consider the following class:
|
||||
}
|
||||
}
|
||||
----
|
||||
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary",chomp="-packages"]
|
||||
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
|
||||
.Kotlin
|
||||
----
|
||||
package x.y
|
||||
@@ -993,7 +993,7 @@ case with the preceding example). When a simple type is used, such as
|
||||
`<value>true</value>`, Spring cannot determine the type of the value, and so cannot match
|
||||
by type without help. Consider the following class:
|
||||
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary",chomp="-packages"]
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
|
||||
.Java
|
||||
----
|
||||
package examples;
|
||||
@@ -1012,7 +1012,7 @@ by type without help. Consider the following class:
|
||||
}
|
||||
}
|
||||
----
|
||||
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary",chomp="-packages"]
|
||||
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
|
||||
.Kotlin
|
||||
----
|
||||
package examples
|
||||
@@ -1077,7 +1077,7 @@ https://download.oracle.com/javase/8/docs/api/java/beans/ConstructorProperties.h
|
||||
JDK annotation to explicitly name your constructor arguments. The sample class would
|
||||
then have to look as follows:
|
||||
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary",chomp="-packages"]
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
|
||||
.Java
|
||||
----
|
||||
package examples;
|
||||
@@ -1093,7 +1093,7 @@ then have to look as follows:
|
||||
}
|
||||
}
|
||||
----
|
||||
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary",chomp="-packages"]
|
||||
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
|
||||
.Kotlin
|
||||
----
|
||||
package examples
|
||||
@@ -2276,9 +2276,10 @@ and by <<beans-factory-client,making a `getBean("B")` call to the container>> as
|
||||
typically new) bean B instance every time bean A needs it. The following example
|
||||
shows this approach:
|
||||
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary",chomp="-packages",fold="none"]
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
|
||||
.Java
|
||||
----
|
||||
// a class that uses a stateful Command-style class to perform some processing
|
||||
package fiona.apple;
|
||||
|
||||
// Spring-API imports
|
||||
@@ -2286,10 +2287,6 @@ shows this approach:
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
|
||||
/**
|
||||
* A class that uses a stateful Command-style class to perform
|
||||
* some processing.
|
||||
*/
|
||||
public class CommandManager implements ApplicationContextAware {
|
||||
|
||||
private ApplicationContext applicationContext;
|
||||
@@ -2313,17 +2310,16 @@ shows this approach:
|
||||
}
|
||||
}
|
||||
----
|
||||
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary",chomp="-packages",fold="none"]
|
||||
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
|
||||
.Kotlin
|
||||
----
|
||||
// a class that uses a stateful Command-style class to perform some processing
|
||||
package fiona.apple
|
||||
|
||||
// Spring-API imports
|
||||
import org.springframework.context.ApplicationContext
|
||||
import org.springframework.context.ApplicationContextAware
|
||||
|
||||
// A class that uses a stateful Command-style class to perform
|
||||
// some processing.
|
||||
class CommandManager : ApplicationContextAware {
|
||||
|
||||
private lateinit var applicationContext: ApplicationContext
|
||||
@@ -2386,7 +2382,7 @@ Spring container dynamically overrides the implementation of the `createCommand(
|
||||
method. The `CommandManager` class does not have any Spring dependencies, as
|
||||
the reworked example shows:
|
||||
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary",chomp="-packages",fold="none"]
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
|
||||
.Java
|
||||
----
|
||||
package fiona.apple;
|
||||
@@ -2407,7 +2403,7 @@ the reworked example shows:
|
||||
protected abstract Command createCommand();
|
||||
}
|
||||
----
|
||||
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary",chomp="-packages",fold="none"]
|
||||
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
|
||||
.Kotlin
|
||||
----
|
||||
package fiona.apple
|
||||
@@ -4218,7 +4214,7 @@ it is created by the container and prints the resulting string to the system con
|
||||
|
||||
The following listing shows the custom `BeanPostProcessor` implementation class definition:
|
||||
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary",chomp="-packages"]
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
|
||||
.Java
|
||||
----
|
||||
package scripting;
|
||||
@@ -4238,11 +4234,9 @@ The following listing shows the custom `BeanPostProcessor` implementation class
|
||||
}
|
||||
}
|
||||
----
|
||||
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary",chomp="-packages"]
|
||||
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
|
||||
.Kotlin
|
||||
----
|
||||
package scripting
|
||||
|
||||
import org.springframework.beans.factory.config.BeanPostProcessor
|
||||
|
||||
class InstantiationTracingBeanPostProcessor : BeanPostProcessor {
|
||||
|
||||
@@ -1978,7 +1978,7 @@ The definition of `TemplateParserContext` follows:
|
||||
|
||||
This section lists the classes used in the examples throughout this chapter.
|
||||
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary",chomp="-packages"]
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
|
||||
.Inventor.Java
|
||||
----
|
||||
package org.spring.samples.spel.inventor;
|
||||
@@ -2051,20 +2051,18 @@ This section lists the classes used in the examples throughout this chapter.
|
||||
}
|
||||
}
|
||||
----
|
||||
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary",chomp="-packages"]
|
||||
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
|
||||
.Inventor.kt
|
||||
----
|
||||
package org.spring.samples.spel.inventor
|
||||
|
||||
class Inventor(
|
||||
var name: String,
|
||||
var nationality: String,
|
||||
var inventions: Array<String>? = null,
|
||||
var birthdate: Date = GregorianCalendar().time,
|
||||
var placeOfBirth: PlaceOfBirth? = null)
|
||||
class Inventor(
|
||||
var name: String,
|
||||
var nationality: String,
|
||||
var inventions: Array<String>? = null,
|
||||
var birthdate: Date = GregorianCalendar().time,
|
||||
var placeOfBirth: PlaceOfBirth? = null)
|
||||
----
|
||||
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary",chomp="-packages"]
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
|
||||
.PlaceOfBirth.java
|
||||
----
|
||||
package org.spring.samples.spel.inventor;
|
||||
@@ -2100,15 +2098,13 @@ This section lists the classes used in the examples throughout this chapter.
|
||||
}
|
||||
}
|
||||
----
|
||||
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary",chomp="-packages"]
|
||||
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
|
||||
.PlaceOfBirth.kt
|
||||
----
|
||||
package org.spring.samples.spel.inventor
|
||||
|
||||
class PlaceOfBirth(var city: String, var country: String? = null) {
|
||||
----
|
||||
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary",chomp="-packages"]
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
|
||||
.Society.java
|
||||
----
|
||||
package org.spring.samples.spel.inventor;
|
||||
@@ -2151,7 +2147,7 @@ This section lists the classes used in the examples throughout this chapter.
|
||||
}
|
||||
}
|
||||
----
|
||||
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary",chomp="-packages"]
|
||||
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
|
||||
.Society.kt
|
||||
----
|
||||
package org.spring.samples.spel.inventor
|
||||
|
||||
@@ -640,7 +640,7 @@ support for additional `PropertyEditor` instances to an `ApplicationContext`.
|
||||
Consider the following example, which defines a user class called `ExoticType` and
|
||||
another class called `DependsOnExoticType`, which needs `ExoticType` set as a property:
|
||||
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary",chomp="-packages"]
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
|
||||
.Java
|
||||
----
|
||||
package example;
|
||||
@@ -663,7 +663,7 @@ another class called `DependsOnExoticType`, which needs `ExoticType` set as a pr
|
||||
}
|
||||
}
|
||||
----
|
||||
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary",chomp="-packages"]
|
||||
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
|
||||
.Kotlin
|
||||
----
|
||||
package example
|
||||
@@ -689,14 +689,12 @@ string, which a `PropertyEditor` converts into an actual
|
||||
|
||||
The `PropertyEditor` implementation could look similar to the following:
|
||||
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary",chomp="-packages"]
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
|
||||
.Java
|
||||
----
|
||||
// converts string representation to ExoticType object
|
||||
package example;
|
||||
|
||||
import java.beans.PropertyEditorSupport;
|
||||
|
||||
// converts string representation to ExoticType object
|
||||
public class ExoticTypeEditor extends PropertyEditorSupport {
|
||||
|
||||
public void setAsText(String text) {
|
||||
@@ -704,14 +702,14 @@ The `PropertyEditor` implementation could look similar to the following:
|
||||
}
|
||||
}
|
||||
----
|
||||
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary",chomp="-packages"]
|
||||
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
|
||||
.Kotlin
|
||||
----
|
||||
// converts string representation to ExoticType object
|
||||
package example
|
||||
|
||||
import java.beans.PropertyEditorSupport
|
||||
|
||||
// converts string representation to ExoticType object
|
||||
class ExoticTypeEditor : PropertyEditorSupport() {
|
||||
|
||||
override fun setAsText(text: String) {
|
||||
@@ -754,7 +752,7 @@ instances for each bean creation attempt.
|
||||
|
||||
The following example shows how to create your own `PropertyEditorRegistrar` implementation:
|
||||
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary",chomp="-packages"]
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
|
||||
.Java
|
||||
----
|
||||
package com.foo.editors.spring;
|
||||
@@ -770,7 +768,7 @@ The following example shows how to create your own `PropertyEditorRegistrar` imp
|
||||
}
|
||||
}
|
||||
----
|
||||
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary",chomp="-packages"]
|
||||
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
|
||||
.Kotlin
|
||||
----
|
||||
package com.foo.editors.spring
|
||||
@@ -878,7 +876,7 @@ where type conversion is needed.
|
||||
The SPI to implement type conversion logic is simple and strongly typed, as the following
|
||||
interface definition shows:
|
||||
|
||||
[source,java,indent=0,subs="verbatim,quotes",chomp="-packages"]
|
||||
[source,java,indent=0,subs="verbatim,quotes"]
|
||||
----
|
||||
package org.springframework.core.convert.converter;
|
||||
|
||||
@@ -903,7 +901,7 @@ Several converter implementations are provided in the `core.convert.support` pac
|
||||
a convenience. These include converters from strings to numbers and other common types.
|
||||
The following listing shows the `StringToInteger` class, which is a typical `Converter` implementation:
|
||||
|
||||
[source,java,indent=0,subs="verbatim,quotes",chomp="-packages"]
|
||||
[source,java,indent=0,subs="verbatim,quotes"]
|
||||
----
|
||||
package org.springframework.core.convert.support;
|
||||
|
||||
@@ -924,7 +922,7 @@ When you need to centralize the conversion logic for an entire class hierarchy
|
||||
(for example, when converting from `String` to `Enum` objects), you can implement
|
||||
`ConverterFactory`, as the following example shows:
|
||||
|
||||
[source,java,indent=0,subs="verbatim,quotes",chomp="-packages"]
|
||||
[source,java,indent=0,subs="verbatim,quotes"]
|
||||
----
|
||||
package org.springframework.core.convert.converter;
|
||||
|
||||
@@ -940,7 +938,7 @@ where T is a subclass of R.
|
||||
|
||||
Consider the `StringToEnumConverterFactory` as an example:
|
||||
|
||||
[source,java,indent=0,subs="verbatim,quotes",chomp="-packages"]
|
||||
[source,java,indent=0,subs="verbatim,quotes"]
|
||||
----
|
||||
package org.springframework.core.convert.support;
|
||||
|
||||
@@ -977,7 +975,7 @@ context that you can use when you implement your conversion logic. Such context
|
||||
type conversion be driven by a field annotation or by generic information declared on a
|
||||
field signature. The following listing shows the interface definition of `GenericConverter`:
|
||||
|
||||
[source,java,indent=0,subs="verbatim,quotes",chomp="-packages"]
|
||||
[source,java,indent=0,subs="verbatim,quotes"]
|
||||
----
|
||||
package org.springframework.core.convert.converter;
|
||||
|
||||
@@ -1041,7 +1039,7 @@ might match only if the target entity type declares a static finder method (for
|
||||
`ConversionService` defines a unified API for executing type conversion logic at
|
||||
runtime. Converters are often run behind the following facade interface:
|
||||
|
||||
[source,java,indent=0,subs="verbatim,quotes",chomp="-packages"]
|
||||
[source,java,indent=0,subs="verbatim,quotes"]
|
||||
----
|
||||
package org.springframework.core.convert;
|
||||
|
||||
@@ -1225,7 +1223,7 @@ provides a unified type conversion API for both SPIs.
|
||||
The `Formatter` SPI to implement field formatting logic is simple and strongly typed. The
|
||||
following listing shows the `Formatter` interface definition:
|
||||
|
||||
[source,java,indent=0,subs="verbatim,quotes",chomp="-packages"]
|
||||
[source,java,indent=0,subs="verbatim,quotes"]
|
||||
----
|
||||
package org.springframework.format;
|
||||
|
||||
@@ -1270,7 +1268,7 @@ a `java.text.DateFormat`.
|
||||
|
||||
The following `DateFormatter` is an example `Formatter` implementation:
|
||||
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary",chomp="-packages"]
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
|
||||
.Java
|
||||
----
|
||||
package org.springframework.format.datetime;
|
||||
@@ -1304,7 +1302,7 @@ The following `DateFormatter` is an example `Formatter` implementation:
|
||||
}
|
||||
}
|
||||
----
|
||||
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary",chomp="-packages"]
|
||||
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
|
||||
.Kotlin
|
||||
----
|
||||
class DateFormatter(private val pattern: String) : Formatter<Date> {
|
||||
@@ -1336,7 +1334,7 @@ Field formatting can be configured by field type or annotation. To bind
|
||||
an annotation to a `Formatter`, implement `AnnotationFormatterFactory`. The following
|
||||
listing shows the definition of the `AnnotationFormatterFactory` interface:
|
||||
|
||||
[source,java,indent=0,subs="verbatim,quotes",chomp="-packages"]
|
||||
[source,java,indent=0,subs="verbatim,quotes"]
|
||||
----
|
||||
package org.springframework.format;
|
||||
|
||||
@@ -1352,14 +1350,15 @@ listing shows the definition of the `AnnotationFormatterFactory` interface:
|
||||
|
||||
To create an implementation:
|
||||
|
||||
. Parameterize `A` to be the field `annotationType` with which you wish to associate
|
||||
. Parameterize A to be the field `annotationType` with which you wish to associate
|
||||
formatting logic -- for example `org.springframework.format.annotation.DateTimeFormat`.
|
||||
. Have `getFieldTypes()` return the types of fields on which the annotation can be used.
|
||||
. Have `getPrinter()` return a `Printer` to print the value of an annotated field.
|
||||
. Have `getParser()` return a `Parser` to parse a `clientValue` for an annotated field.
|
||||
|
||||
The following example `AnnotationFormatterFactory` implementation binds the `@NumberFormat`
|
||||
annotation to a formatter to let a number style or pattern be specified:
|
||||
annotation to a formatter to let a number style or pattern be
|
||||
specified:
|
||||
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
|
||||
.Java
|
||||
@@ -1367,12 +1366,10 @@ annotation to a formatter to let a number style or pattern be specified:
|
||||
public final class NumberFormatAnnotationFormatterFactory
|
||||
implements AnnotationFormatterFactory<NumberFormat> {
|
||||
|
||||
private static final Set<Class<?>> FIELD_TYPES = Set.of(Short.class,
|
||||
Integer.class, Long.class, Float.class, Double.class,
|
||||
BigDecimal.class, BigInteger.class);
|
||||
|
||||
public Set<Class<?>> getFieldTypes() {
|
||||
return FIELD_TYPES;
|
||||
return new HashSet<Class<?>>(asList(new Class<?>[] {
|
||||
Short.class, Integer.class, Long.class, Float.class,
|
||||
Double.class, BigDecimal.class, BigInteger.class }));
|
||||
}
|
||||
|
||||
public Printer<Number> getPrinter(NumberFormat annotation, Class<?> fieldType) {
|
||||
@@ -1386,13 +1383,16 @@ annotation to a formatter to let a number style or pattern be specified:
|
||||
private Formatter<Number> configureFormatterFrom(NumberFormat annotation, Class<?> fieldType) {
|
||||
if (!annotation.pattern().isEmpty()) {
|
||||
return new NumberStyleFormatter(annotation.pattern());
|
||||
} else {
|
||||
Style style = annotation.style();
|
||||
if (style == Style.PERCENT) {
|
||||
return new PercentStyleFormatter();
|
||||
} else if (style == Style.CURRENCY) {
|
||||
return new CurrencyStyleFormatter();
|
||||
} else {
|
||||
return new NumberStyleFormatter();
|
||||
}
|
||||
}
|
||||
// else
|
||||
return switch(annotation.style()) {
|
||||
case Style.PERCENT -> new PercentStyleFormatter();
|
||||
case Style.CURRENCY -> new CurrencyStyleFormatter();
|
||||
default -> new NumberStyleFormatter();
|
||||
};
|
||||
}
|
||||
}
|
||||
----
|
||||
@@ -1428,7 +1428,7 @@ annotation to a formatter to let a number style or pattern be specified:
|
||||
}
|
||||
----
|
||||
|
||||
To trigger formatting, you can annotate fields with `@NumberFormat`, as the following
|
||||
To trigger formatting, you can annotate fields with @NumberFormat, as the following
|
||||
example shows:
|
||||
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
|
||||
@@ -1490,7 +1490,7 @@ for use with Spring's `DataBinder` and the Spring Expression Language (SpEL).
|
||||
|
||||
The following listing shows the `FormatterRegistry` SPI:
|
||||
|
||||
[source,java,indent=0,subs="verbatim,quotes",chomp="-packages"]
|
||||
[source,java,indent=0,subs="verbatim,quotes"]
|
||||
----
|
||||
package org.springframework.format;
|
||||
|
||||
@@ -1526,7 +1526,7 @@ these rules once, and they are applied whenever formatting is needed.
|
||||
`FormatterRegistrar` is an SPI for registering formatters and converters through the
|
||||
FormatterRegistry. The following listing shows its interface definition:
|
||||
|
||||
[source,java,indent=0,subs="verbatim,quotes",chomp="-packages"]
|
||||
[source,java,indent=0,subs="verbatim,quotes"]
|
||||
----
|
||||
package org.springframework.format;
|
||||
|
||||
@@ -1578,22 +1578,20 @@ For example, the following Java configuration registers a global `yyyyMMdd` form
|
||||
public FormattingConversionService conversionService() {
|
||||
|
||||
// Use the DefaultFormattingConversionService but do not register defaults
|
||||
DefaultFormattingConversionService conversionService =
|
||||
new DefaultFormattingConversionService(false);
|
||||
DefaultFormattingConversionService conversionService = new DefaultFormattingConversionService(false);
|
||||
|
||||
// Ensure @NumberFormat is still supported
|
||||
conversionService.addFormatterForFieldAnnotation(
|
||||
new NumberFormatAnnotationFormatterFactory());
|
||||
conversionService.addFormatterForFieldAnnotation(new NumberFormatAnnotationFormatterFactory());
|
||||
|
||||
// Register JSR-310 date conversion with a specific global format
|
||||
DateTimeFormatterRegistrar dateTimeRegistrar = new DateTimeFormatterRegistrar();
|
||||
dateTimeRegistrar.setDateFormatter(DateTimeFormatter.ofPattern("yyyyMMdd"));
|
||||
dateTimeRegistrar.registerFormatters(conversionService);
|
||||
DateTimeFormatterRegistrar registrar = new DateTimeFormatterRegistrar();
|
||||
registrar.setDateFormatter(DateTimeFormatter.ofPattern("yyyyMMdd"));
|
||||
registrar.registerFormatters(conversionService);
|
||||
|
||||
// Register date conversion with a specific global format
|
||||
DateFormatterRegistrar dateRegistrar = new DateFormatterRegistrar();
|
||||
dateRegistrar.setFormatter(new DateFormatter("yyyyMMdd"));
|
||||
dateRegistrar.registerFormatters(conversionService);
|
||||
DateFormatterRegistrar registrar = new DateFormatterRegistrar();
|
||||
registrar.setFormatter(new DateFormatter("yyyyMMdd"));
|
||||
registrar.registerFormatters(conversionService);
|
||||
|
||||
return conversionService;
|
||||
}
|
||||
@@ -1614,14 +1612,14 @@ For example, the following Java configuration registers a global `yyyyMMdd` form
|
||||
addFormatterForFieldAnnotation(NumberFormatAnnotationFormatterFactory())
|
||||
|
||||
// Register JSR-310 date conversion with a specific global format
|
||||
val dateTimeRegistrar = DateTimeFormatterRegistrar()
|
||||
dateTimeRegistrar.setDateFormatter(DateTimeFormatter.ofPattern("yyyyMMdd"))
|
||||
dateTimeRegistrar.registerFormatters(this)
|
||||
val registrar = DateTimeFormatterRegistrar()
|
||||
registrar.setDateFormatter(DateTimeFormatter.ofPattern("yyyyMMdd"))
|
||||
registrar.registerFormatters(this)
|
||||
|
||||
// Register date conversion with a specific global format
|
||||
val dateRegistrar = DateFormatterRegistrar()
|
||||
dateRegistrar.setFormatter(DateFormatter("yyyyMMdd"))
|
||||
dateRegistrar.registerFormatters(this)
|
||||
val registrar = DateFormatterRegistrar()
|
||||
registrar.setFormatter(DateFormatter("yyyyMMdd"))
|
||||
registrar.registerFormatters(this)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -622,7 +622,7 @@ transactions being created and then rolled back in response to the
|
||||
`UnsupportedOperationException` instance. The following listing shows the `FooService`
|
||||
interface:
|
||||
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary",chomp="-packages"]
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
|
||||
.Java
|
||||
----
|
||||
// the service interface that we want to make transactional
|
||||
@@ -641,7 +641,7 @@ interface:
|
||||
|
||||
}
|
||||
----
|
||||
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary",chomp="-packages"]
|
||||
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
|
||||
.Kotlin
|
||||
----
|
||||
// the service interface that we want to make transactional
|
||||
@@ -662,7 +662,7 @@ interface:
|
||||
|
||||
The following example shows an implementation of the preceding interface:
|
||||
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary",chomp="-packages"]
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
|
||||
.Java
|
||||
----
|
||||
package x.y.service;
|
||||
@@ -690,7 +690,7 @@ The following example shows an implementation of the preceding interface:
|
||||
}
|
||||
}
|
||||
----
|
||||
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary",chomp="-packages"]
|
||||
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
|
||||
.Kotlin
|
||||
----
|
||||
package x.y.service
|
||||
@@ -893,7 +893,7 @@ return type is reactive.
|
||||
The following listing shows a modified version of the previously used `FooService`, but
|
||||
this time the code uses reactive types:
|
||||
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary",chomp="-packages"]
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
|
||||
.Java
|
||||
----
|
||||
// the reactive service interface that we want to make transactional
|
||||
@@ -912,7 +912,7 @@ this time the code uses reactive types:
|
||||
|
||||
}
|
||||
----
|
||||
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary",chomp="-packages"]
|
||||
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
|
||||
.Kotlin
|
||||
----
|
||||
// the reactive service interface that we want to make transactional
|
||||
@@ -933,7 +933,7 @@ this time the code uses reactive types:
|
||||
|
||||
The following example shows an implementation of the preceding interface:
|
||||
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary",chomp="-packages"]
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
|
||||
.Java
|
||||
----
|
||||
package x.y.service;
|
||||
@@ -961,7 +961,7 @@ The following example shows an implementation of the preceding interface:
|
||||
}
|
||||
}
|
||||
----
|
||||
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary",chomp="-packages"]
|
||||
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
|
||||
.Kotlin
|
||||
----
|
||||
package x.y.service
|
||||
@@ -2028,7 +2028,7 @@ configuration and AOP in general.
|
||||
|
||||
The following code shows the simple profiling aspect discussed earlier:
|
||||
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary",chomp="-packages"]
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
|
||||
.Java
|
||||
----
|
||||
package x.y;
|
||||
@@ -2065,15 +2065,9 @@ The following code shows the simple profiling aspect discussed earlier:
|
||||
}
|
||||
}
|
||||
----
|
||||
[source,kotlin,indent=0,subs="verbatim",role="secondary",chomp="-packages"]
|
||||
[source,kotlin,indent=0,subs="verbatim",role="secondary"]
|
||||
.Kotlin
|
||||
----
|
||||
package x.y
|
||||
|
||||
import org.aspectj.lang.ProceedingJoinPoint
|
||||
import org.springframework.util.StopWatch
|
||||
import org.springframework.core.Ordered
|
||||
|
||||
class SimpleProfiler : Ordered {
|
||||
|
||||
private var order: Int = 0
|
||||
|
||||
@@ -582,7 +582,7 @@ a similar contract to the JMS `MessageListener` interface but also gives the mes
|
||||
method access to the JMS `Session` from which the `Message` was received.
|
||||
The following listing shows the definition of the `SessionAwareMessageListener` interface:
|
||||
|
||||
[source,java,indent=0,subs="verbatim,quotes",chomp="-packages"]
|
||||
[source,java,indent=0,subs="verbatim,quotes"]
|
||||
----
|
||||
package org.springframework.jms.listener;
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ The core class in Spring's JMX framework is the `MBeanExporter`. This class is
|
||||
responsible for taking your Spring beans and registering them with a JMX `MBeanServer`.
|
||||
For example, consider the following class:
|
||||
|
||||
[source,java,indent=0,subs="verbatim,quotes",chomp="-packages",chomp="-packages"]
|
||||
[source,java,indent=0,subs="verbatim,quotes"]
|
||||
----
|
||||
package org.springframework.jmx;
|
||||
|
||||
@@ -358,7 +358,7 @@ an operation or an attribute.
|
||||
The following example shows the annotated version of the `JmxTestBean` class that we
|
||||
used in <<jmx-exporting-mbeanserver>>:
|
||||
|
||||
[source,java,indent=0,subs="verbatim,quotes",chomp="-packages"]
|
||||
[source,java,indent=0,subs="verbatim,quotes"]
|
||||
----
|
||||
package org.springframework.jmx;
|
||||
|
||||
@@ -1067,7 +1067,7 @@ example, consider the scenario where one would like to be informed (through a
|
||||
`Notification`) each and every time an attribute of a target MBean changes. The following
|
||||
example writes notifications to the console:
|
||||
|
||||
[source,java,indent=0,subs="verbatim,quotes",chomp="-packages"]
|
||||
[source,java,indent=0,subs="verbatim,quotes"]
|
||||
----
|
||||
package com.example;
|
||||
|
||||
@@ -1317,7 +1317,7 @@ published, and invoke the `sendNotification(Notification)` on the
|
||||
In the following example, exported instances of the `JmxTestBean` publish a
|
||||
`NotificationEvent` every time the `add(int, int)` operation is invoked:
|
||||
|
||||
[source,java,indent=0,subs="verbatim,quotes",chomp="-packages"]
|
||||
[source,java,indent=0,subs="verbatim,quotes"]
|
||||
----
|
||||
package org.springframework.jmx;
|
||||
|
||||
|
||||
@@ -9,30 +9,6 @@ Traces provide a holistic view of an entire system, crossing application boundar
|
||||
Spring Framework instruments various parts of its own codebase to publish observations if an `ObservationRegistry` is configured.
|
||||
You can learn more about {docs-spring-boot}/html/actuator.html#actuator.metrics[configuring the observability infrastructure in Spring Boot].
|
||||
|
||||
|
||||
[[integration.observability.list]]
|
||||
== List of produced Observations
|
||||
|
||||
Spring Framework instruments various features for observability.
|
||||
As outlined <<integration.observability,at the beginning of this section>>, observations can generate timer Metrics and/or Traces depending on the configuration.
|
||||
|
||||
.Observations produced by Spring Framework
|
||||
[%autowidth]
|
||||
|===
|
||||
|Observation name |Description
|
||||
|
||||
|<<integration.observability.http-client,`"http.client.requests"`>>
|
||||
|Time spent for HTTP client exchanges
|
||||
|
||||
|<<integration.observability.http-server,`"http.server.requests"`>>
|
||||
|Processing time for HTTP server exchanges at the Framework level
|
||||
|===
|
||||
|
||||
NOTE: Observations are using Micrometer's official naming convention, but Metrics names will be automatically converted
|
||||
https://micrometer.io/docs/concepts#_naming_meters[to the format preferred by the monitoring system backend]
|
||||
(Prometheus, Atlas, Graphite, InfluxDB...).
|
||||
|
||||
|
||||
[[integration.observability.concepts]]
|
||||
== Micrometer Observation concepts
|
||||
|
||||
|
||||
@@ -816,7 +816,8 @@ its properties from the job data mapped to properties of the job instance. So, i
|
||||
the `ExampleJob` contains a bean property named `timeout`, and the `JobDetail`
|
||||
has it applied automatically:
|
||||
|
||||
[source,java,indent=0,subs="verbatim,quotes",chomp="-packages"]
|
||||
[source,java,indent=0]
|
||||
[subs="verbatim"]
|
||||
----
|
||||
package example;
|
||||
|
||||
@@ -826,7 +827,7 @@ has it applied automatically:
|
||||
|
||||
/**
|
||||
* Setter called after the ExampleJob is instantiated
|
||||
* with the value from the JobDetailFactoryBean.
|
||||
* with the value from the JobDetailFactoryBean (5)
|
||||
*/
|
||||
public void setTimeout(int timeout) {
|
||||
this.timeout = timeout;
|
||||
|
||||
@@ -33,7 +33,7 @@ implement. Note that this interface is defined in plain Java. Dependent objects
|
||||
are injected with a reference to the `Messenger` do not know that the underlying
|
||||
implementation is a Groovy script. The following listing shows the `Messenger` interface:
|
||||
|
||||
[source,java,indent=0,subs="verbatim,quotes",chomp="-packages"]
|
||||
[source,java,indent=0,subs="verbatim,quotes"]
|
||||
----
|
||||
package org.springframework.scripting;
|
||||
|
||||
@@ -45,7 +45,7 @@ implementation is a Groovy script. The following listing shows the `Messenger` i
|
||||
|
||||
The following example defines a class that has a dependency on the `Messenger` interface:
|
||||
|
||||
[source,java,indent=0,subs="verbatim,quotes",chomp="-packages"]
|
||||
[source,java,indent=0,subs="verbatim,quotes"]
|
||||
----
|
||||
package org.springframework.scripting;
|
||||
|
||||
@@ -65,14 +65,15 @@ The following example defines a class that has a dependency on the `Messenger` i
|
||||
|
||||
The following example implements the `Messenger` interface in Groovy:
|
||||
|
||||
[source,groovy,indent=0,subs="verbatim,quotes",chomp="-packages",fold="none"]
|
||||
[source,groovy,indent=0,subs="verbatim,quotes"]
|
||||
----
|
||||
package org.springframework.scripting.groovy
|
||||
// from the file 'Messenger.groovy'
|
||||
package org.springframework.scripting.groovy;
|
||||
|
||||
// Import the Messenger interface (written in Java) that is to be implemented
|
||||
// import the Messenger interface (written in Java) that is to be implemented
|
||||
import org.springframework.scripting.Messenger
|
||||
|
||||
// Define the implementation in Groovy in file 'Messenger.groovy'
|
||||
// define the implementation in Groovy
|
||||
class GroovyMessenger implements Messenger {
|
||||
|
||||
String message
|
||||
@@ -275,7 +276,7 @@ surrounded by quotation marks. The following listing shows the changes that you
|
||||
(the developer) should make to the `Messenger.groovy` source file when the
|
||||
execution of the program is paused:
|
||||
|
||||
[source,groovy,indent=0,subs="verbatim,quotes",chomp="-packages"]
|
||||
[source,groovy,indent=0,subs="verbatim,quotes"]
|
||||
----
|
||||
package org.springframework.scripting
|
||||
|
||||
@@ -330,13 +331,13 @@ feature works:
|
||||
<lang:groovy id="messenger">
|
||||
<lang:inline-script>
|
||||
|
||||
package org.springframework.scripting.groovy
|
||||
package org.springframework.scripting.groovy;
|
||||
|
||||
import org.springframework.scripting.Messenger
|
||||
import org.springframework.scripting.Messenger
|
||||
|
||||
class GroovyMessenger implements Messenger {
|
||||
String message
|
||||
}
|
||||
class GroovyMessenger implements Messenger {
|
||||
String message
|
||||
}
|
||||
|
||||
</lang:inline-script>
|
||||
<lang:property name="message" value="I Can Do The Frug" />
|
||||
@@ -362,13 +363,13 @@ constructors and properties 100% clear, the following mixture of code and config
|
||||
does not work:
|
||||
|
||||
.An approach that cannot work
|
||||
[source,groovy,indent=0,subs="verbatim,quotes",chomp="-packages"]
|
||||
[source,groovy,indent=0,subs="verbatim,quotes"]
|
||||
----
|
||||
package org.springframework.scripting.groovy
|
||||
// from the file 'Messenger.groovy'
|
||||
package org.springframework.scripting.groovy;
|
||||
|
||||
import org.springframework.scripting.Messenger
|
||||
|
||||
// from the file 'Messenger.groovy'
|
||||
class GroovyMessenger implements Messenger {
|
||||
|
||||
GroovyMessenger() {}
|
||||
@@ -419,7 +420,7 @@ If you have read this chapter straight from the top, you have already
|
||||
<<dynamic-language-a-first-example, seen an example>> of a Groovy-dynamic-language-backed
|
||||
bean. Now consider another example (again using an example from the Spring test suite):
|
||||
|
||||
[source,java,indent=0,subs="verbatim,quotes",chomp="-packages"]
|
||||
[source,java,indent=0,subs="verbatim,quotes"]
|
||||
----
|
||||
package org.springframework.scripting;
|
||||
|
||||
@@ -431,11 +432,11 @@ bean. Now consider another example (again using an example from the Spring test
|
||||
|
||||
The following example implements the `Calculator` interface in Groovy:
|
||||
|
||||
[source,groovy,indent=0,subs="verbatim,quotes",chomp="-packages"]
|
||||
[source,groovy,indent=0,subs="verbatim,quotes"]
|
||||
----
|
||||
// from the file 'calculator.groovy'
|
||||
package org.springframework.scripting.groovy
|
||||
|
||||
// from the file 'calculator.groovy'
|
||||
class GroovyCalculator implements Calculator {
|
||||
|
||||
int add(int x, int y) {
|
||||
@@ -456,7 +457,7 @@ The following bean definition uses the calculator defined in Groovy:
|
||||
|
||||
Finally, the following small application exercises the preceding configuration:
|
||||
|
||||
[source,java,indent=0,subs="verbatim,quotes",chomp="-packages"]
|
||||
[source,java,indent=0,subs="verbatim,quotes"]
|
||||
----
|
||||
package org.springframework.scripting;
|
||||
|
||||
@@ -595,7 +596,7 @@ Now we can show a fully working example of using a BeanShell-based bean that imp
|
||||
the `Messenger` interface that was defined earlier in this chapter. We again show the
|
||||
definition of the `Messenger` interface:
|
||||
|
||||
[source,java,indent=0,subs="verbatim,quotes",chomp="-packages"]
|
||||
[source,java,indent=0,subs="verbatim,quotes"]
|
||||
----
|
||||
package org.springframework.scripting;
|
||||
|
||||
@@ -675,8 +676,9 @@ beans, you have to enable the "`refreshable beans`" functionality. See
|
||||
The following example shows an `org.springframework.web.servlet.mvc.Controller` implemented
|
||||
by using the Groovy dynamic language:
|
||||
|
||||
[source,groovy,indent=0,subs="verbatim,quotes",chomp="-packages"]
|
||||
[source,groovy,indent=0,subs="verbatim,quotes"]
|
||||
----
|
||||
// from the file '/WEB-INF/groovy/FortuneController.groovy'
|
||||
package org.springframework.showcase.fortune.web
|
||||
|
||||
import org.springframework.showcase.fortune.service.FortuneService
|
||||
@@ -687,7 +689,6 @@ by using the Groovy dynamic language:
|
||||
import jakarta.servlet.http.HttpServletRequest
|
||||
import jakarta.servlet.http.HttpServletResponse
|
||||
|
||||
// from the file '/WEB-INF/groovy/FortuneController.groovy'
|
||||
class FortuneController implements Controller {
|
||||
|
||||
@Property FortuneService fortuneService
|
||||
|
||||
@@ -251,7 +251,7 @@ By default global configuration enables the following:
|
||||
* `GET`, `HEAD`, and `POST` methods.
|
||||
|
||||
`allowedCredentials` is not enabled by default, since that establishes a trust level
|
||||
that exposes sensitive user-specific information (such as cookies and CSRF tokens) and
|
||||
that exposes sensitive user-specific information( such as cookies and CSRF tokens) and
|
||||
should be used only where appropriate. When it is enabled either `allowOrigins` must be
|
||||
set to one or more specific domain (but not the special value `"*"`) or alternatively
|
||||
the `allowOriginPatterns` property may be used to match to a dynamic set of origins.
|
||||
|
||||
@@ -2504,7 +2504,7 @@ reactive type, as the following example shows:
|
||||
----
|
||||
|
||||
Note that use of `@ModelAttribute` is optional -- for example, to set its attributes.
|
||||
By default, any argument that is not a simple value type (as determined by
|
||||
By default, any argument that is not a simple value type( as determined by
|
||||
{api-spring-framework}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty])
|
||||
and is not resolved by any other argument resolver is treated as if it were annotated
|
||||
with `@ModelAttribute`.
|
||||
|
||||
@@ -9,17 +9,17 @@ javaPlatform {
|
||||
dependencies {
|
||||
api(platform("com.fasterxml.jackson:jackson-bom:2.14.2"))
|
||||
api(platform("io.micrometer:micrometer-bom:1.10.4"))
|
||||
api(platform("io.netty:netty-bom:4.1.90.Final"))
|
||||
api(platform("io.netty:netty-bom:4.1.89.Final"))
|
||||
api(platform("io.netty:netty5-bom:5.0.0.Alpha5"))
|
||||
api(platform("io.projectreactor:reactor-bom:2022.0.5"))
|
||||
api(platform("io.projectreactor:reactor-bom:2022.0.3"))
|
||||
api(platform("io.rsocket:rsocket-bom:1.1.3"))
|
||||
api(platform("org.apache.groovy:groovy-bom:4.0.8"))
|
||||
api(platform("org.apache.logging.log4j:log4j-bom:2.20.0"))
|
||||
api(platform("org.eclipse.jetty:jetty-bom:11.0.14"))
|
||||
api(platform("org.apache.logging.log4j:log4j-bom:2.19.0"))
|
||||
api(platform("org.eclipse.jetty:jetty-bom:11.0.13"))
|
||||
api(platform("org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.6.4"))
|
||||
api(platform("org.jetbrains.kotlinx:kotlinx-serialization-bom:1.4.0"))
|
||||
api(platform("org.junit:junit-bom:5.9.2"))
|
||||
api(platform("org.mockito:mockito-bom:5.2.0"))
|
||||
api(platform("org.mockito:mockito-bom:5.1.1"))
|
||||
|
||||
constraints {
|
||||
api("com.fasterxml:aalto-xml:1.3.1")
|
||||
@@ -55,9 +55,9 @@ dependencies {
|
||||
api("io.r2dbc:r2dbc-spi:1.0.0.RELEASE")
|
||||
api("io.reactivex.rxjava3:rxjava:3.1.5")
|
||||
api("io.smallrye.reactive:mutiny:1.8.0")
|
||||
api("io.undertow:undertow-core:2.3.4.Final")
|
||||
api("io.undertow:undertow-servlet:2.3.4.Final")
|
||||
api("io.undertow:undertow-websockets-jsr:2.3.4.Final")
|
||||
api("io.undertow:undertow-core:2.3.3.Final")
|
||||
api("io.undertow:undertow-servlet:2.3.3.Final")
|
||||
api("io.undertow:undertow-websockets-jsr:2.3.3.Final")
|
||||
api("io.vavr:vavr:0.10.4")
|
||||
api("jakarta.activation:jakarta.activation-api:2.0.1")
|
||||
api("jakarta.annotation:jakarta.annotation-api:2.0.0")
|
||||
@@ -99,10 +99,10 @@ dependencies {
|
||||
api("org.apache.httpcomponents.client5:httpclient5:5.2.1")
|
||||
api("org.apache.httpcomponents.core5:httpcore5-reactive:5.2.1")
|
||||
api("org.apache.poi:poi-ooxml:5.2.3")
|
||||
api("org.apache.tomcat.embed:tomcat-embed-core:10.1.7")
|
||||
api("org.apache.tomcat.embed:tomcat-embed-websocket:10.1.7")
|
||||
api("org.apache.tomcat:tomcat-util:10.1.7")
|
||||
api("org.apache.tomcat:tomcat-websocket:10.1.7")
|
||||
api("org.apache.tomcat.embed:tomcat-embed-core:10.1.5")
|
||||
api("org.apache.tomcat.embed:tomcat-embed-websocket:10.1.5")
|
||||
api("org.apache.tomcat:tomcat-util:10.1.5")
|
||||
api("org.apache.tomcat:tomcat-websocket:10.1.5")
|
||||
api("org.aspectj:aspectjrt:1.9.9.1")
|
||||
api("org.aspectj:aspectjtools:1.9.9.1")
|
||||
api("org.aspectj:aspectjweaver:1.9.9.1")
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
version=6.0.7
|
||||
version=6.0.5
|
||||
|
||||
org.gradle.caching=true
|
||||
org.gradle.jvmargs=-Xmx2048m
|
||||
|
||||
+9
-15
@@ -248,26 +248,20 @@ public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedence
|
||||
}
|
||||
|
||||
/**
|
||||
* Set by the creator of this advice object if the argument names are known.
|
||||
* <p>This could be for example because they have been explicitly specified in XML
|
||||
* Set by creator of this advice object if the argument names are known.
|
||||
* <p>This could be for example because they have been explicitly specified in XML,
|
||||
* or in an advice annotation.
|
||||
* @param argumentNames comma delimited list of argument names
|
||||
* @param argNames comma delimited list of arg names
|
||||
*/
|
||||
public void setArgumentNames(String argumentNames) {
|
||||
String[] tokens = StringUtils.commaDelimitedListToStringArray(argumentNames);
|
||||
public void setArgumentNames(String argNames) {
|
||||
String[] tokens = StringUtils.commaDelimitedListToStringArray(argNames);
|
||||
setArgumentNamesFromStringArray(tokens);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set by the creator of this advice object if the argument names are known.
|
||||
* <p>This could be for example because they have been explicitly specified in XML
|
||||
* or in an advice annotation.
|
||||
* @param argumentNames list of argument names
|
||||
*/
|
||||
public void setArgumentNamesFromStringArray(String... argumentNames) {
|
||||
this.argumentNames = new String[argumentNames.length];
|
||||
for (int i = 0; i < argumentNames.length; i++) {
|
||||
this.argumentNames[i] = argumentNames[i].strip();
|
||||
public void setArgumentNamesFromStringArray(String... args) {
|
||||
this.argumentNames = new String[args.length];
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
this.argumentNames[i] = args[i].strip();
|
||||
if (!isVariableName(this.argumentNames[i])) {
|
||||
throw new IllegalArgumentException(
|
||||
"'argumentNames' property of AbstractAspectJAdvice contains an argument name '" +
|
||||
|
||||
+47
-32
@@ -38,14 +38,6 @@ import org.springframework.util.StringUtils;
|
||||
* for an advice method from the pointcut expression, returning, and throwing clauses.
|
||||
* If an unambiguous interpretation is not available, it returns {@code null}.
|
||||
*
|
||||
* <h3>Algorithm Summary</h3>
|
||||
* <p>If an unambiguous binding can be deduced, then it is.
|
||||
* If the advice requirements cannot possibly be satisfied, then {@code null}
|
||||
* is returned. By setting the {@link #setRaiseExceptions(boolean) raiseExceptions}
|
||||
* property to {@code true}, descriptive exceptions will be thrown instead of
|
||||
* returning {@code null} in the case that the parameter names cannot be discovered.
|
||||
*
|
||||
* <h3>Algorithm Details</h3>
|
||||
* <p>This class interprets arguments in the following way:
|
||||
* <ol>
|
||||
* <li>If the first parameter of the method is of type {@link JoinPoint}
|
||||
@@ -73,15 +65,15 @@ import org.springframework.util.StringUtils;
|
||||
* zero we proceed to the next stage. If {@code a} > 1 then an
|
||||
* {@code AmbiguousBindingException} is raised. If {@code a} == 1,
|
||||
* and there are no unbound arguments of type {@code Annotation+},
|
||||
* then an {@code IllegalArgumentException} is raised. If there is
|
||||
* then an {@code IllegalArgumentException} is raised. if there is
|
||||
* exactly one such argument, then the corresponding parameter name is
|
||||
* assigned the value from the pointcut expression.</li>
|
||||
* <li>If a {@code returningName} has been set, and there are no unbound arguments
|
||||
* <li>If a returningName has been set, and there are no unbound arguments
|
||||
* then an {@code IllegalArgumentException} is raised. If there is
|
||||
* more than one unbound argument then an
|
||||
* {@code AmbiguousBindingException} is raised. If there is exactly
|
||||
* one unbound argument then the corresponding parameter name is assigned
|
||||
* the value of the {@code returningName}.</li>
|
||||
* the value <returningName>.</li>
|
||||
* <li>If there remain unbound arguments, then the pointcut expression is
|
||||
* examined once more for {@code this}, {@code target}, and
|
||||
* {@code args} pointcut expressions used in the binding form (binding
|
||||
@@ -107,12 +99,20 @@ import org.springframework.util.StringUtils;
|
||||
* <p>The behavior on raising an {@code IllegalArgumentException} or
|
||||
* {@code AmbiguousBindingException} is configurable to allow this discoverer
|
||||
* to be used as part of a chain-of-responsibility. By default the condition will
|
||||
* be logged and the {@link #getParameterNames(Method)} method will simply return
|
||||
* be logged and the {@code getParameterNames(..)} method will simply return
|
||||
* {@code null}. If the {@link #setRaiseExceptions(boolean) raiseExceptions}
|
||||
* property is set to {@code true}, the conditions will be thrown as
|
||||
* {@code IllegalArgumentException} and {@code AmbiguousBindingException},
|
||||
* respectively.
|
||||
*
|
||||
* <p>Was that perfectly clear? ;)
|
||||
*
|
||||
* <p>Short version: If an unambiguous binding can be deduced, then it is.
|
||||
* If the advice requirements cannot possibly be satisfied, then {@code null}
|
||||
* is returned. By setting the {@link #setRaiseExceptions(boolean) raiseExceptions}
|
||||
* property to {@code true}, descriptive exceptions will be thrown instead of
|
||||
* returning {@code null} in the case that the parameter names cannot be discovered.
|
||||
*
|
||||
* @author Adrian Colyer
|
||||
* @author Juergen Hoeller
|
||||
* @since 2.0
|
||||
@@ -197,7 +197,7 @@ public class AspectJAdviceParameterNameDiscoverer implements ParameterNameDiscov
|
||||
|
||||
/**
|
||||
* If {@code afterReturning} advice binds the return value, the
|
||||
* {@code returning} variable name must be specified.
|
||||
* returning variable name must be specified.
|
||||
* @param returningName the name of the returning variable
|
||||
*/
|
||||
public void setReturningName(@Nullable String returningName) {
|
||||
@@ -206,17 +206,18 @@ public class AspectJAdviceParameterNameDiscoverer implements ParameterNameDiscov
|
||||
|
||||
/**
|
||||
* If {@code afterThrowing} advice binds the thrown value, the
|
||||
* {@code throwing} variable name must be specified.
|
||||
* throwing variable name must be specified.
|
||||
* @param throwingName the name of the throwing variable
|
||||
*/
|
||||
public void setThrowingName(@Nullable String throwingName) {
|
||||
this.throwingName = throwingName;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Deduce the parameter names for an advice method.
|
||||
* <p>See the {@link AspectJAdviceParameterNameDiscoverer class-level javadoc}
|
||||
* for this class for details on the algorithm used.
|
||||
* <p>See the {@link AspectJAdviceParameterNameDiscoverer class level javadoc}
|
||||
* for this class for details of the algorithm used.
|
||||
* @param method the target {@link Method}
|
||||
* @return the parameter names
|
||||
*/
|
||||
@@ -308,7 +309,7 @@ public class AspectJAdviceParameterNameDiscoverer implements ParameterNameDiscov
|
||||
}
|
||||
|
||||
/**
|
||||
* If the first parameter is of type JoinPoint or ProceedingJoinPoint, bind "thisJoinPoint" as
|
||||
* If the first parameter is of type JoinPoint or ProceedingJoinPoint,bind "thisJoinPoint" as
|
||||
* parameter name and return true, else return false.
|
||||
*/
|
||||
private boolean maybeBindThisJoinPoint() {
|
||||
@@ -347,14 +348,14 @@ public class AspectJAdviceParameterNameDiscoverer implements ParameterNameDiscov
|
||||
// Second candidate we've found - ambiguous binding
|
||||
throw new AmbiguousBindingException("Binding of throwing parameter '" +
|
||||
this.throwingName + "' is ambiguous: could be bound to argument " +
|
||||
throwableIndex + " or " + i);
|
||||
throwableIndex + " or argument " + i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (throwableIndex == -1) {
|
||||
throw new IllegalStateException("Binding of throwing parameter '" + this.throwingName +
|
||||
"' could not be completed as no available arguments are a subtype of Throwable");
|
||||
throw new IllegalStateException("Binding of throwing parameter '" + this.throwingName
|
||||
+ "' could not be completed as no available arguments are a subtype of Throwable");
|
||||
}
|
||||
else {
|
||||
bindParameterName(throwableIndex, this.throwingName);
|
||||
@@ -373,7 +374,7 @@ public class AspectJAdviceParameterNameDiscoverer implements ParameterNameDiscov
|
||||
if (this.returningName != null) {
|
||||
if (this.numberOfRemainingUnboundArguments > 1) {
|
||||
throw new AmbiguousBindingException("Binding of returning parameter '" + this.returningName +
|
||||
"' is ambiguous: there are " + this.numberOfRemainingUnboundArguments + " candidates.");
|
||||
"' is ambiguous, there are " + this.numberOfRemainingUnboundArguments + " candidates.");
|
||||
}
|
||||
|
||||
// We're all set... find the unbound parameter, and bind it.
|
||||
@@ -386,6 +387,7 @@ public class AspectJAdviceParameterNameDiscoverer implements ParameterNameDiscov
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Parse the string pointcut expression looking for:
|
||||
* @this, @target, @args, @within, @withincode, @annotation.
|
||||
@@ -429,7 +431,7 @@ public class AspectJAdviceParameterNameDiscoverer implements ParameterNameDiscov
|
||||
int numAnnotationSlots = countNumberOfUnboundAnnotationArguments();
|
||||
if (numAnnotationSlots > 1) {
|
||||
throw new AmbiguousBindingException("Found " + varNames.size() +
|
||||
" potential annotation variable(s) and " +
|
||||
" potential annotation variable(s), and " +
|
||||
numAnnotationSlots + " potential argument slots");
|
||||
}
|
||||
else if (numAnnotationSlots == 1) {
|
||||
@@ -450,7 +452,7 @@ public class AspectJAdviceParameterNameDiscoverer implements ParameterNameDiscov
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
/*
|
||||
* If the token starts meets Java identifier conventions, it's in.
|
||||
*/
|
||||
@Nullable
|
||||
@@ -486,7 +488,7 @@ public class AspectJAdviceParameterNameDiscoverer implements ParameterNameDiscov
|
||||
private void maybeBindThisOrTargetOrArgsFromPointcutExpression() {
|
||||
if (this.numberOfRemainingUnboundArguments > 1) {
|
||||
throw new AmbiguousBindingException("Still " + this.numberOfRemainingUnboundArguments
|
||||
+ " unbound args at this()/target()/args() binding stage, with no way to determine between them");
|
||||
+ " unbound args at this(),target(),args() binding stage, with no way to determine between them");
|
||||
}
|
||||
|
||||
List<String> varNames = new ArrayList<>();
|
||||
@@ -518,9 +520,10 @@ public class AspectJAdviceParameterNameDiscoverer implements ParameterNameDiscov
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (varNames.size() > 1) {
|
||||
throw new AmbiguousBindingException("Found " + varNames.size() +
|
||||
" candidate this(), target(), or args() variables but only one unbound argument slot");
|
||||
" candidate this(), target() or args() variables but only one unbound argument slot");
|
||||
}
|
||||
else if (varNames.size() == 1) {
|
||||
for (int j = 0; j < this.parameterNameBindings.length; j++) {
|
||||
@@ -593,7 +596,7 @@ public class AspectJAdviceParameterNameDiscoverer implements ParameterNameDiscov
|
||||
// else varNames.size must be 0 and we have nothing to bind.
|
||||
}
|
||||
|
||||
/**
|
||||
/*
|
||||
* We've found the start of a binding pointcut at the given index into the
|
||||
* token array. Now we need to extract the pointcut body and return it.
|
||||
*/
|
||||
@@ -646,8 +649,8 @@ public class AspectJAdviceParameterNameDiscoverer implements ParameterNameDiscov
|
||||
private void maybeBindPrimitiveArgsFromPointcutExpression() {
|
||||
int numUnboundPrimitives = countNumberOfUnboundPrimitiveArguments();
|
||||
if (numUnboundPrimitives > 1) {
|
||||
throw new AmbiguousBindingException("Found " + numUnboundPrimitives +
|
||||
" unbound primitive arguments with no way to distinguish between them.");
|
||||
throw new AmbiguousBindingException("Found '" + numUnboundPrimitives +
|
||||
"' unbound primitive arguments with no way to distinguish between them.");
|
||||
}
|
||||
if (numUnboundPrimitives == 1) {
|
||||
// Look for arg variable and bind it if we find exactly one...
|
||||
@@ -693,7 +696,7 @@ public class AspectJAdviceParameterNameDiscoverer implements ParameterNameDiscov
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
/*
|
||||
* Return {@code true} if the given argument type is a subclass
|
||||
* of the given supertype.
|
||||
*/
|
||||
@@ -721,7 +724,7 @@ public class AspectJAdviceParameterNameDiscoverer implements ParameterNameDiscov
|
||||
return count;
|
||||
}
|
||||
|
||||
/**
|
||||
/*
|
||||
* Find the argument index with the given type, and bind the given
|
||||
* {@code varName} in that position.
|
||||
*/
|
||||
@@ -738,10 +741,22 @@ public class AspectJAdviceParameterNameDiscoverer implements ParameterNameDiscov
|
||||
|
||||
|
||||
/**
|
||||
* Simple record to hold the extracted text from a pointcut body, together
|
||||
* Simple struct to hold the extracted text from a pointcut body, together
|
||||
* with the number of tokens consumed in extracting it.
|
||||
*/
|
||||
private record PointcutBody(int numTokensConsumed, @Nullable String text) {}
|
||||
private static class PointcutBody {
|
||||
|
||||
private final int numTokensConsumed;
|
||||
|
||||
@Nullable
|
||||
private final String text;
|
||||
|
||||
public PointcutBody(int tokens, @Nullable String text) {
|
||||
this.numTokensConsumed = tokens;
|
||||
this.text = text;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Thrown in response to an ambiguous binding being detected when
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2023 the original author or authors.
|
||||
* Copyright 2002-2022 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.
|
||||
@@ -117,7 +117,7 @@ public class TypePatternClassFilter implements ClassFilter {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(@Nullable Object obj) {
|
||||
public boolean equals(Object obj) {
|
||||
return (this == obj || (obj instanceof TypePatternClassFilter that &&
|
||||
ObjectUtils.nullSafeEquals(this.typePattern, that.typePattern)));
|
||||
}
|
||||
|
||||
+22
-24
@@ -121,21 +121,21 @@ public abstract class AbstractAspectJAdvisorFactory implements AspectJAdvisorFac
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
@Nullable
|
||||
protected static AspectJAnnotation findAspectJAnnotationOnMethod(Method method) {
|
||||
for (Class<?> annotationType : ASPECTJ_ANNOTATION_CLASSES) {
|
||||
AspectJAnnotation annotation = findAnnotation(method, (Class<Annotation>) annotationType);
|
||||
if (annotation != null) {
|
||||
return annotation;
|
||||
protected static AspectJAnnotation<?> findAspectJAnnotationOnMethod(Method method) {
|
||||
for (Class<?> clazz : ASPECTJ_ANNOTATION_CLASSES) {
|
||||
AspectJAnnotation<?> foundAnnotation = findAnnotation(method, (Class<Annotation>) clazz);
|
||||
if (foundAnnotation != null) {
|
||||
return foundAnnotation;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static AspectJAnnotation findAnnotation(Method method, Class<? extends Annotation> annotationType) {
|
||||
Annotation annotation = AnnotationUtils.findAnnotation(method, annotationType);
|
||||
if (annotation != null) {
|
||||
return new AspectJAnnotation(annotation);
|
||||
private static <A extends Annotation> AspectJAnnotation<A> findAnnotation(Method method, Class<A> toLookFor) {
|
||||
A result = AnnotationUtils.findAnnotation(method, toLookFor);
|
||||
if (result != null) {
|
||||
return new AspectJAnnotation<>(result);
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
@@ -156,8 +156,9 @@ public abstract class AbstractAspectJAdvisorFactory implements AspectJAdvisorFac
|
||||
/**
|
||||
* Class modeling an AspectJ annotation, exposing its type enumeration and
|
||||
* pointcut String.
|
||||
* @param <A> the annotation type
|
||||
*/
|
||||
protected static class AspectJAnnotation {
|
||||
protected static class AspectJAnnotation<A extends Annotation> {
|
||||
|
||||
private static final String[] EXPRESSION_ATTRIBUTES = {"pointcut", "value"};
|
||||
|
||||
@@ -170,7 +171,7 @@ public abstract class AbstractAspectJAdvisorFactory implements AspectJAdvisorFac
|
||||
AfterThrowing.class, AspectJAnnotationType.AtAfterThrowing //
|
||||
);
|
||||
|
||||
private final Annotation annotation;
|
||||
private final A annotation;
|
||||
|
||||
private final AspectJAnnotationType annotationType;
|
||||
|
||||
@@ -178,11 +179,11 @@ public abstract class AbstractAspectJAdvisorFactory implements AspectJAdvisorFac
|
||||
|
||||
private final String argumentNames;
|
||||
|
||||
public AspectJAnnotation(Annotation annotation) {
|
||||
public AspectJAnnotation(A annotation) {
|
||||
this.annotation = annotation;
|
||||
this.annotationType = determineAnnotationType(annotation);
|
||||
try {
|
||||
this.pointcutExpression = resolvePointcutExpression(annotation);
|
||||
this.pointcutExpression = resolveExpression(annotation);
|
||||
Object argNames = AnnotationUtils.getValue(annotation, "argNames");
|
||||
this.argumentNames = (argNames instanceof String names ? names : "");
|
||||
}
|
||||
@@ -191,7 +192,7 @@ public abstract class AbstractAspectJAdvisorFactory implements AspectJAdvisorFac
|
||||
}
|
||||
}
|
||||
|
||||
private AspectJAnnotationType determineAnnotationType(Annotation annotation) {
|
||||
private AspectJAnnotationType determineAnnotationType(A annotation) {
|
||||
AspectJAnnotationType type = annotationTypeMap.get(annotation.annotationType());
|
||||
if (type != null) {
|
||||
return type;
|
||||
@@ -199,21 +200,21 @@ public abstract class AbstractAspectJAdvisorFactory implements AspectJAdvisorFac
|
||||
throw new IllegalStateException("Unknown annotation type: " + annotation);
|
||||
}
|
||||
|
||||
private String resolvePointcutExpression(Annotation annotation) {
|
||||
private String resolveExpression(A annotation) {
|
||||
for (String attributeName : EXPRESSION_ATTRIBUTES) {
|
||||
Object val = AnnotationUtils.getValue(annotation, attributeName);
|
||||
if (val instanceof String str && !str.isEmpty()) {
|
||||
return str;
|
||||
}
|
||||
}
|
||||
throw new IllegalStateException("Failed to resolve pointcut expression in: " + annotation);
|
||||
throw new IllegalStateException("Failed to resolve expression in: " + annotation);
|
||||
}
|
||||
|
||||
public AspectJAnnotationType getAnnotationType() {
|
||||
return this.annotationType;
|
||||
}
|
||||
|
||||
public Annotation getAnnotation() {
|
||||
public A getAnnotation() {
|
||||
return this.annotation;
|
||||
}
|
||||
|
||||
@@ -238,22 +239,19 @@ public abstract class AbstractAspectJAdvisorFactory implements AspectJAdvisorFac
|
||||
*/
|
||||
private static class AspectJAnnotationParameterNameDiscoverer implements ParameterNameDiscoverer {
|
||||
|
||||
private static final String[] EMPTY_ARRAY = new String[0];
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public String[] getParameterNames(Method method) {
|
||||
if (method.getParameterCount() == 0) {
|
||||
return EMPTY_ARRAY;
|
||||
return new String[0];
|
||||
}
|
||||
AspectJAnnotation annotation = findAspectJAnnotationOnMethod(method);
|
||||
AspectJAnnotation<?> annotation = findAspectJAnnotationOnMethod(method);
|
||||
if (annotation == null) {
|
||||
return null;
|
||||
}
|
||||
StringTokenizer nameTokens = new StringTokenizer(annotation.getArgumentNames(), ",");
|
||||
int numTokens = nameTokens.countTokens();
|
||||
if (numTokens > 0) {
|
||||
String[] names = new String[numTokens];
|
||||
if (nameTokens.countTokens() > 0) {
|
||||
String[] names = new String[nameTokens.countTokens()];
|
||||
for (int i = 0; i < names.length; i++) {
|
||||
names[i] = nameTokens.nextToken();
|
||||
}
|
||||
|
||||
+3
-4
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2023 the original author or authors.
|
||||
* Copyright 2002-2022 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.
|
||||
@@ -35,8 +35,7 @@ import org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
* Internal implementation of AspectJPointcutAdvisor.
|
||||
*
|
||||
* <p>Note that there will be one instance of this advisor for each target method.
|
||||
* Note that there will be one instance of this advisor for each target method.
|
||||
*
|
||||
* @author Rod Johnson
|
||||
* @author Juergen Hoeller
|
||||
@@ -213,7 +212,7 @@ final class InstantiationModelAwarePointcutAdvisorImpl
|
||||
* creation of the advice.
|
||||
*/
|
||||
private void determineAdviceType() {
|
||||
AspectJAnnotation aspectJAnnotation =
|
||||
AspectJAnnotation<?> aspectJAnnotation =
|
||||
AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(this.aspectJAdviceMethod);
|
||||
if (aspectJAnnotation == null) {
|
||||
this.isBeforeAdvice = false;
|
||||
|
||||
+7
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2023 the original author or authors.
|
||||
* Copyright 2002-2016 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.
|
||||
@@ -23,6 +23,10 @@ import org.springframework.lang.Nullable;
|
||||
* Subinterface of {@link org.springframework.aop.aspectj.AspectInstanceFactory}
|
||||
* that returns {@link AspectMetadata} associated with AspectJ-annotated classes.
|
||||
*
|
||||
* <p>Ideally, AspectInstanceFactory would include this method itself, but because
|
||||
* AspectMetadata uses Java-5-only {@link org.aspectj.lang.reflect.AjType},
|
||||
* we need to split out this subinterface.
|
||||
*
|
||||
* @author Rod Johnson
|
||||
* @since 2.0
|
||||
* @see AspectMetadata
|
||||
@@ -31,13 +35,13 @@ import org.springframework.lang.Nullable;
|
||||
public interface MetadataAwareAspectInstanceFactory extends AspectInstanceFactory {
|
||||
|
||||
/**
|
||||
* Get the AspectJ AspectMetadata for this factory's aspect.
|
||||
* Return the AspectJ AspectMetadata for this factory's aspect.
|
||||
* @return the aspect metadata
|
||||
*/
|
||||
AspectMetadata getAspectMetadata();
|
||||
|
||||
/**
|
||||
* Get the best possible creation mutex for this factory.
|
||||
* Return the best possible creation mutex for this factory.
|
||||
* @return the mutex object (may be {@code null} for no mutex to use)
|
||||
* @since 4.3
|
||||
*/
|
||||
|
||||
+4
-4
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2023 the original author or authors.
|
||||
* Copyright 2002-2022 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.
|
||||
@@ -87,7 +87,7 @@ public class ReflectiveAspectJAdvisorFactory extends AbstractAspectJAdvisorFacto
|
||||
new InstanceComparator<>(
|
||||
Around.class, Before.class, After.class, AfterReturning.class, AfterThrowing.class),
|
||||
(Converter<Method, Annotation>) method -> {
|
||||
AspectJAnnotation ann = AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(method);
|
||||
AspectJAnnotation<?> ann = AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(method);
|
||||
return (ann != null ? ann.getAnnotation() : null);
|
||||
});
|
||||
Comparator<Method> methodNameComparator = new ConvertingComparator<>(Method::getName);
|
||||
@@ -216,7 +216,7 @@ public class ReflectiveAspectJAdvisorFactory extends AbstractAspectJAdvisorFacto
|
||||
|
||||
@Nullable
|
||||
private AspectJExpressionPointcut getPointcut(Method candidateAdviceMethod, Class<?> candidateAspectClass) {
|
||||
AspectJAnnotation aspectJAnnotation =
|
||||
AspectJAnnotation<?> aspectJAnnotation =
|
||||
AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod);
|
||||
if (aspectJAnnotation == null) {
|
||||
return null;
|
||||
@@ -240,7 +240,7 @@ public class ReflectiveAspectJAdvisorFactory extends AbstractAspectJAdvisorFacto
|
||||
Class<?> candidateAspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
|
||||
validate(candidateAspectClass);
|
||||
|
||||
AspectJAnnotation aspectJAnnotation =
|
||||
AspectJAnnotation<?> aspectJAnnotation =
|
||||
AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod);
|
||||
if (aspectJAnnotation == null) {
|
||||
return null;
|
||||
|
||||
+14
-7
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2023 the original author or authors.
|
||||
* Copyright 2002-2007 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.
|
||||
@@ -21,13 +21,20 @@ import org.aopalliance.intercept.MethodInterceptor;
|
||||
import org.springframework.aop.MethodMatcher;
|
||||
|
||||
/**
|
||||
* Internal framework record, combining a {@link MethodInterceptor} instance
|
||||
* with a {@link MethodMatcher} for use as an element in the advisor chain.
|
||||
* Internal framework class, combining a MethodInterceptor instance
|
||||
* with a MethodMatcher for use as an element in the advisor chain.
|
||||
*
|
||||
* @author Rod Johnson
|
||||
* @author Sam Brannen
|
||||
* @param interceptor the {@code MethodInterceptor}
|
||||
* @param matcher the {@code MethodMatcher}
|
||||
*/
|
||||
record InterceptorAndDynamicMethodMatcher(MethodInterceptor interceptor, MethodMatcher matcher) {
|
||||
class InterceptorAndDynamicMethodMatcher {
|
||||
|
||||
final MethodInterceptor interceptor;
|
||||
|
||||
final MethodMatcher methodMatcher;
|
||||
|
||||
public InterceptorAndDynamicMethodMatcher(MethodInterceptor interceptor, MethodMatcher methodMatcher) {
|
||||
this.interceptor = interceptor;
|
||||
this.methodMatcher = methodMatcher;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+3
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2023 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.
|
||||
@@ -169,8 +169,8 @@ public class ReflectiveMethodInvocation implements ProxyMethodInvocation, Clonea
|
||||
// Evaluate dynamic method matcher here: static part will already have
|
||||
// been evaluated and found to match.
|
||||
Class<?> targetClass = (this.targetClass != null ? this.targetClass : this.method.getDeclaringClass());
|
||||
if (dm.matcher().matches(this.method, targetClass, this.arguments)) {
|
||||
return dm.interceptor().invoke(this);
|
||||
if (dm.methodMatcher.matches(this.method, targetClass, this.arguments)) {
|
||||
return dm.interceptor.invoke(this);
|
||||
}
|
||||
else {
|
||||
// Dynamic matching failed.
|
||||
|
||||
+3
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2023 the original author or authors.
|
||||
* Copyright 2002-2018 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.
|
||||
@@ -92,7 +92,8 @@ public class BeanFactoryAdvisorRetrievalHelper {
|
||||
}
|
||||
catch (BeanCreationException ex) {
|
||||
Throwable rootCause = ex.getMostSpecificCause();
|
||||
if (rootCause instanceof BeanCurrentlyInCreationException bce) {
|
||||
if (rootCause instanceof BeanCurrentlyInCreationException) {
|
||||
BeanCreationException bce = (BeanCreationException) rootCause;
|
||||
String bceBeanName = bce.getBeanName();
|
||||
if (bceBeanName != null && this.beanFactory.isCurrentlyInCreation(bceBeanName)) {
|
||||
if (logger.isTraceEnabled()) {
|
||||
|
||||
+3
-4
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2023 the original author or authors.
|
||||
* Copyright 2002-2022 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,11 +58,11 @@ public abstract class AbstractBeanFactoryBasedTargetSourceCreator
|
||||
|
||||
protected final Log logger = LogFactory.getLog(getClass());
|
||||
|
||||
@Nullable
|
||||
private ConfigurableBeanFactory beanFactory;
|
||||
|
||||
/** Internally used DefaultListableBeanFactory instances, keyed by bean name. */
|
||||
private final Map<String, DefaultListableBeanFactory> internalBeanFactories = new HashMap<>();
|
||||
private final Map<String, DefaultListableBeanFactory> internalBeanFactories =
|
||||
new HashMap<>();
|
||||
|
||||
|
||||
@Override
|
||||
@@ -77,7 +77,6 @@ public abstract class AbstractBeanFactoryBasedTargetSourceCreator
|
||||
/**
|
||||
* Return the BeanFactory that this TargetSourceCreators runs in.
|
||||
*/
|
||||
@Nullable
|
||||
protected final BeanFactory getBeanFactory() {
|
||||
return this.beanFactory;
|
||||
}
|
||||
|
||||
-10
@@ -1,10 +0,0 @@
|
||||
/**
|
||||
* Various {@link org.springframework.aop.framework.autoproxy.TargetSourceCreator}
|
||||
* implementations for use with Spring's AOP auto-proxying support.
|
||||
*/
|
||||
@NonNullApi
|
||||
@NonNullFields
|
||||
package org.springframework.aop.framework.autoproxy.target;
|
||||
|
||||
import org.springframework.lang.NonNullApi;
|
||||
import org.springframework.lang.NonNullFields;
|
||||
+3
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2023 the original author or authors.
|
||||
* Copyright 2002-2022 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.
|
||||
@@ -55,8 +55,8 @@ class ScopedProxyBeanRegistrationAotProcessor implements BeanRegistrationAotProc
|
||||
|
||||
@Override
|
||||
public BeanRegistrationAotContribution processAheadOfTime(RegisteredBean registeredBean) {
|
||||
Class<?> beanClass = registeredBean.getBeanClass();
|
||||
if (beanClass.equals(ScopedProxyFactoryBean.class)) {
|
||||
Class<?> beanType = registeredBean.getBeanType().toClass();
|
||||
if (beanType.equals(ScopedProxyFactoryBean.class)) {
|
||||
String targetBeanName = getTargetBeanName(registeredBean.getMergedBeanDefinition());
|
||||
BeanDefinition targetBeanDefinition =
|
||||
getTargetBeanDefinition(registeredBean.getBeanFactory(), targetBeanName);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2023 the original author or authors.
|
||||
* Copyright 2002-2022 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.
|
||||
@@ -19,7 +19,6 @@ package org.springframework.aop.support;
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.springframework.aop.ClassFilter;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
@@ -46,7 +45,7 @@ public class RootClassFilter implements ClassFilter, Serializable {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(@Nullable Object obj) {
|
||||
public boolean equals(Object obj) {
|
||||
return (this == obj || (obj instanceof RootClassFilter that &&
|
||||
this.clazz.equals(that.clazz)));
|
||||
}
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2023 the original author or authors.
|
||||
* Copyright 2002-2022 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.
|
||||
@@ -183,7 +183,7 @@ public class AnnotationMatchingPointcut implements Pointcut {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(@Nullable Object obj) {
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
|
||||
+2
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2023 the original author or authors.
|
||||
* Copyright 2002-2022 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.
|
||||
@@ -24,7 +24,6 @@ import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.aop.TargetSource;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.BeanFactoryAware;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
/**
|
||||
@@ -170,7 +169,7 @@ public abstract class AbstractBeanFactoryBasedTargetSource implements TargetSour
|
||||
|
||||
|
||||
@Override
|
||||
public boolean equals(@Nullable Object other) {
|
||||
public boolean equals(Object other) {
|
||||
if (this == other) {
|
||||
return true;
|
||||
}
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2023 the original author or authors.
|
||||
* Copyright 2002-2018 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.
|
||||
@@ -181,7 +181,7 @@ public class CommonsPool2TargetSource extends AbstractPoolingTargetSource implem
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether the call should block when the pool is exhausted.
|
||||
* Set whether the call should bock when the pool is exhausted.
|
||||
*/
|
||||
public void setBlockWhenExhausted(boolean blockWhenExhausted) {
|
||||
this.blockWhenExhausted = blockWhenExhausted;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2023 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.
|
||||
@@ -131,7 +131,7 @@ public final class EmptyTargetSource implements TargetSource, Serializable {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(@Nullable Object other) {
|
||||
public boolean equals(Object other) {
|
||||
if (this == other) {
|
||||
return true;
|
||||
}
|
||||
|
||||
+2
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2023 the original author or authors.
|
||||
* Copyright 2002-2022 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.
|
||||
@@ -19,7 +19,6 @@ package org.springframework.aop.target;
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.springframework.aop.TargetSource;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
@@ -101,7 +100,7 @@ public class HotSwappableTargetSource implements TargetSource, Serializable {
|
||||
* objects are equal.
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(@Nullable Object obj) {
|
||||
public boolean equals(Object obj) {
|
||||
return (this == obj || (obj instanceof HotSwappableTargetSource that &&
|
||||
this.target.equals(that.target)));
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2023 the original author or authors.
|
||||
* Copyright 2002-2012 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.
|
||||
@@ -65,6 +65,7 @@ public class LazyInitTargetSource extends AbstractBeanFactoryBasedTargetSource {
|
||||
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public synchronized Object getTarget() throws BeansException {
|
||||
if (this.target == null) {
|
||||
this.target = getBeanFactory().getBean(getTargetBeanName());
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2023 the original author or authors.
|
||||
* Copyright 2002-2022 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.
|
||||
@@ -19,7 +19,6 @@ package org.springframework.aop.target;
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.springframework.aop.TargetSource;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
@@ -83,7 +82,7 @@ public class SingletonTargetSource implements TargetSource, Serializable {
|
||||
* targets or the targets are equal.
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(@Nullable Object other) {
|
||||
public boolean equals(Object other) {
|
||||
if (this == other) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
/**
|
||||
* Support for dynamic, refreshable {@link org.springframework.aop.TargetSource}
|
||||
* implementations for use with Spring AOP.
|
||||
*/
|
||||
@NonNullApi
|
||||
@NonNullFields
|
||||
package org.springframework.aop.target.dynamic;
|
||||
|
||||
import org.springframework.lang.NonNullApi;
|
||||
import org.springframework.lang.NonNullFields;
|
||||
@@ -1,10 +0,0 @@
|
||||
/**
|
||||
* Various {@link org.springframework.aop.TargetSource} implementations for use
|
||||
* with Spring AOP.
|
||||
*/
|
||||
@NonNullApi
|
||||
@NonNullFields
|
||||
package org.springframework.aop.target;
|
||||
|
||||
import org.springframework.lang.NonNullApi;
|
||||
import org.springframework.lang.NonNullFields;
|
||||
+67
-55
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2023 the original author or authors.
|
||||
* Copyright 2002-2022 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.
|
||||
@@ -17,6 +17,7 @@
|
||||
package org.springframework.aop.aspectj;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.aspectj.lang.JoinPoint;
|
||||
import org.aspectj.lang.ProceedingJoinPoint;
|
||||
@@ -42,17 +43,17 @@ class AspectJAdviceParameterNameDiscovererTests {
|
||||
|
||||
@Test
|
||||
void noArgs() {
|
||||
assertParameterNames(getMethod("noArgs"), "execution(* *(..))");
|
||||
assertParameterNames(getMethod("noArgs"), "execution(* *(..))", new String[0]);
|
||||
}
|
||||
|
||||
@Test
|
||||
void joinPointOnly() {
|
||||
assertParameterNames(getMethod("tjp"), "execution(* *(..))", "thisJoinPoint");
|
||||
assertParameterNames(getMethod("tjp"), "execution(* *(..))", new String[] {"thisJoinPoint"});
|
||||
}
|
||||
|
||||
@Test
|
||||
void joinPointStaticPartOnly() {
|
||||
assertParameterNames(getMethod("tjpsp"), "execution(* *(..))", "thisJoinPointStaticPart");
|
||||
assertParameterNames(getMethod("tjpsp"), "execution(* *(..))", new String[] {"thisJoinPointStaticPart"});
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -63,18 +64,18 @@ class AspectJAdviceParameterNameDiscovererTests {
|
||||
|
||||
@Test
|
||||
void oneThrowable() {
|
||||
assertParameterNamesExtended(getMethod("oneThrowable"), "foo()", null, "ex", "ex");
|
||||
assertParameterNames(getMethod("oneThrowable"), "foo()", null, "ex", new String[] {"ex"});
|
||||
}
|
||||
|
||||
@Test
|
||||
void oneJPAndOneThrowable() {
|
||||
assertParameterNamesExtended(getMethod("jpAndOneThrowable"), "foo()", null, "ex", "thisJoinPoint", "ex");
|
||||
assertParameterNames(getMethod("jpAndOneThrowable"), "foo()", null, "ex", new String[] {"thisJoinPoint", "ex"});
|
||||
}
|
||||
|
||||
@Test
|
||||
void oneJPAndTwoThrowables() {
|
||||
assertException(getMethod("jpAndTwoThrowables"), "foo()", null, "ex", AmbiguousBindingException.class,
|
||||
"Binding of throwing parameter 'ex' is ambiguous: could be bound to argument 1 or 2");
|
||||
"Binding of throwing parameter 'ex' is ambiguous: could be bound to argument 1 or argument 2");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -85,13 +86,13 @@ class AspectJAdviceParameterNameDiscovererTests {
|
||||
|
||||
@Test
|
||||
void returning() {
|
||||
assertParameterNamesExtended(getMethod("oneObject"), "foo()", "obj", null, "obj");
|
||||
assertParameterNames(getMethod("oneObject"), "foo()", "obj", null, new String[] {"obj"});
|
||||
}
|
||||
|
||||
@Test
|
||||
void ambiguousReturning() {
|
||||
assertException(getMethod("twoObjects"), "foo()", "obj", null, AmbiguousBindingException.class,
|
||||
"Binding of returning parameter 'obj' is ambiguous: there are 2 candidates.");
|
||||
"Binding of returning parameter 'obj' is ambiguous, there are 2 candidates.");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -102,22 +103,22 @@ class AspectJAdviceParameterNameDiscovererTests {
|
||||
|
||||
@Test
|
||||
void thisBindingOneCandidate() {
|
||||
assertParameterNames(getMethod("oneObject"), "this(x)", "x");
|
||||
assertParameterNames(getMethod("oneObject"), "this(x)", new String[] {"x"});
|
||||
}
|
||||
|
||||
@Test
|
||||
void thisBindingWithAlternateTokenizations() {
|
||||
assertParameterNames(getMethod("oneObject"), "this( x )", "x");
|
||||
assertParameterNames(getMethod("oneObject"), "this( x)", "x");
|
||||
assertParameterNames(getMethod("oneObject"), "this (x )", "x");
|
||||
assertParameterNames(getMethod("oneObject"), "this(x )", "x");
|
||||
assertParameterNames(getMethod("oneObject"), "foo() && this(x)", "x");
|
||||
assertParameterNames(getMethod("oneObject"), "this( x )", new String[] {"x"});
|
||||
assertParameterNames(getMethod("oneObject"), "this( x)", new String[] {"x"});
|
||||
assertParameterNames(getMethod("oneObject"), "this (x )", new String[] {"x"});
|
||||
assertParameterNames(getMethod("oneObject"), "this(x )", new String[] {"x"});
|
||||
assertParameterNames(getMethod("oneObject"), "foo() && this(x)", new String[] {"x"});
|
||||
}
|
||||
|
||||
@Test
|
||||
void thisBindingTwoCandidates() {
|
||||
assertException(getMethod("oneObject"), "this(x) || this(y)", AmbiguousBindingException.class,
|
||||
"Found 2 candidate this(), target(), or args() variables but only one unbound argument slot");
|
||||
"Found 2 candidate this(), target() or args() variables but only one unbound argument slot");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -130,22 +131,22 @@ class AspectJAdviceParameterNameDiscovererTests {
|
||||
|
||||
@Test
|
||||
void targetBindingOneCandidate() {
|
||||
assertParameterNames(getMethod("oneObject"), "target(x)", "x");
|
||||
assertParameterNames(getMethod("oneObject"), "target(x)", new String[] {"x"});
|
||||
}
|
||||
|
||||
@Test
|
||||
void targetBindingWithAlternateTokenizations() {
|
||||
assertParameterNames(getMethod("oneObject"), "target( x )", "x");
|
||||
assertParameterNames(getMethod("oneObject"), "target( x)", "x");
|
||||
assertParameterNames(getMethod("oneObject"), "target (x )", "x");
|
||||
assertParameterNames(getMethod("oneObject"), "target(x )", "x");
|
||||
assertParameterNames(getMethod("oneObject"), "foo() && target(x)", "x");
|
||||
assertParameterNames(getMethod("oneObject"), "target( x )", new String[] {"x"});
|
||||
assertParameterNames(getMethod("oneObject"), "target( x)", new String[] {"x"});
|
||||
assertParameterNames(getMethod("oneObject"), "target (x )", new String[] {"x"});
|
||||
assertParameterNames(getMethod("oneObject"), "target(x )", new String[] {"x"});
|
||||
assertParameterNames(getMethod("oneObject"), "foo() && target(x)", new String[] {"x"});
|
||||
}
|
||||
|
||||
@Test
|
||||
void targetBindingTwoCandidates() {
|
||||
assertException(getMethod("oneObject"), "target(x) || target(y)", AmbiguousBindingException.class,
|
||||
"Found 2 candidate this(), target(), or args() variables but only one unbound argument slot");
|
||||
"Found 2 candidate this(), target() or args() variables but only one unbound argument slot");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -158,24 +159,24 @@ class AspectJAdviceParameterNameDiscovererTests {
|
||||
|
||||
@Test
|
||||
void argsBindingOneObject() {
|
||||
assertParameterNames(getMethod("oneObject"), "args(x)", "x");
|
||||
assertParameterNames(getMethod("oneObject"), "args(x)", new String[] {"x"});
|
||||
}
|
||||
|
||||
@Test
|
||||
void argsBindingOneObjectTwoCandidates() {
|
||||
assertException(getMethod("oneObject"), "args(x,y)", AmbiguousBindingException.class,
|
||||
"Found 2 candidate this(), target(), or args() variables but only one unbound argument slot");
|
||||
"Found 2 candidate this(), target() or args() variables but only one unbound argument slot");
|
||||
}
|
||||
|
||||
@Test
|
||||
void ambiguousArgsBinding() {
|
||||
assertException(getMethod("twoObjects"), "args(x,y)", AmbiguousBindingException.class,
|
||||
"Still 2 unbound args at this()/target()/args() binding stage, with no way to determine between them");
|
||||
"Still 2 unbound args at this(),target(),args() binding stage, with no way to determine between them");
|
||||
}
|
||||
|
||||
@Test
|
||||
void argsOnePrimitive() {
|
||||
assertParameterNames(getMethod("onePrimitive"), "args(count)", "count");
|
||||
assertParameterNames(getMethod("onePrimitive"), "args(count)", new String[] {"count"});
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -187,37 +188,37 @@ class AspectJAdviceParameterNameDiscovererTests {
|
||||
@Test
|
||||
void thisAndPrimitive() {
|
||||
assertParameterNames(getMethod("oneObjectOnePrimitive"), "args(count) && this(obj)",
|
||||
"obj", "count");
|
||||
new String[] {"obj", "count"});
|
||||
}
|
||||
|
||||
@Test
|
||||
void targetAndPrimitive() {
|
||||
assertParameterNames(getMethod("oneObjectOnePrimitive"), "args(count) && target(obj)",
|
||||
"obj", "count");
|
||||
new String[] {"obj", "count"});
|
||||
}
|
||||
|
||||
@Test
|
||||
void throwingAndPrimitive() {
|
||||
assertParameterNamesExtended(getMethod("oneThrowableOnePrimitive"), "args(count)", null, "ex",
|
||||
"ex", "count");
|
||||
assertParameterNames(getMethod("oneThrowableOnePrimitive"), "args(count)", null, "ex",
|
||||
new String[] {"ex", "count"});
|
||||
}
|
||||
|
||||
@Test
|
||||
void allTogetherNow() {
|
||||
assertParameterNamesExtended(getMethod("theBigOne"), "this(foo) && args(x)", null, "ex",
|
||||
"thisJoinPoint", "ex", "x", "foo");
|
||||
assertParameterNames(getMethod("theBigOne"), "this(foo) && args(x)", null, "ex",
|
||||
new String[] {"thisJoinPoint", "ex", "x", "foo"});
|
||||
}
|
||||
|
||||
@Test
|
||||
void referenceBinding() {
|
||||
assertParameterNames(getMethod("onePrimitive"),"somepc(foo)", "foo");
|
||||
assertParameterNames(getMethod("onePrimitive"),"somepc(foo)", new String[] {"foo"});
|
||||
}
|
||||
|
||||
@Test
|
||||
void referenceBindingWithAlternateTokenizations() {
|
||||
assertParameterNames(getMethod("onePrimitive"),"call(bar *) && somepc(foo)", "foo");
|
||||
assertParameterNames(getMethod("onePrimitive"),"somepc ( foo )", "foo");
|
||||
assertParameterNames(getMethod("onePrimitive"),"somepc( foo)", "foo");
|
||||
assertParameterNames(getMethod("onePrimitive"),"call(bar *) && somepc(foo)", new String[] {"foo"});
|
||||
assertParameterNames(getMethod("onePrimitive"),"somepc ( foo )", new String[] {"foo"});
|
||||
assertParameterNames(getMethod("onePrimitive"),"somepc( foo)", new String[] {"foo"});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -229,38 +230,38 @@ class AspectJAdviceParameterNameDiscovererTests {
|
||||
|
||||
@Test
|
||||
void atThis() {
|
||||
assertParameterNames(getMethod("oneAnnotation"),"@this(a)", "a");
|
||||
assertParameterNames(getMethod("oneAnnotation"),"@this(a)", new String[] {"a"});
|
||||
}
|
||||
|
||||
@Test
|
||||
void atTarget() {
|
||||
assertParameterNames(getMethod("oneAnnotation"),"@target(a)", "a");
|
||||
assertParameterNames(getMethod("oneAnnotation"),"@target(a)", new String[] {"a"});
|
||||
}
|
||||
|
||||
@Test
|
||||
void atArgs() {
|
||||
assertParameterNames(getMethod("oneAnnotation"),"@args(a)", "a");
|
||||
assertParameterNames(getMethod("oneAnnotation"),"@args(a)", new String[] {"a"});
|
||||
}
|
||||
|
||||
@Test
|
||||
void atWithin() {
|
||||
assertParameterNames(getMethod("oneAnnotation"),"@within(a)", "a");
|
||||
assertParameterNames(getMethod("oneAnnotation"),"@within(a)", new String[] {"a"});
|
||||
}
|
||||
|
||||
@Test
|
||||
void atWithincode() {
|
||||
assertParameterNames(getMethod("oneAnnotation"),"@withincode(a)", "a");
|
||||
assertParameterNames(getMethod("oneAnnotation"),"@withincode(a)", new String[] {"a"});
|
||||
}
|
||||
|
||||
@Test
|
||||
void atAnnotation() {
|
||||
assertParameterNames(getMethod("oneAnnotation"),"@annotation(a)", "a");
|
||||
assertParameterNames(getMethod("oneAnnotation"),"@annotation(a)", new String[] {"a"});
|
||||
}
|
||||
|
||||
@Test
|
||||
void ambiguousAnnotationTwoVars() {
|
||||
assertException(getMethod("twoAnnotations"),"@annotation(a) && @this(x)", AmbiguousBindingException.class,
|
||||
"Found 2 potential annotation variable(s) and 2 potential argument slots");
|
||||
"Found 2 potential annotation variable(s), and 2 potential argument slots");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -271,14 +272,15 @@ class AspectJAdviceParameterNameDiscovererTests {
|
||||
|
||||
@Test
|
||||
void annotationMedley() {
|
||||
assertParameterNamesExtended(getMethod("annotationMedley"),"@annotation(a) && args(count) && this(foo)",
|
||||
null, "ex", "ex", "foo", "count", "a");
|
||||
assertParameterNames(getMethod("annotationMedley"),"@annotation(a) && args(count) && this(foo)",
|
||||
null, "ex", new String[] {"ex", "foo", "count", "a"});
|
||||
}
|
||||
|
||||
@Test
|
||||
void annotationBinding() {
|
||||
assertParameterNames(getMethod("pjpAndAnAnnotation"),
|
||||
"execution(* *(..)) && @annotation(ann)", "thisJoinPoint", "ann");
|
||||
"execution(* *(..)) && @annotation(ann)",
|
||||
new String[] {"thisJoinPoint","ann"});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -294,23 +296,33 @@ class AspectJAdviceParameterNameDiscovererTests {
|
||||
throw new AssertionError("Bad test specification, no method '" + name + "' found in test class");
|
||||
}
|
||||
|
||||
private void assertParameterNames(Method method, String pointcut, String... parameterNames) {
|
||||
assertParameterNamesExtended(method, pointcut, null, null, parameterNames);
|
||||
private void assertParameterNames(Method method, String pointcut, String[] parameterNames) {
|
||||
assertParameterNames(method, pointcut, null, null, parameterNames);
|
||||
}
|
||||
|
||||
private void assertParameterNamesExtended(
|
||||
Method method, String pointcut, String returning, String throwing, String... parameterNames) {
|
||||
private void assertParameterNames(
|
||||
Method method, String pointcut, String returning, String throwing, String[] parameterNames) {
|
||||
|
||||
assertThat(parameterNames)
|
||||
.as("bad test specification, must have same number of parameter names as method arguments")
|
||||
.hasSize(method.getParameterCount());
|
||||
assertThat(parameterNames.length).as("bad test specification, must have same number of parameter names as method arguments").isEqualTo(method.getParameterCount());
|
||||
|
||||
AspectJAdviceParameterNameDiscoverer discoverer = new AspectJAdviceParameterNameDiscoverer(pointcut);
|
||||
discoverer.setRaiseExceptions(true);
|
||||
discoverer.setReturningName(returning);
|
||||
discoverer.setThrowingName(throwing);
|
||||
String[] discoveredNames = discoverer.getParameterNames(method);
|
||||
|
||||
assertThat(discoverer.getParameterNames(method)).isEqualTo(parameterNames);
|
||||
String formattedExpectedNames = Arrays.toString(parameterNames);
|
||||
String formattedActualNames = Arrays.toString(discoveredNames);
|
||||
|
||||
assertThat(discoveredNames.length).as("Expecting " + parameterNames.length + " parameter names in return set '" +
|
||||
formattedExpectedNames + "', but found " + discoveredNames.length +
|
||||
" '" + formattedActualNames + "'").isEqualTo(parameterNames.length);
|
||||
|
||||
for (int i = 0; i < discoveredNames.length; i++) {
|
||||
assertThat(discoveredNames[i]).as("Parameter names must never be null").isNotNull();
|
||||
assertThat(discoveredNames[i]).as("Expecting parameter " + i + " to be named '" +
|
||||
parameterNames[i] + "' but was '" + discoveredNames[i] + "'").isEqualTo(parameterNames[i]);
|
||||
}
|
||||
}
|
||||
|
||||
private void assertException(Method method, String pointcut, Class<? extends Throwable> exceptionType, String message) {
|
||||
|
||||
+48
-44
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2023 the original author or authors.
|
||||
* Copyright 2002-2019 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.
|
||||
@@ -38,55 +38,56 @@ import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
|
||||
* @author Adrian Colyer
|
||||
* @author Juergen Hoeller
|
||||
* @author Chris Beams
|
||||
* @author Sam Brannen
|
||||
*/
|
||||
class ArgumentBindingTests {
|
||||
public class ArgumentBindingTests {
|
||||
|
||||
@Test
|
||||
void bindingInPointcutUsedByAdvice() {
|
||||
AspectJProxyFactory proxyFactory = new AspectJProxyFactory(new TestBean());
|
||||
public void testBindingInPointcutUsedByAdvice() {
|
||||
TestBean tb = new TestBean();
|
||||
AspectJProxyFactory proxyFactory = new AspectJProxyFactory(tb);
|
||||
proxyFactory.addAspect(NamedPointcutWithArgs.class);
|
||||
|
||||
ITestBean proxiedTestBean = proxyFactory.getProxy();
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> proxiedTestBean.setName("enigma"))
|
||||
.withMessage("enigma");
|
||||
assertThatIllegalArgumentException().isThrownBy(() ->
|
||||
proxiedTestBean.setName("Supercalifragalisticexpialidocious"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void annotationArgumentNameBinding() {
|
||||
AspectJProxyFactory proxyFactory = new AspectJProxyFactory(new TransactionalBean());
|
||||
public void testAnnotationArgumentNameBinding() {
|
||||
TransactionalBean tb = new TransactionalBean();
|
||||
AspectJProxyFactory proxyFactory = new AspectJProxyFactory(tb);
|
||||
proxyFactory.addAspect(PointcutWithAnnotationArgument.class);
|
||||
|
||||
ITransactionalBean proxiedTestBean = proxyFactory.getProxy();
|
||||
assertThatIllegalStateException()
|
||||
.isThrownBy(proxiedTestBean::doInTransaction)
|
||||
.withMessage("Invoked with @Transactional");
|
||||
assertThatIllegalStateException().isThrownBy(
|
||||
proxiedTestBean::doInTransaction);
|
||||
}
|
||||
|
||||
@Test
|
||||
void parameterNameDiscoverWithReferencePointcut() throws Exception {
|
||||
public void testParameterNameDiscoverWithReferencePointcut() throws Exception {
|
||||
AspectJAdviceParameterNameDiscoverer discoverer =
|
||||
new AspectJAdviceParameterNameDiscoverer("somepc(formal) && set(* *)");
|
||||
discoverer.setRaiseExceptions(true);
|
||||
Method method = getClass().getDeclaredMethod("methodWithOneParam", String.class);
|
||||
assertThat(discoverer.getParameterNames(method)).containsExactly("formal");
|
||||
Method methodUsedForParameterTypeDiscovery =
|
||||
getClass().getMethod("methodWithOneParam", String.class);
|
||||
String[] pnames = discoverer.getParameterNames(methodUsedForParameterTypeDiscovery);
|
||||
assertThat(pnames.length).as("one parameter name").isEqualTo(1);
|
||||
assertThat(pnames[0]).isEqualTo("formal");
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private void methodWithOneParam(String aParam) {
|
||||
public void methodWithOneParam(String aParam) {
|
||||
}
|
||||
|
||||
|
||||
interface ITransactionalBean {
|
||||
public interface ITransactionalBean {
|
||||
|
||||
@Transactional
|
||||
void doInTransaction();
|
||||
}
|
||||
|
||||
|
||||
static class TransactionalBean implements ITransactionalBean {
|
||||
public static class TransactionalBean implements ITransactionalBean {
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
@@ -94,35 +95,38 @@ class ArgumentBindingTests {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Mimics Spring's @Transactional annotation without actually introducing the dependency.
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@interface Transactional {
|
||||
}
|
||||
}
|
||||
|
||||
@Aspect
|
||||
static class PointcutWithAnnotationArgument {
|
||||
/**
|
||||
* Represents Spring's Transactional annotation without actually introducing the dependency
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@interface Transactional {
|
||||
}
|
||||
|
||||
@Around(value = "execution(* org.springframework..*.*(..)) && @annotation(transactional)")
|
||||
public Object around(ProceedingJoinPoint pjp, Transactional transactional) throws Throwable {
|
||||
throw new IllegalStateException("Invoked with @Transactional");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Aspect
|
||||
static class NamedPointcutWithArgs {
|
||||
|
||||
@Pointcut("execution(* *(..)) && args(s,..)")
|
||||
public void pointcutWithArgs(String s) {}
|
||||
|
||||
@Around("pointcutWithArgs(aString)")
|
||||
public Object doAround(ProceedingJoinPoint pjp, String aString) throws Throwable {
|
||||
throw new IllegalArgumentException(aString);
|
||||
}
|
||||
@Aspect
|
||||
class PointcutWithAnnotationArgument {
|
||||
|
||||
@Around(value = "execution(* org.springframework..*.*(..)) && @annotation(transaction)")
|
||||
public Object around(ProceedingJoinPoint pjp, Transactional transaction) throws Throwable {
|
||||
System.out.println("Invoked with transaction " + transaction);
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Aspect
|
||||
class NamedPointcutWithArgs {
|
||||
|
||||
@Pointcut("execution(* *(..)) && args(s,..)")
|
||||
public void pointcutWithArgs(String s) {}
|
||||
|
||||
@Around("pointcutWithArgs(aString)")
|
||||
public Object doAround(ProceedingJoinPoint pjp, String aString) throws Throwable {
|
||||
System.out.println("got '" + aString + "' at '" + pjp + "'");
|
||||
throw new IllegalArgumentException(aString);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+2
-4
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2023 the original author or authors.
|
||||
* Copyright 2002-2022 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.
|
||||
@@ -21,8 +21,6 @@ import java.lang.reflect.Method;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
* Abstract superclass for counting advices etc.
|
||||
*
|
||||
@@ -61,7 +59,7 @@ public class MethodCounter implements Serializable {
|
||||
* @see java.lang.Object#equals(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(@Nullable Object other) {
|
||||
public boolean equals(Object other) {
|
||||
return (other != null && other.getClass() == this.getClass());
|
||||
}
|
||||
|
||||
|
||||
+7
-9
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2023 the original author or authors.
|
||||
* Copyright 2002-2016 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.
|
||||
@@ -19,8 +19,6 @@ package org.springframework.aop.testfixture.interceptor;
|
||||
import org.aopalliance.intercept.MethodInterceptor;
|
||||
import org.aopalliance.intercept.MethodInvocation;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
* Trivial interceptor that can be introduced in a chain to display it.
|
||||
*
|
||||
@@ -47,14 +45,14 @@ public class NopInterceptor implements MethodInterceptor {
|
||||
|
||||
|
||||
@Override
|
||||
public boolean equals(@Nullable Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (!(obj instanceof NopInterceptor that)) {
|
||||
public boolean equals(Object other) {
|
||||
if (!(other instanceof NopInterceptor)) {
|
||||
return false;
|
||||
}
|
||||
return this.count == that.count;
|
||||
if (this == other) {
|
||||
return true;
|
||||
}
|
||||
return this.count == ((NopInterceptor) other).count;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+3
-4
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2023 the original author or authors.
|
||||
* Copyright 2002-2018 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.
|
||||
@@ -17,8 +17,8 @@
|
||||
package org.springframework.cache.aspectj;
|
||||
|
||||
/**
|
||||
* Utility to trick the compiler to throw valid checked exceptions masked as
|
||||
* runtime exceptions within the interceptor.
|
||||
* Utility to trick the compiler to throw a valid checked
|
||||
* exceptions within the interceptor.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
@@ -36,5 +36,4 @@ final class AnyThrow {
|
||||
private static <E extends Throwable> void throwAny(Throwable e) throws E {
|
||||
throw (E) e;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
-9
@@ -1,9 +0,0 @@
|
||||
/**
|
||||
* AspectJ-based caching support.
|
||||
*/
|
||||
@NonNullApi
|
||||
@NonNullFields
|
||||
package org.springframework.cache.aspectj;
|
||||
|
||||
import org.springframework.lang.NonNullApi;
|
||||
import org.springframework.lang.NonNullFields;
|
||||
-11
@@ -1,11 +0,0 @@
|
||||
/**
|
||||
* AspectJ-based dependency injection support driven by the
|
||||
* {@link org.springframework.beans.factory.annotation.Configurable @Configurable}
|
||||
* annotation.
|
||||
*/
|
||||
@NonNullApi
|
||||
@NonNullFields
|
||||
package org.springframework.context.annotation.aspectj;
|
||||
|
||||
import org.springframework.lang.NonNullApi;
|
||||
import org.springframework.lang.NonNullFields;
|
||||
@@ -1,9 +0,0 @@
|
||||
/**
|
||||
* AspectJ-based scheduling support.
|
||||
*/
|
||||
@NonNullApi
|
||||
@NonNullFields
|
||||
package org.springframework.scheduling.aspectj;
|
||||
|
||||
import org.springframework.lang.NonNullApi;
|
||||
import org.springframework.lang.NonNullFields;
|
||||
@@ -1,9 +0,0 @@
|
||||
/**
|
||||
* AspectJ-based transaction management support.
|
||||
*/
|
||||
@NonNullApi
|
||||
@NonNullFields
|
||||
package org.springframework.transaction.aspectj;
|
||||
|
||||
import org.springframework.lang.NonNullApi;
|
||||
import org.springframework.lang.NonNullFields;
|
||||
+9
-5
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2023 the original author or authors.
|
||||
* Copyright 2002-2019 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.
|
||||
@@ -16,7 +16,6 @@
|
||||
|
||||
package org.springframework.cache.config;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
/**
|
||||
@@ -46,11 +45,16 @@ public class TestEntity {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(@Nullable Object obj) {
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == this) {
|
||||
return true;
|
||||
}
|
||||
return (obj instanceof TestEntity that && ObjectUtils.nullSafeEquals(this.id, that.id));
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (obj instanceof TestEntity) {
|
||||
return ObjectUtils.nullSafeEquals(this.id, ((TestEntity) obj).id);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2023 the original author or authors.
|
||||
* Copyright 2002-2022 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.
|
||||
@@ -29,7 +29,6 @@ import java.time.temporal.Temporal;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
@@ -247,8 +246,7 @@ public abstract class BeanUtils {
|
||||
// A single public constructor
|
||||
return (Constructor<T>) ctors[0];
|
||||
}
|
||||
else if (ctors.length == 0) {
|
||||
// No public constructors -> check non-public
|
||||
else if (ctors.length == 0){
|
||||
ctors = clazz.getDeclaredConstructors();
|
||||
if (ctors.length == 1) {
|
||||
// A single non-public constructor, e.g. from a non-public record type
|
||||
@@ -792,11 +790,11 @@ public abstract class BeanUtils {
|
||||
actualEditable = editable;
|
||||
}
|
||||
PropertyDescriptor[] targetPds = getPropertyDescriptors(actualEditable);
|
||||
Set<String> ignoredProps = (ignoreProperties != null ? new HashSet<>(Arrays.asList(ignoreProperties)) : null);
|
||||
List<String> ignoreList = (ignoreProperties != null ? Arrays.asList(ignoreProperties) : null);
|
||||
|
||||
for (PropertyDescriptor targetPd : targetPds) {
|
||||
Method writeMethod = targetPd.getWriteMethod();
|
||||
if (writeMethod != null && (ignoredProps == null || !ignoredProps.contains(targetPd.getName()))) {
|
||||
if (writeMethod != null && (ignoreList == null || !ignoreList.contains(targetPd.getName()))) {
|
||||
PropertyDescriptor sourcePd = getPropertyDescriptor(source.getClass(), targetPd.getName());
|
||||
if (sourcePd != null) {
|
||||
Method readMethod = sourcePd.getReadMethod();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2023 the original author or authors.
|
||||
* Copyright 2002-2022 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.
|
||||
@@ -88,9 +88,8 @@ abstract class PropertyDescriptorUtils {
|
||||
BasicPropertyDescriptor pd = pdMap.get(propertyName);
|
||||
if (pd != null) {
|
||||
if (setter) {
|
||||
Method writeMethod = pd.getWriteMethod();
|
||||
if (writeMethod == null ||
|
||||
writeMethod.getParameterTypes()[0].isAssignableFrom(method.getParameterTypes()[0])) {
|
||||
if (pd.getWriteMethod() == null ||
|
||||
pd.getWriteMethod().getParameterTypes()[0].isAssignableFrom(method.getParameterTypes()[0])) {
|
||||
pd.setWriteMethod(method);
|
||||
}
|
||||
else {
|
||||
@@ -98,9 +97,8 @@ abstract class PropertyDescriptorUtils {
|
||||
}
|
||||
}
|
||||
else {
|
||||
Method readMethod = pd.getReadMethod();
|
||||
if (readMethod == null ||
|
||||
(readMethod.getReturnType() == method.getReturnType() && method.getName().startsWith("is"))) {
|
||||
if (pd.getReadMethod() == null ||
|
||||
(pd.getReadMethod().getReturnType() == method.getReturnType() && method.getName().startsWith("is"))) {
|
||||
pd.setReadMethod(method);
|
||||
}
|
||||
}
|
||||
|
||||
+2
-3
@@ -280,7 +280,6 @@ public class AutowiredAnnotationBeanPostProcessor implements SmartInstantiationA
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public BeanRegistrationAotContribution processAheadOfTime(RegisteredBean registeredBean) {
|
||||
Class<?> beanClass = registeredBean.getBeanClass();
|
||||
String beanName = registeredBean.getBeanName();
|
||||
@@ -324,10 +323,10 @@ public class AutowiredAnnotationBeanPostProcessor implements SmartInstantiationA
|
||||
checkLookupMethods(beanClass, beanName);
|
||||
|
||||
// Pick up subclass with fresh lookup method override from above
|
||||
if (this.beanFactory instanceof AbstractAutowireCapableBeanFactory aacBeanFactory) {
|
||||
if (this.beanFactory instanceof AbstractAutowireCapableBeanFactory aacbf) {
|
||||
RootBeanDefinition mbd = (RootBeanDefinition) this.beanFactory.getMergedBeanDefinition(beanName);
|
||||
if (mbd.getFactoryMethodName() == null && mbd.hasBeanClass()) {
|
||||
return aacBeanFactory.getInstantiationStrategy().getActualBeanClass(mbd, beanName, aacBeanFactory);
|
||||
return aacbf.getInstantiationStrategy().getActualBeanClass(mbd, beanName, this.beanFactory);
|
||||
}
|
||||
}
|
||||
return beanClass;
|
||||
|
||||
+1
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2023 the original author or authors.
|
||||
* Copyright 2002-2022 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.
|
||||
@@ -157,7 +157,6 @@ public class InitDestroyAnnotationBeanPostProcessor implements DestructionAwareB
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public BeanRegistrationAotContribution processAheadOfTime(RegisteredBean registeredBean) {
|
||||
RootBeanDefinition beanDefinition = registeredBean.getMergedBeanDefinition();
|
||||
beanDefinition.resolveDestroyMethodIfNecessary();
|
||||
|
||||
+2
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2023 the original author or authors.
|
||||
* Copyright 2002-2022 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.
|
||||
@@ -20,7 +20,6 @@ import java.util.stream.Stream;
|
||||
|
||||
import org.springframework.aot.hint.RuntimeHints;
|
||||
import org.springframework.aot.hint.RuntimeHintsRegistrar;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
/**
|
||||
@@ -32,7 +31,7 @@ import org.springframework.util.ClassUtils;
|
||||
class JakartaAnnotationsRuntimeHints implements RuntimeHintsRegistrar {
|
||||
|
||||
@Override
|
||||
public void registerHints(RuntimeHints hints, @Nullable ClassLoader classLoader) {
|
||||
public void registerHints(RuntimeHints hints, ClassLoader classLoader) {
|
||||
if (ClassUtils.isPresent("jakarta.inject.Inject", classLoader)) {
|
||||
Stream.of("jakarta.inject.Inject", "jakarta.inject.Qualifier").forEach(annotationType ->
|
||||
hints.reflection().registerType(ClassUtils.resolveClassName(annotationType, classLoader)));
|
||||
|
||||
+2
-4
@@ -25,7 +25,6 @@ import java.util.Set;
|
||||
|
||||
import org.springframework.beans.SimpleTypeConverter;
|
||||
import org.springframework.beans.TypeConverter;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||
import org.springframework.beans.factory.config.BeanDefinitionHolder;
|
||||
import org.springframework.beans.factory.config.DependencyDescriptor;
|
||||
@@ -241,11 +240,10 @@ public class QualifierAnnotationAutowireCandidateResolver extends GenericTypeAwa
|
||||
}
|
||||
}
|
||||
if (targetAnnotation == null) {
|
||||
BeanFactory beanFactory = getBeanFactory();
|
||||
// Look for matching annotation on the target class
|
||||
if (beanFactory != null) {
|
||||
if (getBeanFactory() != null) {
|
||||
try {
|
||||
Class<?> beanType = beanFactory.getType(bdHolder.getBeanName());
|
||||
Class<?> beanType = getBeanFactory().getType(bdHolder.getBeanName());
|
||||
if (beanType != null) {
|
||||
targetAnnotation = AnnotationUtils.getAnnotation(ClassUtils.getUserClass(beanType), type);
|
||||
}
|
||||
|
||||
+3
-3
@@ -138,7 +138,7 @@ class BeanDefinitionMethodGenerator {
|
||||
ClassName topLevelClassName = target.topLevelClassName();
|
||||
GeneratedClass generatedClass = generationContext.getGeneratedClasses()
|
||||
.getOrAddForFeatureComponent("BeanDefinitions", topLevelClassName, type -> {
|
||||
type.addJavadoc("Bean definitions for {@link $T}.", topLevelClassName);
|
||||
type.addJavadoc("Bean definitions for {@link $T}", topLevelClassName);
|
||||
type.addModifiers(Modifier.PUBLIC);
|
||||
});
|
||||
|
||||
@@ -159,7 +159,7 @@ class BeanDefinitionMethodGenerator {
|
||||
|
||||
private static GeneratedClass createInnerClass(GeneratedClass generatedClass, String name, ClassName target) {
|
||||
return generatedClass.getOrAdd(name, type -> {
|
||||
type.addJavadoc("Bean definitions for {@link $T}.", target);
|
||||
type.addJavadoc("Bean definitions for {@link $T}", target);
|
||||
type.addModifiers(Modifier.PUBLIC, Modifier.STATIC);
|
||||
});
|
||||
}
|
||||
@@ -186,7 +186,7 @@ class BeanDefinitionMethodGenerator {
|
||||
this.aotContributions.forEach(aotContribution -> aotContribution.applyTo(generationContext, codeGenerator));
|
||||
|
||||
return generatedMethods.add("getBeanDefinition", method -> {
|
||||
method.addJavadoc("Get the $L definition for '$L'.",
|
||||
method.addJavadoc("Get the $L definition for '$L'",
|
||||
(!this.registeredBean.isInnerBean()) ? "bean" : "inner-bean",
|
||||
getName());
|
||||
method.addModifiers(modifier, Modifier.STATIC);
|
||||
|
||||
+57
-38
@@ -27,9 +27,9 @@ import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.springframework.aot.hint.ExecutableMode;
|
||||
import org.springframework.beans.BeanInstantiationException;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.TypeConverter;
|
||||
import org.springframework.beans.factory.BeanCreationException;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.InjectionPoint;
|
||||
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||
@@ -97,13 +97,11 @@ public final class BeanInstanceSupplier<T> extends AutowiredElementResolver impl
|
||||
private BeanInstanceSupplier(ExecutableLookup lookup,
|
||||
@Nullable ThrowingBiFunction<RegisteredBean, AutowiredArguments, T> generator,
|
||||
@Nullable String[] shortcuts) {
|
||||
|
||||
this.lookup = lookup;
|
||||
this.generator = generator;
|
||||
this.shortcuts = shortcuts;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create a {@link BeanInstanceSupplier} that resolves
|
||||
* arguments for the specified bean constructor.
|
||||
@@ -111,7 +109,9 @@ public final class BeanInstanceSupplier<T> extends AutowiredElementResolver impl
|
||||
* @param parameterTypes the constructor parameter types
|
||||
* @return a new {@link BeanInstanceSupplier} instance
|
||||
*/
|
||||
public static <T> BeanInstanceSupplier<T> forConstructor(Class<?>... parameterTypes) {
|
||||
public static <T> BeanInstanceSupplier<T> forConstructor(
|
||||
Class<?>... parameterTypes) {
|
||||
|
||||
Assert.notNull(parameterTypes, "'parameterTypes' must not be null");
|
||||
Assert.noNullElements(parameterTypes, "'parameterTypes' must not contain null elements");
|
||||
return new BeanInstanceSupplier<>(new ConstructorLookup(parameterTypes), null, null);
|
||||
@@ -149,11 +149,11 @@ public final class BeanInstanceSupplier<T> extends AutowiredElementResolver impl
|
||||
* @param generator a {@link ThrowingBiFunction} that uses the
|
||||
* {@link RegisteredBean} and resolved {@link AutowiredArguments} to
|
||||
* instantiate the underlying bean
|
||||
* @return a new {@link BeanInstanceSupplier} instance with the specified generator
|
||||
* @return a new {@link BeanInstanceSupplier} instance with the specified
|
||||
* generator
|
||||
*/
|
||||
public BeanInstanceSupplier<T> withGenerator(
|
||||
ThrowingBiFunction<RegisteredBean, AutowiredArguments, T> generator) {
|
||||
|
||||
Assert.notNull(generator, "'generator' must not be null");
|
||||
return new BeanInstanceSupplier<>(this.lookup, generator, this.shortcuts);
|
||||
}
|
||||
@@ -163,9 +163,11 @@ public final class BeanInstanceSupplier<T> extends AutowiredElementResolver impl
|
||||
* {@code generator} function to instantiate the underlying bean.
|
||||
* @param generator a {@link ThrowingFunction} that uses the
|
||||
* {@link RegisteredBean} to instantiate the underlying bean
|
||||
* @return a new {@link BeanInstanceSupplier} instance with the specified generator
|
||||
* @return a new {@link BeanInstanceSupplier} instance with the specified
|
||||
* generator
|
||||
*/
|
||||
public BeanInstanceSupplier<T> withGenerator(ThrowingFunction<RegisteredBean, T> generator) {
|
||||
public BeanInstanceSupplier<T> withGenerator(
|
||||
ThrowingFunction<RegisteredBean, T> generator) {
|
||||
Assert.notNull(generator, "'generator' must not be null");
|
||||
return new BeanInstanceSupplier<>(this.lookup,
|
||||
(registeredBean, args) -> generator.apply(registeredBean), this.shortcuts);
|
||||
@@ -174,8 +176,10 @@ public final class BeanInstanceSupplier<T> extends AutowiredElementResolver impl
|
||||
/**
|
||||
* Return a new {@link BeanInstanceSupplier} instance that uses the specified
|
||||
* {@code generator} supplier to instantiate the underlying bean.
|
||||
* @param generator a {@link ThrowingSupplier} to instantiate the underlying bean
|
||||
* @return a new {@link BeanInstanceSupplier} instance with the specified generator
|
||||
* @param generator a {@link ThrowingSupplier} to instantiate the underlying
|
||||
* bean
|
||||
* @return a new {@link BeanInstanceSupplier} instance with the specified
|
||||
* generator
|
||||
*/
|
||||
public BeanInstanceSupplier<T> withGenerator(ThrowingSupplier<T> generator) {
|
||||
Assert.notNull(generator, "'generator' must not be null");
|
||||
@@ -278,7 +282,8 @@ public final class BeanInstanceSupplier<T> extends AutowiredElementResolver impl
|
||||
if (executable instanceof Method method) {
|
||||
return new MethodParameter(method, index);
|
||||
}
|
||||
throw new IllegalStateException("Unsupported executable: " + executable.getClass().getName());
|
||||
throw new IllegalStateException(
|
||||
"Unsupported executable " + executable.getClass().getName());
|
||||
}
|
||||
|
||||
private ConstructorArgumentValues resolveArgumentValues(
|
||||
@@ -298,7 +303,9 @@ public final class BeanInstanceSupplier<T> extends AutowiredElementResolver impl
|
||||
return resolved;
|
||||
}
|
||||
|
||||
private ValueHolder resolveArgumentValue(BeanDefinitionValueResolver resolver, ValueHolder valueHolder) {
|
||||
private ValueHolder resolveArgumentValue(BeanDefinitionValueResolver resolver,
|
||||
ValueHolder valueHolder) {
|
||||
|
||||
if (valueHolder.isConverted()) {
|
||||
return valueHolder;
|
||||
}
|
||||
@@ -324,7 +331,8 @@ public final class BeanInstanceSupplier<T> extends AutowiredElementResolver impl
|
||||
}
|
||||
try {
|
||||
try {
|
||||
return beanFactory.resolveDependency(dependencyDescriptor, beanName, autowiredBeans, typeConverter);
|
||||
return beanFactory.resolveDependency(dependencyDescriptor, beanName,
|
||||
autowiredBeans, typeConverter);
|
||||
}
|
||||
catch (NoSuchBeanDefinitionException ex) {
|
||||
if (parameterType.isArray()) {
|
||||
@@ -340,45 +348,47 @@ public final class BeanInstanceSupplier<T> extends AutowiredElementResolver impl
|
||||
}
|
||||
}
|
||||
catch (BeansException ex) {
|
||||
throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(parameter), ex);
|
||||
throw new UnsatisfiedDependencyException(null, beanName,
|
||||
new InjectionPoint(parameter), ex);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private T instantiate(ConfigurableBeanFactory beanFactory, Executable executable, Object[] args) {
|
||||
if (executable instanceof Constructor<?> constructor) {
|
||||
try {
|
||||
return (T) instantiate(constructor, args);
|
||||
private T instantiate(ConfigurableBeanFactory beanFactory, Executable executable,
|
||||
Object[] arguments) {
|
||||
|
||||
try {
|
||||
if (executable instanceof Constructor<?> constructor) {
|
||||
return (T) instantiate(constructor, arguments);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw new BeanInstantiationException(constructor, ex.getMessage(), ex);
|
||||
if (executable instanceof Method method) {
|
||||
return (T) instantiate(beanFactory, method, arguments);
|
||||
}
|
||||
}
|
||||
if (executable instanceof Method method) {
|
||||
try {
|
||||
return (T) instantiate(beanFactory, method, args);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw new BeanInstantiationException(method, ex.getMessage(), ex);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw new BeanCreationException(
|
||||
"Unable to instantiate bean using " + executable, ex);
|
||||
}
|
||||
throw new IllegalStateException("Unsupported executable " + executable.getClass().getName());
|
||||
throw new IllegalStateException(
|
||||
"Unsupported executable " + executable.getClass().getName());
|
||||
}
|
||||
|
||||
private Object instantiate(Constructor<?> constructor, Object[] args) throws Exception {
|
||||
private Object instantiate(Constructor<?> constructor, Object[] arguments) throws Exception {
|
||||
Class<?> declaringClass = constructor.getDeclaringClass();
|
||||
if (ClassUtils.isInnerClass(declaringClass)) {
|
||||
Object enclosingInstance = createInstance(declaringClass.getEnclosingClass());
|
||||
args = ObjectUtils.addObjectToArray(args, enclosingInstance, 0);
|
||||
arguments = ObjectUtils.addObjectToArray(arguments, enclosingInstance, 0);
|
||||
}
|
||||
ReflectionUtils.makeAccessible(constructor);
|
||||
return constructor.newInstance(args);
|
||||
return constructor.newInstance(arguments);
|
||||
}
|
||||
|
||||
private Object instantiate(ConfigurableBeanFactory beanFactory, Method method, Object[] args) throws Exception {
|
||||
Object target = getFactoryMethodTarget(beanFactory, method);
|
||||
private Object instantiate(ConfigurableBeanFactory beanFactory, Method method,
|
||||
Object[] arguments) {
|
||||
|
||||
ReflectionUtils.makeAccessible(method);
|
||||
return method.invoke(target, args);
|
||||
Object target = getFactoryMethodTarget(beanFactory, method);
|
||||
return ReflectionUtils.invokeMethod(method, target, arguments);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -406,13 +416,13 @@ public final class BeanInstanceSupplier<T> extends AutowiredElementResolver impl
|
||||
return Arrays.stream(parameterTypes).map(Class::getName).collect(Collectors.joining(", "));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Performs lookup of the {@link Executable}.
|
||||
*/
|
||||
static abstract class ExecutableLookup {
|
||||
|
||||
abstract Executable get(RegisteredBean registeredBean);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -423,10 +433,12 @@ public final class BeanInstanceSupplier<T> extends AutowiredElementResolver impl
|
||||
|
||||
private final Class<?>[] parameterTypes;
|
||||
|
||||
|
||||
ConstructorLookup(Class<?>[] parameterTypes) {
|
||||
this.parameterTypes = parameterTypes;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Executable get(RegisteredBean registeredBean) {
|
||||
Class<?> beanClass = registeredBean.getBeanClass();
|
||||
@@ -444,8 +456,10 @@ public final class BeanInstanceSupplier<T> extends AutowiredElementResolver impl
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Constructor with parameter types [%s]".formatted(toCommaSeparatedNames(this.parameterTypes));
|
||||
return "Constructor with parameter types [%s]".formatted(
|
||||
toCommaSeparatedNames(this.parameterTypes));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -460,19 +474,23 @@ public final class BeanInstanceSupplier<T> extends AutowiredElementResolver impl
|
||||
|
||||
private final Class<?>[] parameterTypes;
|
||||
|
||||
FactoryMethodLookup(Class<?> declaringClass, String methodName, Class<?>[] parameterTypes) {
|
||||
|
||||
FactoryMethodLookup(Class<?> declaringClass, String methodName,
|
||||
Class<?>[] parameterTypes) {
|
||||
this.declaringClass = declaringClass;
|
||||
this.methodName = methodName;
|
||||
this.parameterTypes = parameterTypes;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Executable get(RegisteredBean registeredBean) {
|
||||
return get();
|
||||
}
|
||||
|
||||
Method get() {
|
||||
Method method = ReflectionUtils.findMethod(this.declaringClass, this.methodName, this.parameterTypes);
|
||||
Method method = ReflectionUtils.findMethod(this.declaringClass,
|
||||
this.methodName, this.parameterTypes);
|
||||
Assert.notNull(method, () -> "%s cannot be found".formatted(this));
|
||||
return method;
|
||||
}
|
||||
@@ -483,6 +501,7 @@ public final class BeanInstanceSupplier<T> extends AutowiredElementResolver impl
|
||||
this.methodName, toCommaSeparatedNames(this.parameterTypes),
|
||||
this.declaringClass);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2023 the original author or authors.
|
||||
* Copyright 2002-2022 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.
|
||||
|
||||
+4
-4
@@ -130,10 +130,10 @@ public interface AutowireCapableBeanFactory extends BeanFactory {
|
||||
* {@link BeanPostProcessor BeanPostProcessors}.
|
||||
* <p>Note: This is intended for creating a fresh instance, populating annotated
|
||||
* fields and methods as well as applying all standard bean initialization callbacks.
|
||||
* Constructor resolution is based on Kotlin primary / single public / single non-public,
|
||||
* with a fallback to the default constructor in ambiguous scenarios, also influenced
|
||||
* by {@link SmartInstantiationAwareBeanPostProcessor#determineCandidateConstructors}
|
||||
* (e.g. for annotation-driven constructor selection).
|
||||
* Constructor resolution is done via {@link #AUTOWIRE_CONSTRUCTOR}, also influenced
|
||||
* by {@link SmartInstantiationAwareBeanPostProcessor#determineCandidateConstructors}.
|
||||
* It does <i>not</i> imply traditional by-name or by-type autowiring of properties;
|
||||
* use {@link #createBean(Class, int, boolean)} for those purposes.
|
||||
* @param beanClass the class of the bean to create
|
||||
* @return the new bean instance
|
||||
* @throws BeansException if instantiation or wiring failed
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2023 the original author or authors.
|
||||
* Copyright 2002-2022 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.
|
||||
@@ -188,7 +188,7 @@ public class ConstructorArgumentValues {
|
||||
* rather than matched multiple times.
|
||||
* @param value the argument value
|
||||
*/
|
||||
public void addGenericArgumentValue(@Nullable Object value) {
|
||||
public void addGenericArgumentValue(Object value) {
|
||||
this.genericArgumentValues.add(new ValueHolder(value));
|
||||
}
|
||||
|
||||
|
||||
-4
@@ -53,7 +53,6 @@ import org.springframework.beans.factory.xml.XmlReaderContext;
|
||||
import org.springframework.core.io.DescriptiveResource;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.core.io.support.EncodedResource;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
@@ -150,10 +149,8 @@ public class GroovyBeanDefinitionReader extends AbstractBeanDefinitionReader imp
|
||||
|
||||
private MetaClass metaClass = GroovySystem.getMetaClassRegistry().getMetaClass(getClass());
|
||||
|
||||
@Nullable
|
||||
private Binding binding;
|
||||
|
||||
@Nullable
|
||||
private GroovyBeanDefinitionWrapper currentBeanDefinition;
|
||||
|
||||
|
||||
@@ -206,7 +203,6 @@ public class GroovyBeanDefinitionReader extends AbstractBeanDefinitionReader imp
|
||||
/**
|
||||
* Return a specified binding for Groovy variables, if any.
|
||||
*/
|
||||
@Nullable
|
||||
public Binding getBinding() {
|
||||
return this.binding;
|
||||
}
|
||||
|
||||
+30
-28
@@ -16,9 +16,9 @@
|
||||
|
||||
package org.springframework.beans.factory.groovy;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import groovy.lang.GroovyObjectSupport;
|
||||
|
||||
@@ -30,8 +30,6 @@ import org.springframework.beans.factory.config.ConstructorArgumentValues;
|
||||
import org.springframework.beans.factory.config.RuntimeBeanReference;
|
||||
import org.springframework.beans.factory.support.AbstractBeanDefinition;
|
||||
import org.springframework.beans.factory.support.GenericBeanDefinition;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
/**
|
||||
@@ -53,54 +51,58 @@ class GroovyBeanDefinitionWrapper extends GroovyObjectSupport {
|
||||
private static final String DESTROY_METHOD = "destroyMethod";
|
||||
private static final String SINGLETON = "singleton";
|
||||
|
||||
private static final Set<String> dynamicProperties = Set.of(PARENT, AUTOWIRE, CONSTRUCTOR_ARGS,
|
||||
FACTORY_BEAN, FACTORY_METHOD, INIT_METHOD, DESTROY_METHOD, SINGLETON);
|
||||
private static final List<String> dynamicProperties = new ArrayList<>(8);
|
||||
|
||||
static {
|
||||
dynamicProperties.add(PARENT);
|
||||
dynamicProperties.add(AUTOWIRE);
|
||||
dynamicProperties.add(CONSTRUCTOR_ARGS);
|
||||
dynamicProperties.add(FACTORY_BEAN);
|
||||
dynamicProperties.add(FACTORY_METHOD);
|
||||
dynamicProperties.add(INIT_METHOD);
|
||||
dynamicProperties.add(DESTROY_METHOD);
|
||||
dynamicProperties.add(SINGLETON);
|
||||
}
|
||||
|
||||
|
||||
@Nullable
|
||||
private String beanName;
|
||||
|
||||
@Nullable
|
||||
private final Class<?> clazz;
|
||||
private Class<?> clazz;
|
||||
|
||||
@Nullable
|
||||
private final Collection<?> constructorArgs;
|
||||
private Collection<?> constructorArgs;
|
||||
|
||||
@Nullable
|
||||
private AbstractBeanDefinition definition;
|
||||
|
||||
@Nullable
|
||||
private BeanWrapper definitionWrapper;
|
||||
|
||||
@Nullable
|
||||
private String parentName;
|
||||
|
||||
|
||||
GroovyBeanDefinitionWrapper(String beanName) {
|
||||
this(beanName, null);
|
||||
public GroovyBeanDefinitionWrapper(String beanName) {
|
||||
this.beanName = beanName;
|
||||
}
|
||||
|
||||
GroovyBeanDefinitionWrapper(@Nullable String beanName, @Nullable Class<?> clazz) {
|
||||
this(beanName, clazz, null);
|
||||
public GroovyBeanDefinitionWrapper(String beanName, Class<?> clazz) {
|
||||
this.beanName = beanName;
|
||||
this.clazz = clazz;
|
||||
}
|
||||
|
||||
GroovyBeanDefinitionWrapper(@Nullable String beanName, Class<?> clazz, @Nullable Collection<?> constructorArgs) {
|
||||
public GroovyBeanDefinitionWrapper(String beanName, Class<?> clazz, Collection<?> constructorArgs) {
|
||||
this.beanName = beanName;
|
||||
this.clazz = clazz;
|
||||
this.constructorArgs = constructorArgs;
|
||||
}
|
||||
|
||||
|
||||
@Nullable
|
||||
public String getBeanName() {
|
||||
return this.beanName;
|
||||
}
|
||||
|
||||
void setBeanDefinition(AbstractBeanDefinition definition) {
|
||||
public void setBeanDefinition(AbstractBeanDefinition definition) {
|
||||
this.definition = definition;
|
||||
}
|
||||
|
||||
AbstractBeanDefinition getBeanDefinition() {
|
||||
public AbstractBeanDefinition getBeanDefinition() {
|
||||
if (this.definition == null) {
|
||||
this.definition = createBeanDefinition();
|
||||
}
|
||||
@@ -124,17 +126,19 @@ class GroovyBeanDefinitionWrapper extends GroovyObjectSupport {
|
||||
return bd;
|
||||
}
|
||||
|
||||
void setBeanDefinitionHolder(BeanDefinitionHolder holder) {
|
||||
public void setBeanDefinitionHolder(BeanDefinitionHolder holder) {
|
||||
this.definition = (AbstractBeanDefinition) holder.getBeanDefinition();
|
||||
this.beanName = holder.getBeanName();
|
||||
}
|
||||
|
||||
BeanDefinitionHolder getBeanDefinitionHolder() {
|
||||
public BeanDefinitionHolder getBeanDefinitionHolder() {
|
||||
return new BeanDefinitionHolder(getBeanDefinition(), getBeanName());
|
||||
}
|
||||
|
||||
void setParent(Object obj) {
|
||||
Assert.notNull(obj, "Parent bean cannot be set to a null runtime bean reference.");
|
||||
public void setParent(Object obj) {
|
||||
if (obj == null) {
|
||||
throw new IllegalArgumentException("Parent bean cannot be set to a null runtime bean reference!");
|
||||
}
|
||||
if (obj instanceof String name) {
|
||||
this.parentName = name;
|
||||
}
|
||||
@@ -148,7 +152,7 @@ class GroovyBeanDefinitionWrapper extends GroovyObjectSupport {
|
||||
getBeanDefinition().setAbstract(false);
|
||||
}
|
||||
|
||||
GroovyBeanDefinitionWrapper addProperty(String propertyName, Object propertyValue) {
|
||||
public GroovyBeanDefinitionWrapper addProperty(String propertyName, Object propertyValue) {
|
||||
if (propertyValue instanceof GroovyBeanDefinitionWrapper wrapper) {
|
||||
propertyValue = wrapper.getBeanDefinition();
|
||||
}
|
||||
@@ -159,7 +163,6 @@ class GroovyBeanDefinitionWrapper extends GroovyObjectSupport {
|
||||
|
||||
@Override
|
||||
public Object getProperty(String property) {
|
||||
Assert.state(this.definitionWrapper != null, "BeanDefinition wrapper not initialized");
|
||||
if (this.definitionWrapper.isReadableProperty(property)) {
|
||||
return this.definitionWrapper.getPropertyValue(property);
|
||||
}
|
||||
@@ -176,7 +179,6 @@ class GroovyBeanDefinitionWrapper extends GroovyObjectSupport {
|
||||
}
|
||||
else {
|
||||
AbstractBeanDefinition bd = getBeanDefinition();
|
||||
Assert.state(this.definitionWrapper != null, "BeanDefinition wrapper not initialized");
|
||||
if (AUTOWIRE.equals(property)) {
|
||||
if ("byName".equals(newValue)) {
|
||||
bd.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_NAME);
|
||||
|
||||
+1
-4
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2023 the original author or authors.
|
||||
* Copyright 2002-2022 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.
|
||||
@@ -31,7 +31,6 @@ import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.config.BeanDefinitionHolder;
|
||||
import org.springframework.beans.factory.support.AbstractBeanDefinition;
|
||||
import org.springframework.beans.factory.xml.BeanDefinitionParserDelegate;
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
* Used by GroovyBeanDefinitionReader to read a Spring XML namespace expression
|
||||
@@ -69,7 +68,6 @@ class GroovyDynamicElementReader extends GroovyObjectSupport {
|
||||
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public Object invokeMethod(String name, Object obj) {
|
||||
Object[] args = (Object[]) obj;
|
||||
if (name.equals("doCall")) {
|
||||
@@ -90,7 +88,6 @@ class GroovyDynamicElementReader extends GroovyObjectSupport {
|
||||
String myNamespace = this.rootNamespace;
|
||||
Map<String, String> myNamespaces = this.xmlNamespaces;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
Closure<Object> callable = new Closure<>(this) {
|
||||
@Override
|
||||
public Object call(Object... arguments) {
|
||||
|
||||
@@ -1,9 +1,4 @@
|
||||
/**
|
||||
* Support package for Groovy-based bean definitions.
|
||||
*/
|
||||
@NonNullApi
|
||||
@NonNullFields
|
||||
package org.springframework.beans.factory.groovy;
|
||||
|
||||
import org.springframework.lang.NonNullApi;
|
||||
import org.springframework.lang.NonNullFields;
|
||||
|
||||
+32
-81
@@ -61,6 +61,7 @@ import org.springframework.beans.factory.config.AutowiredPropertyMarker;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.config.BeanPostProcessor;
|
||||
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.beans.factory.config.ConstructorArgumentValues;
|
||||
import org.springframework.beans.factory.config.DependencyDescriptor;
|
||||
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor;
|
||||
@@ -314,7 +315,8 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> T createBean(Class<T> beanClass) throws BeansException {
|
||||
// Use non-singleton bean definition, to avoid registering bean as dependent bean.
|
||||
RootBeanDefinition bd = new CreateFromClassBeanDefinition(beanClass);
|
||||
RootBeanDefinition bd = new RootBeanDefinition(beanClass);
|
||||
bd.setAutowireMode(AUTOWIRE_CONSTRUCTOR);
|
||||
bd.setScope(SCOPE_PROTOTYPE);
|
||||
bd.allowCaching = ClassUtils.isCacheSafe(beanClass, getBeanClassLoader());
|
||||
return (T) createBean(beanClass.getName(), bd, null);
|
||||
@@ -754,15 +756,13 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
||||
if (candidate.getTypeParameters().length > 0) {
|
||||
try {
|
||||
// Fully resolve parameter names and argument values.
|
||||
ConstructorArgumentValues cav = mbd.getConstructorArgumentValues();
|
||||
Class<?>[] paramTypes = candidate.getParameterTypes();
|
||||
String[] paramNames = null;
|
||||
if (cav.containsNamedArgument()) {
|
||||
ParameterNameDiscoverer pnd = getParameterNameDiscoverer();
|
||||
if (pnd != null) {
|
||||
paramNames = pnd.getParameterNames(candidate);
|
||||
}
|
||||
ParameterNameDiscoverer pnd = getParameterNameDiscoverer();
|
||||
if (pnd != null) {
|
||||
paramNames = pnd.getParameterNames(candidate);
|
||||
}
|
||||
ConstructorArgumentValues cav = mbd.getConstructorArgumentValues();
|
||||
Set<ConstructorArgumentValues.ValueHolder> usedValueHolders = new HashSet<>(paramTypes.length);
|
||||
Object[] args = new Object[paramTypes.length];
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
@@ -1155,7 +1155,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
||||
|
||||
Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
|
||||
if (instanceSupplier != null) {
|
||||
return obtainFromSupplier(instanceSupplier, beanName, mbd);
|
||||
return obtainFromSupplier(instanceSupplier, beanName);
|
||||
}
|
||||
|
||||
if (mbd.getFactoryMethodName() != null) {
|
||||
@@ -1204,20 +1204,38 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
||||
* @param supplier the configured supplier
|
||||
* @param beanName the corresponding bean name
|
||||
* @return a BeanWrapper for the new instance
|
||||
* @since 5.0
|
||||
* @see #getObjectForBeanInstance
|
||||
*/
|
||||
private BeanWrapper obtainFromSupplier(Supplier<?> supplier, String beanName, RootBeanDefinition mbd) {
|
||||
protected BeanWrapper obtainFromSupplier(Supplier<?> supplier, String beanName) {
|
||||
Object instance = obtainInstanceFromSupplier(supplier, beanName);
|
||||
if (instance == null) {
|
||||
instance = new NullBean();
|
||||
}
|
||||
BeanWrapper bw = new BeanWrapperImpl(instance);
|
||||
initBeanWrapper(bw);
|
||||
return bw;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private Object obtainInstanceFromSupplier(Supplier<?> supplier, String beanName) {
|
||||
String outerBean = this.currentlyCreatedBean.get();
|
||||
this.currentlyCreatedBean.set(beanName);
|
||||
Object instance;
|
||||
|
||||
try {
|
||||
instance = obtainInstanceFromSupplier(supplier, beanName, mbd);
|
||||
if (supplier instanceof InstanceSupplier<?> instanceSupplier) {
|
||||
return instanceSupplier.get(RegisteredBean.of((ConfigurableListableBeanFactory) this, beanName));
|
||||
}
|
||||
if (supplier instanceof ThrowingSupplier<?> throwableSupplier) {
|
||||
return throwableSupplier.getWithException();
|
||||
}
|
||||
return supplier.get();
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
if (ex instanceof BeansException beansException) {
|
||||
throw beansException;
|
||||
}
|
||||
throw new BeanCreationException(beanName, "Instantiation of supplied bean failed", ex);
|
||||
throw new BeanCreationException(beanName,
|
||||
"Instantiation of supplied bean failed", ex);
|
||||
}
|
||||
finally {
|
||||
if (outerBean != null) {
|
||||
@@ -1227,31 +1245,6 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
||||
this.currentlyCreatedBean.remove();
|
||||
}
|
||||
}
|
||||
|
||||
if (instance == null) {
|
||||
instance = new NullBean();
|
||||
}
|
||||
BeanWrapper bw = new BeanWrapperImpl(instance);
|
||||
initBeanWrapper(bw);
|
||||
return bw;
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtain a bean instance from the given supplier.
|
||||
* @param supplier the configured supplier
|
||||
* @param beanName the corresponding bean name
|
||||
* @param mbd the bean definition for the bean
|
||||
* @return the bean instance (possibly {@code null})
|
||||
* @since 6.0.7
|
||||
*/
|
||||
@Nullable
|
||||
protected Object obtainInstanceFromSupplier(Supplier<?> supplier, String beanName, RootBeanDefinition mbd)
|
||||
throws Exception {
|
||||
|
||||
if (supplier instanceof ThrowingSupplier<?> throwingSupplier) {
|
||||
return throwingSupplier.getWithException();
|
||||
}
|
||||
return supplier.get();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1371,17 +1364,6 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
||||
}
|
||||
}
|
||||
|
||||
if (bw.getWrappedClass().isRecord()) {
|
||||
if (mbd.hasPropertyValues()) {
|
||||
throw new BeanCreationException(
|
||||
mbd.getResourceDescription(), beanName, "Cannot apply property values to a record");
|
||||
}
|
||||
else {
|
||||
// Skip property population phase for records since they are immutable.
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
|
||||
// state of the bean before properties are set. This can be used, for example,
|
||||
// to support styles of field injection.
|
||||
@@ -1916,36 +1898,6 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* {@link RootBeanDefinition} subclass for {@code #createBean} calls with
|
||||
* flexible selection of a Kotlin primary / single public / single non-public
|
||||
* constructor candidate in addition to the default constructor.
|
||||
* @see BeanUtils#getResolvableConstructor(Class)
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
private static class CreateFromClassBeanDefinition extends RootBeanDefinition {
|
||||
|
||||
public CreateFromClassBeanDefinition(Class<?> beanClass) {
|
||||
super(beanClass);
|
||||
}
|
||||
|
||||
public CreateFromClassBeanDefinition(CreateFromClassBeanDefinition original) {
|
||||
super(original);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public Constructor<?>[] getPreferredConstructors() {
|
||||
return ConstructorResolver.determinePreferredConstructors(getBeanClass());
|
||||
}
|
||||
|
||||
@Override
|
||||
public RootBeanDefinition cloneBeanDefinition() {
|
||||
return new CreateFromClassBeanDefinition(this);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Special DependencyDescriptor variant for Spring's good old autowire="byType" mode.
|
||||
* Always optional; never considering the parameter name for choosing a primary candidate.
|
||||
@@ -1958,7 +1910,6 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public String getDependencyName() {
|
||||
return null;
|
||||
}
|
||||
@@ -1979,7 +1930,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doWith(Method method) throws IllegalArgumentException {
|
||||
public void doWith(Method method) throws IllegalArgumentException, IllegalAccessException {
|
||||
if (isFactoryBeanMethod(method)) {
|
||||
ResolvableType returnType = ResolvableType.forMethodReturnType(method);
|
||||
ResolvableType candidate = returnType.as(FactoryBean.class).getGeneric();
|
||||
|
||||
+7
-11
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2023 the original author or authors.
|
||||
* Copyright 2002-2022 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.
|
||||
@@ -853,12 +853,10 @@ public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccess
|
||||
*/
|
||||
@Override
|
||||
public ConstructorArgumentValues getConstructorArgumentValues() {
|
||||
ConstructorArgumentValues cav = this.constructorArgumentValues;
|
||||
if (cav == null) {
|
||||
cav = new ConstructorArgumentValues();
|
||||
this.constructorArgumentValues = cav;
|
||||
if (this.constructorArgumentValues == null) {
|
||||
this.constructorArgumentValues = new ConstructorArgumentValues();
|
||||
}
|
||||
return cav;
|
||||
return this.constructorArgumentValues;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -881,12 +879,10 @@ public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccess
|
||||
*/
|
||||
@Override
|
||||
public MutablePropertyValues getPropertyValues() {
|
||||
MutablePropertyValues pvs = this.propertyValues;
|
||||
if (pvs == null) {
|
||||
pvs = new MutablePropertyValues();
|
||||
this.propertyValues = pvs;
|
||||
if (this.propertyValues == null) {
|
||||
this.propertyValues = new MutablePropertyValues();
|
||||
}
|
||||
return pvs;
|
||||
return this.propertyValues;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
-48
@@ -1222,54 +1222,6 @@ class ConstructorResolver {
|
||||
return old;
|
||||
}
|
||||
|
||||
/**
|
||||
* See {@link BeanUtils#getResolvableConstructor(Class)} for alignment.
|
||||
* This variant adds a lenient fallback to the default constructor if available, similar to
|
||||
* {@link org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor#determineCandidateConstructors}.
|
||||
*/
|
||||
@Nullable
|
||||
static Constructor<?>[] determinePreferredConstructors(Class<?> clazz) {
|
||||
Constructor<?> primaryCtor = BeanUtils.findPrimaryConstructor(clazz);
|
||||
|
||||
Constructor<?> defaultCtor;
|
||||
try {
|
||||
defaultCtor = clazz.getDeclaredConstructor();
|
||||
}
|
||||
catch (NoSuchMethodException ex) {
|
||||
defaultCtor = null;
|
||||
}
|
||||
|
||||
if (primaryCtor != null) {
|
||||
if (defaultCtor != null && !primaryCtor.equals(defaultCtor)) {
|
||||
return new Constructor<?>[] {primaryCtor, defaultCtor};
|
||||
}
|
||||
else {
|
||||
return new Constructor<?>[] {primaryCtor};
|
||||
}
|
||||
}
|
||||
|
||||
Constructor<?>[] ctors = clazz.getConstructors();
|
||||
if (ctors.length == 1) {
|
||||
// A single public constructor, potentially in combination with a non-public default constructor
|
||||
if (defaultCtor != null && !ctors[0].equals(defaultCtor)) {
|
||||
return new Constructor<?>[] {ctors[0], defaultCtor};
|
||||
}
|
||||
else {
|
||||
return ctors;
|
||||
}
|
||||
}
|
||||
else if (ctors.length == 0) {
|
||||
// No public constructors -> check non-public
|
||||
ctors = clazz.getDeclaredConstructors();
|
||||
if (ctors.length == 1) {
|
||||
// A single non-public constructor, e.g. from a non-public record type
|
||||
return ctors;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Private inner class for holding argument combinations.
|
||||
|
||||
+2
-14
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2023 the original author or authors.
|
||||
* Copyright 2002-2022 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.
|
||||
@@ -40,7 +40,6 @@ import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import jakarta.inject.Provider;
|
||||
@@ -938,17 +937,6 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
||||
return (this.configurationFrozen || super.isBeanEligibleForMetadataCaching(beanName));
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
protected Object obtainInstanceFromSupplier(Supplier<?> supplier, String beanName, RootBeanDefinition mbd)
|
||||
throws Exception {
|
||||
|
||||
if (supplier instanceof InstanceSupplier<?> instanceSupplier) {
|
||||
return instanceSupplier.get(RegisteredBean.of(this, beanName, mbd));
|
||||
}
|
||||
return super.obtainInstanceFromSupplier(supplier, beanName, mbd);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void preInstantiateSingletons() throws BeansException {
|
||||
if (logger.isTraceEnabled()) {
|
||||
@@ -1732,7 +1720,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
||||
if (beanInstance != null) {
|
||||
Integer candidatePriority = getPriority(beanInstance);
|
||||
if (candidatePriority != null) {
|
||||
if (highestPriority != null) {
|
||||
if (highestPriorityBeanName != null) {
|
||||
if (candidatePriority.equals(highestPriority)) {
|
||||
throw new NoUniqueBeanDefinitionException(requiredType, candidates.size(),
|
||||
"Multiple beans found with the same priority ('" + highestPriority +
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2023 the original author or authors.
|
||||
* Copyright 2002-2020 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.
|
||||
@@ -340,7 +340,7 @@ public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements
|
||||
* (within the entire factory).
|
||||
* @param beanName the name of the bean
|
||||
*/
|
||||
public boolean isSingletonCurrentlyInCreation(@Nullable String beanName) {
|
||||
public boolean isSingletonCurrentlyInCreation(String beanName) {
|
||||
return this.singletonsCurrentlyInCreation.contains(beanName);
|
||||
}
|
||||
|
||||
|
||||
+9
-7
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2023 the original author or authors.
|
||||
* Copyright 2002-2022 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.
|
||||
@@ -35,7 +35,6 @@ import org.springframework.util.function.ThrowingSupplier;
|
||||
* @since 6.0
|
||||
* @param <T> the type of instance supplied by this supplier
|
||||
* @see RegisteredBean
|
||||
* @see org.springframework.beans.factory.aot.BeanInstanceSupplier
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface InstanceSupplier<T> extends ThrowingSupplier<T> {
|
||||
@@ -75,17 +74,19 @@ public interface InstanceSupplier<T> extends ThrowingSupplier<T> {
|
||||
*/
|
||||
default <V> InstanceSupplier<V> andThen(
|
||||
ThrowingBiFunction<RegisteredBean, ? super T, ? extends V> after) {
|
||||
|
||||
Assert.notNull(after, "'after' function must not be null");
|
||||
return new InstanceSupplier<>() {
|
||||
|
||||
@Override
|
||||
public V get(RegisteredBean registeredBean) throws Exception {
|
||||
return after.applyWithException(registeredBean, InstanceSupplier.this.get(registeredBean));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Method getFactoryMethod() {
|
||||
return InstanceSupplier.this.getFactoryMethod();
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
@@ -114,21 +115,22 @@ public interface InstanceSupplier<T> extends ThrowingSupplier<T> {
|
||||
*/
|
||||
static <T> InstanceSupplier<T> using(@Nullable Method factoryMethod, ThrowingSupplier<T> supplier) {
|
||||
Assert.notNull(supplier, "Supplier must not be null");
|
||||
|
||||
if (supplier instanceof InstanceSupplier<T> instanceSupplier &&
|
||||
instanceSupplier.getFactoryMethod() == factoryMethod) {
|
||||
if (supplier instanceof InstanceSupplier<T> instanceSupplier
|
||||
&& instanceSupplier.getFactoryMethod() == factoryMethod) {
|
||||
return instanceSupplier;
|
||||
}
|
||||
|
||||
return new InstanceSupplier<>() {
|
||||
|
||||
@Override
|
||||
public T get(RegisteredBean registeredBean) throws Exception {
|
||||
return supplier.getWithException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Method getFactoryMethod() {
|
||||
return factoryMethod;
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
+18
-19
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2023 the original author or authors.
|
||||
* Copyright 2002-2022 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.
|
||||
@@ -80,18 +80,6 @@ public final class RegisteredBean {
|
||||
null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new {@link RegisteredBean} instance for a regular bean.
|
||||
* @param beanFactory the source bean factory
|
||||
* @param beanName the bean name
|
||||
* @param mbd the pre-determined merged bean definition
|
||||
* @return a new {@link RegisteredBean} instance
|
||||
* @since 6.0.7
|
||||
*/
|
||||
static RegisteredBean of(ConfigurableListableBeanFactory beanFactory, String beanName, RootBeanDefinition mbd) {
|
||||
return new RegisteredBean(beanFactory, () -> beanName, false, () -> mbd, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new {@link RegisteredBean} instance for an inner-bean.
|
||||
* @param parent the parent of the inner-bean
|
||||
@@ -232,34 +220,45 @@ public final class RegisteredBean {
|
||||
@Nullable
|
||||
private volatile String resolvedBeanName;
|
||||
|
||||
InnerBeanResolver(RegisteredBean parent, @Nullable String innerBeanName, BeanDefinition innerBeanDefinition) {
|
||||
Assert.isInstanceOf(AbstractAutowireCapableBeanFactory.class, parent.getBeanFactory());
|
||||
|
||||
InnerBeanResolver(RegisteredBean parent, @Nullable String innerBeanName,
|
||||
BeanDefinition innerBeanDefinition) {
|
||||
|
||||
Assert.isInstanceOf(AbstractAutowireCapableBeanFactory.class,
|
||||
parent.getBeanFactory());
|
||||
this.parent = parent;
|
||||
this.innerBeanName = innerBeanName;
|
||||
this.innerBeanDefinition = innerBeanDefinition;
|
||||
}
|
||||
|
||||
|
||||
String resolveBeanName() {
|
||||
String resolvedBeanName = this.resolvedBeanName;
|
||||
if (resolvedBeanName != null) {
|
||||
return resolvedBeanName;
|
||||
}
|
||||
resolvedBeanName = resolveInnerBean((beanName, mergedBeanDefinition) -> beanName);
|
||||
resolvedBeanName = resolveInnerBean(
|
||||
(beanName, mergedBeanDefinition) -> beanName);
|
||||
this.resolvedBeanName = resolvedBeanName;
|
||||
return resolvedBeanName;
|
||||
}
|
||||
|
||||
RootBeanDefinition resolveMergedBeanDefinition() {
|
||||
return resolveInnerBean((beanName, mergedBeanDefinition) -> mergedBeanDefinition);
|
||||
return resolveInnerBean(
|
||||
(beanName, mergedBeanDefinition) -> mergedBeanDefinition);
|
||||
}
|
||||
|
||||
private <T> T resolveInnerBean(BiFunction<String, RootBeanDefinition, T> resolver) {
|
||||
private <T> T resolveInnerBean(
|
||||
BiFunction<String, RootBeanDefinition, T> resolver) {
|
||||
|
||||
// Always use a fresh BeanDefinitionValueResolver in case the parent merged bean definition has changed.
|
||||
BeanDefinitionValueResolver beanDefinitionValueResolver = new BeanDefinitionValueResolver(
|
||||
(AbstractAutowireCapableBeanFactory) this.parent.getBeanFactory(),
|
||||
this.parent.getBeanName(), this.parent.getMergedBeanDefinition());
|
||||
return beanDefinitionValueResolver.resolveInnerBean(this.innerBeanName, this.innerBeanDefinition, resolver);
|
||||
return beanDefinitionValueResolver.resolveInnerBean(this.innerBeanName,
|
||||
this.innerBeanDefinition, resolver);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+3
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2023 the original author or authors.
|
||||
* Copyright 2002-2022 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.
|
||||
@@ -163,8 +163,8 @@ public class SimpleInstantiationStrategy implements InstantiationStrategy {
|
||||
catch (InvocationTargetException ex) {
|
||||
String msg = "Factory method '" + factoryMethod.getName() + "' threw exception with message: " +
|
||||
ex.getTargetException().getMessage();
|
||||
if (bd.getFactoryBeanName() != null && owner instanceof ConfigurableBeanFactory cbf &&
|
||||
cbf.isCurrentlyInCreation(bd.getFactoryBeanName())) {
|
||||
if (bd.getFactoryBeanName() != null && owner instanceof ConfigurableBeanFactory &&
|
||||
((ConfigurableBeanFactory) owner).isCurrentlyInCreation(bd.getFactoryBeanName())) {
|
||||
msg = "Circular reference involving containing bean '" + bd.getFactoryBeanName() + "' - consider " +
|
||||
"declaring the factory method as static for independence from its containing instance. " + msg;
|
||||
}
|
||||
|
||||
+11
-11
@@ -127,9 +127,9 @@ public class StaticListableBeanFactory implements ListableBeanFactory {
|
||||
throw new BeanIsNotAFactoryException(beanName, bean.getClass());
|
||||
}
|
||||
|
||||
if (bean instanceof FactoryBean<?> factoryBean && !BeanFactoryUtils.isFactoryDereference(name)) {
|
||||
if (bean instanceof FactoryBean && !BeanFactoryUtils.isFactoryDereference(name)) {
|
||||
try {
|
||||
Object exposedObject = factoryBean.getObject();
|
||||
Object exposedObject = ((FactoryBean<?>) bean).getObject();
|
||||
if (exposedObject == null) {
|
||||
throw new BeanCreationException(beanName, "FactoryBean exposed null object");
|
||||
}
|
||||
@@ -205,8 +205,8 @@ public class StaticListableBeanFactory implements ListableBeanFactory {
|
||||
public boolean isSingleton(String name) throws NoSuchBeanDefinitionException {
|
||||
Object bean = getBean(name);
|
||||
// In case of FactoryBean, return singleton status of created object.
|
||||
if (bean instanceof FactoryBean<?> factoryBean) {
|
||||
return factoryBean.isSingleton();
|
||||
if (bean instanceof FactoryBean) {
|
||||
return ((FactoryBean<?>) bean).isSingleton();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -215,8 +215,8 @@ public class StaticListableBeanFactory implements ListableBeanFactory {
|
||||
public boolean isPrototype(String name) throws NoSuchBeanDefinitionException {
|
||||
Object bean = getBean(name);
|
||||
// In case of FactoryBean, return prototype status of created object.
|
||||
return ((bean instanceof SmartFactoryBean<?> smartFactoryBean && smartFactoryBean.isPrototype()) ||
|
||||
(bean instanceof FactoryBean<?> factoryBean && !factoryBean.isSingleton()));
|
||||
return ((bean instanceof SmartFactoryBean && ((SmartFactoryBean<?>) bean).isPrototype()) ||
|
||||
(bean instanceof FactoryBean && !((FactoryBean<?>) bean).isSingleton()));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -246,9 +246,9 @@ public class StaticListableBeanFactory implements ListableBeanFactory {
|
||||
"Defined beans are [" + StringUtils.collectionToCommaDelimitedString(this.beans.keySet()) + "]");
|
||||
}
|
||||
|
||||
if (bean instanceof FactoryBean<?> factoryBean && !BeanFactoryUtils.isFactoryDereference(name)) {
|
||||
if (bean instanceof FactoryBean && !BeanFactoryUtils.isFactoryDereference(name)) {
|
||||
// If it's a FactoryBean, we want to look at what it creates, not the factory class.
|
||||
return factoryBean.getObjectType();
|
||||
return ((FactoryBean<?>) bean).getObjectType();
|
||||
}
|
||||
return bean.getClass();
|
||||
}
|
||||
@@ -408,10 +408,10 @@ public class StaticListableBeanFactory implements ListableBeanFactory {
|
||||
String beanName = entry.getKey();
|
||||
Object beanInstance = entry.getValue();
|
||||
// Is bean a FactoryBean?
|
||||
if (beanInstance instanceof FactoryBean<?> factoryBean && !isFactoryType) {
|
||||
if (beanInstance instanceof FactoryBean<?> factory && !isFactoryType) {
|
||||
// Match object created by FactoryBean.
|
||||
Class<?> objectType = factoryBean.getObjectType();
|
||||
if ((includeNonSingletons || factoryBean.isSingleton()) &&
|
||||
Class<?> objectType = factory.getObjectType();
|
||||
if ((includeNonSingletons || factory.isSingleton()) &&
|
||||
objectType != null && (type == null || type.isAssignableFrom(objectType))) {
|
||||
matches.put(beanName, getBean(beanName, type));
|
||||
}
|
||||
|
||||
+2
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2023 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.
|
||||
@@ -547,8 +547,7 @@ public class XmlBeanDefinitionReader extends AbstractBeanDefinitionReader {
|
||||
* @see DefaultNamespaceHandlerResolver#DefaultNamespaceHandlerResolver(ClassLoader)
|
||||
*/
|
||||
protected NamespaceHandlerResolver createDefaultNamespaceHandlerResolver() {
|
||||
ResourceLoader resourceLoader = getResourceLoader();
|
||||
ClassLoader cl = (resourceLoader != null ? resourceLoader.getClassLoader() : getBeanClassLoader());
|
||||
ClassLoader cl = (getResourceLoader() != null ? getResourceLoader().getClassLoader() : getBeanClassLoader());
|
||||
return new DefaultNamespaceHandlerResolver(cl);
|
||||
}
|
||||
|
||||
|
||||
-1
@@ -111,7 +111,6 @@ public class ArgumentConvertingMethodInvoker extends MethodInvoker {
|
||||
* @see #doFindMatchingMethod
|
||||
*/
|
||||
@Override
|
||||
@Nullable
|
||||
protected Method findMatchingMethod() {
|
||||
Method matchingMethod = super.findMatchingMethod();
|
||||
// Second pass: look for method where arguments can be converted to parameter types.
|
||||
|
||||
+55
-156
@@ -18,9 +18,7 @@ package org.springframework.beans.factory;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.io.Serializable;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.MalformedURLException;
|
||||
import java.text.NumberFormat;
|
||||
import java.text.ParseException;
|
||||
@@ -76,9 +74,7 @@ import org.springframework.beans.testfixture.beans.NestedTestBean;
|
||||
import org.springframework.beans.testfixture.beans.SideEffectBean;
|
||||
import org.springframework.beans.testfixture.beans.TestBean;
|
||||
import org.springframework.beans.testfixture.beans.factory.DummyFactory;
|
||||
import org.springframework.core.DefaultParameterNameDiscoverer;
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.core.ParameterNameDiscoverer;
|
||||
import org.springframework.core.ResolvableType;
|
||||
import org.springframework.core.annotation.AnnotationAwareOrderComparator;
|
||||
import org.springframework.core.convert.support.DefaultConversionService;
|
||||
@@ -115,21 +111,7 @@ import static org.mockito.Mockito.verify;
|
||||
*/
|
||||
class DefaultListableBeanFactoryTests {
|
||||
|
||||
private final DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
|
||||
|
||||
{
|
||||
// No parameter name discovery expected unless named arguments are used
|
||||
lbf.setParameterNameDiscoverer(new ParameterNameDiscoverer() {
|
||||
@Override
|
||||
public String[] getParameterNames(Method method) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
@Override
|
||||
public String[] getParameterNames(Constructor<?> ctor) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
});
|
||||
}
|
||||
private DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
|
||||
|
||||
|
||||
@Test
|
||||
@@ -449,6 +431,7 @@ class DefaultListableBeanFactoryTests {
|
||||
|
||||
@Test
|
||||
void empty() {
|
||||
ListableBeanFactory lbf = new DefaultListableBeanFactory();
|
||||
assertThat(lbf.getBeanDefinitionNames() != null).as("No beans defined --> array != null").isTrue();
|
||||
assertThat(lbf.getBeanDefinitionNames().length == 0).as("No beans defined after no arg constructor").isTrue();
|
||||
assertThat(lbf.getBeanDefinitionCount() == 0).as("No beans defined after no arg constructor").isTrue();
|
||||
@@ -458,7 +441,6 @@ class DefaultListableBeanFactoryTests {
|
||||
void emptyPropertiesPopulation() {
|
||||
Properties p = new Properties();
|
||||
registerBeanDefinitions(p);
|
||||
|
||||
assertThat(lbf.getBeanDefinitionCount() == 0).as("No beans defined after ignorable invalid").isTrue();
|
||||
}
|
||||
|
||||
@@ -468,7 +450,6 @@ class DefaultListableBeanFactoryTests {
|
||||
p.setProperty("foo", "bar");
|
||||
p.setProperty("qwert", "er");
|
||||
registerBeanDefinitions(p, "test");
|
||||
|
||||
assertThat(lbf.getBeanDefinitionCount() == 0).as("No beans defined after harmless ignorable rubbish").isTrue();
|
||||
}
|
||||
|
||||
@@ -479,9 +460,8 @@ class DefaultListableBeanFactoryTests {
|
||||
p.setProperty("test.name", "Tony");
|
||||
p.setProperty("test.age", "48");
|
||||
int count = registerBeanDefinitions(p);
|
||||
|
||||
assertThat(count == 1).as("1 beans registered, not " + count).isTrue();
|
||||
testPropertiesPopulation(lbf);
|
||||
singleTestBean(lbf);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -492,22 +472,8 @@ class DefaultListableBeanFactoryTests {
|
||||
p.setProperty(PREFIX + "test.name", "Tony");
|
||||
p.setProperty(PREFIX + "test.age", "0x30");
|
||||
int count = registerBeanDefinitions(p, PREFIX);
|
||||
|
||||
assertThat(count == 1).as("1 beans registered, not " + count).isTrue();
|
||||
testPropertiesPopulation(lbf);
|
||||
}
|
||||
|
||||
private void testPropertiesPopulation(ListableBeanFactory lbf) {
|
||||
assertThat(lbf.getBeanDefinitionCount() == 1).as("1 beans defined").isTrue();
|
||||
String[] names = lbf.getBeanDefinitionNames();
|
||||
assertThat(names != lbf.getBeanDefinitionNames()).isTrue();
|
||||
assertThat(names.length == 1).as("Array length == 1").isTrue();
|
||||
assertThat(names[0].equals("test")).as("0th element == test").isTrue();
|
||||
|
||||
TestBean tb = (TestBean) lbf.getBean("test");
|
||||
assertThat(tb != null).as("Test is non null").isTrue();
|
||||
assertThat("Tony".equals(tb.getName())).as("Test bean name is Tony").isTrue();
|
||||
assertThat(tb.getAge() == 48).as("Test bean age is 48").isTrue();
|
||||
singleTestBean(lbf);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -559,7 +525,6 @@ class DefaultListableBeanFactoryTests {
|
||||
p.setProperty(PREFIX + "kerry.spouse(ref)", "rod");
|
||||
|
||||
registerBeanDefinitions(p, PREFIX);
|
||||
|
||||
assertThatExceptionOfType(BeansException.class).as("unresolved reference").isThrownBy(() ->
|
||||
lbf.getBean("kerry"));
|
||||
}
|
||||
@@ -685,6 +650,7 @@ class DefaultListableBeanFactoryTests {
|
||||
assertThat(kerry1 != null).as("Non null").isTrue();
|
||||
assertThat(kerry1 == kerry2).as("Singletons equal").isTrue();
|
||||
|
||||
lbf = new DefaultListableBeanFactory();
|
||||
p = new Properties();
|
||||
p.setProperty("kerry.(class)", TestBean.class.getName());
|
||||
p.setProperty("kerry.(scope)", BeanDefinition.SCOPE_PROTOTYPE);
|
||||
@@ -695,6 +661,7 @@ class DefaultListableBeanFactoryTests {
|
||||
assertThat(kerry1 != null).as("Non null").isTrue();
|
||||
assertThat(kerry1 != kerry2).as("Prototypes NOT equal").isTrue();
|
||||
|
||||
lbf = new DefaultListableBeanFactory();
|
||||
p = new Properties();
|
||||
p.setProperty("kerry.(class)", TestBean.class.getName());
|
||||
p.setProperty("kerry.(scope)", "singleton");
|
||||
@@ -717,8 +684,8 @@ class DefaultListableBeanFactoryTests {
|
||||
p.setProperty("rod.(singleton)", "false");
|
||||
p.setProperty("rod.age", "34");
|
||||
p.setProperty("rod.spouse", "*kerry");
|
||||
registerBeanDefinitions(p);
|
||||
|
||||
registerBeanDefinitions(p);
|
||||
assertThatExceptionOfType(BeanCreationException.class).isThrownBy(() ->
|
||||
lbf.getBean("kerry"))
|
||||
.satisfies(ex -> assertThat(ex.contains(BeanCurrentlyInCreationException.class)).isTrue());
|
||||
@@ -739,6 +706,7 @@ class DefaultListableBeanFactoryTests {
|
||||
assertThat(kerry1).as("Non null").isNotNull();
|
||||
assertThat(kerry1 == kerry2).as("Singletons equal").isTrue();
|
||||
|
||||
lbf = new DefaultListableBeanFactory();
|
||||
p = new Properties();
|
||||
p.setProperty("wife.(class)", TestBean.class.getName());
|
||||
p.setProperty("wife.name", "kerry");
|
||||
@@ -753,6 +721,7 @@ class DefaultListableBeanFactoryTests {
|
||||
assertThat(kerry1 != null).as("Non null").isTrue();
|
||||
assertThat(kerry1 != kerry2).as("Prototypes NOT equal").isTrue();
|
||||
|
||||
lbf = new DefaultListableBeanFactory();
|
||||
p = new Properties();
|
||||
p.setProperty("kerry.(class)", TestBean.class.getName());
|
||||
p.setProperty("kerry.(singleton)", "true");
|
||||
@@ -827,17 +796,41 @@ class DefaultListableBeanFactoryTests {
|
||||
assertThat(factory.getBean("child")).isInstanceOf(DerivedTestBean.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void nameAlreadyBound() {
|
||||
Properties p = new Properties();
|
||||
p.setProperty("kerry.(class)", TestBean.class.getName());
|
||||
p.setProperty("kerry.age", "35");
|
||||
registerBeanDefinitions(p);
|
||||
try {
|
||||
registerBeanDefinitions(p);
|
||||
}
|
||||
catch (BeanDefinitionStoreException ex) {
|
||||
assertThat(ex.getBeanName()).isEqualTo("kerry");
|
||||
// expected
|
||||
}
|
||||
}
|
||||
|
||||
private void singleTestBean(ListableBeanFactory lbf) {
|
||||
assertThat(lbf.getBeanDefinitionCount() == 1).as("1 beans defined").isTrue();
|
||||
String[] names = lbf.getBeanDefinitionNames();
|
||||
assertThat(names != lbf.getBeanDefinitionNames()).isTrue();
|
||||
assertThat(names.length == 1).as("Array length == 1").isTrue();
|
||||
assertThat(names[0].equals("test")).as("0th element == test").isTrue();
|
||||
TestBean tb = (TestBean) lbf.getBean("test");
|
||||
assertThat(tb != null).as("Test is non null").isTrue();
|
||||
assertThat("Tony".equals(tb.getName())).as("Test bean name is Tony").isTrue();
|
||||
assertThat(tb.getAge() == 48).as("Test bean age is 48").isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void aliasCircle() {
|
||||
lbf.registerAlias("test", "test2");
|
||||
lbf.registerAlias("test2", "test3");
|
||||
|
||||
assertThatIllegalStateException().isThrownBy(() ->
|
||||
lbf.registerAlias("test3", "test2"));
|
||||
|
||||
assertThatIllegalStateException().isThrownBy(() ->
|
||||
lbf.registerAlias("test3", "test"));
|
||||
|
||||
lbf.registerAlias("test", "test3");
|
||||
}
|
||||
|
||||
@@ -847,7 +840,6 @@ class DefaultListableBeanFactoryTests {
|
||||
lbf.registerAlias("test", "testAlias");
|
||||
lbf.registerAlias("testAlias", "testAlias2");
|
||||
lbf.registerAlias("testAlias2", "testAlias3");
|
||||
|
||||
Object bean = lbf.getBean("test");
|
||||
assertThat(lbf.getBean("testAlias")).isSameAs(bean);
|
||||
assertThat(lbf.getBean("testAlias2")).isSameAs(bean);
|
||||
@@ -862,7 +854,6 @@ class DefaultListableBeanFactoryTests {
|
||||
lbf.registerAlias("test", "test2");
|
||||
lbf.registerAlias("test", "testX");
|
||||
lbf.registerBeanDefinition("testX", new RootBeanDefinition(TestBean.class));
|
||||
|
||||
assertThat(lbf.getBean("test")).isInstanceOf(NestedTestBean.class);
|
||||
assertThat(lbf.getBean("test2")).isInstanceOf(NestedTestBean.class);
|
||||
assertThat(lbf.getBean("testX")).isInstanceOf(TestBean.class);
|
||||
@@ -875,15 +866,13 @@ class DefaultListableBeanFactoryTests {
|
||||
BeanDefinition newDef = new RootBeanDefinition(NestedTestBean.class);
|
||||
lbf.registerBeanDefinition("test", oldDef);
|
||||
lbf.registerAlias("test", "testX");
|
||||
|
||||
assertThatExceptionOfType(BeanDefinitionOverrideException.class).isThrownBy(() ->
|
||||
lbf.registerBeanDefinition("test", newDef))
|
||||
lbf.registerBeanDefinition("test", newDef))
|
||||
.satisfies(ex -> {
|
||||
assertThat(ex.getBeanName()).isEqualTo("test");
|
||||
assertThat(ex.getBeanDefinition()).isEqualTo(newDef);
|
||||
assertThat(ex.getExistingDefinition()).isEqualTo(oldDef);
|
||||
});
|
||||
|
||||
assertThatExceptionOfType(BeanDefinitionOverrideException.class).isThrownBy(() ->
|
||||
lbf.registerBeanDefinition("testX", newDef))
|
||||
.satisfies(ex -> {
|
||||
@@ -899,7 +888,6 @@ class DefaultListableBeanFactoryTests {
|
||||
lbf.registerAlias("test", "testAlias");
|
||||
lbf.registerBeanDefinition("test", new RootBeanDefinition(NestedTestBean.class));
|
||||
lbf.registerAlias("test", "testAlias");
|
||||
|
||||
assertThat(lbf.getBean("test")).isInstanceOf(NestedTestBean.class);
|
||||
assertThat(lbf.getBean("testAlias")).isInstanceOf(NestedTestBean.class);
|
||||
}
|
||||
@@ -912,7 +900,6 @@ class DefaultListableBeanFactoryTests {
|
||||
RootBeanDefinition bd2 = new RootBeanDefinition(NestedTestBean.class);
|
||||
bd2.getConstructorArgumentValues().addIndexedArgumentValue(0, "value0");
|
||||
lbf.registerBeanDefinition("test", bd2);
|
||||
|
||||
assertThat(lbf.getBean("test")).isInstanceOf(NestedTestBean.class);
|
||||
assertThat(lbf.getBean("test", NestedTestBean.class).getCompany()).isEqualTo("value0");
|
||||
}
|
||||
@@ -929,7 +916,6 @@ class DefaultListableBeanFactoryTests {
|
||||
lbf.removeAlias("test2");
|
||||
lbf.registerBeanDefinition("test", new RootBeanDefinition(NestedTestBean.class));
|
||||
lbf.registerAlias("test", "test2");
|
||||
|
||||
assertThat(lbf.getBean("test")).isInstanceOf(NestedTestBean.class);
|
||||
assertThat(lbf.getBean("test2")).isInstanceOf(NestedTestBean.class);
|
||||
}
|
||||
@@ -969,7 +955,6 @@ class DefaultListableBeanFactoryTests {
|
||||
p.setProperty("k.name", "kerry");
|
||||
p.setProperty("k.spouse", "*r");
|
||||
registerBeanDefinitions(p);
|
||||
|
||||
TestBean k = (TestBean) lbf.getBean("k");
|
||||
TestBean r = (TestBean) lbf.getBean("r");
|
||||
assertThat(k.getSpouse() == r).isTrue();
|
||||
@@ -982,7 +967,6 @@ class DefaultListableBeanFactoryTests {
|
||||
p.setProperty("r.(class)", TestBean.class.getName());
|
||||
p.setProperty("r.name", "*" + name);
|
||||
registerBeanDefinitions(p);
|
||||
|
||||
TestBean r = (TestBean) lbf.getBean("r");
|
||||
assertThat(r.getName().equals(name)).isTrue();
|
||||
}
|
||||
@@ -998,7 +982,6 @@ class DefaultListableBeanFactoryTests {
|
||||
RootBeanDefinition bd = new RootBeanDefinition(TestBean.class);
|
||||
bd.setPropertyValues(pvs);
|
||||
lbf.registerBeanDefinition("testBean", bd);
|
||||
|
||||
TestBean testBean = (TestBean) lbf.getBean("testBean");
|
||||
assertThat(testBean.getMyFloat() == 1.1f).isTrue();
|
||||
}
|
||||
@@ -1016,13 +999,11 @@ class DefaultListableBeanFactoryTests {
|
||||
}
|
||||
});
|
||||
lbf.setConversionService(conversionService);
|
||||
|
||||
MutablePropertyValues pvs = new MutablePropertyValues();
|
||||
pvs.add("myFloat", "1,1");
|
||||
RootBeanDefinition bd = new RootBeanDefinition(TestBean.class);
|
||||
bd.setPropertyValues(pvs);
|
||||
lbf.registerBeanDefinition("testBean", bd);
|
||||
|
||||
TestBean testBean = (TestBean) lbf.getBean("testBean");
|
||||
assertThat(testBean.getMyFloat() == 1.1f).isTrue();
|
||||
}
|
||||
@@ -1039,7 +1020,6 @@ class DefaultListableBeanFactoryTests {
|
||||
bd.setPropertyValues(pvs);
|
||||
lbf.registerBeanDefinition("testBean", bd);
|
||||
lbf.registerSingleton("myFloat", "1,1");
|
||||
|
||||
TestBean testBean = (TestBean) lbf.getBean("testBean");
|
||||
assertThat(testBean.getMyFloat() == 1.1f).isTrue();
|
||||
}
|
||||
@@ -1054,7 +1034,6 @@ class DefaultListableBeanFactoryTests {
|
||||
cav.addIndexedArgumentValue(0, "myName");
|
||||
cav.addIndexedArgumentValue(1, "myAge");
|
||||
lbf.registerBeanDefinition("testBean", new RootBeanDefinition(TestBean.class, cav, pvs));
|
||||
|
||||
TestBean testBean = (TestBean) lbf.getBean("testBean");
|
||||
assertThat(testBean.getName()).isEqualTo("myName");
|
||||
assertThat(testBean.getAge()).isEqualTo(5);
|
||||
@@ -1072,7 +1051,6 @@ class DefaultListableBeanFactoryTests {
|
||||
cav.addIndexedArgumentValue(1, "myAge");
|
||||
lbf.registerBeanDefinition("testBean", new RootBeanDefinition(TestBean.class, cav, pvs));
|
||||
lbf.registerSingleton("myFloat", "1,1");
|
||||
|
||||
TestBean testBean = (TestBean) lbf.getBean("testBean");
|
||||
assertThat(testBean.getName()).isEqualTo("myName");
|
||||
assertThat(testBean.getAge()).isEqualTo(5);
|
||||
@@ -1189,7 +1167,6 @@ class DefaultListableBeanFactoryTests {
|
||||
bd1.setScope(BeanDefinition.SCOPE_PROTOTYPE);
|
||||
lbf.registerBeanDefinition("testBean", bd1);
|
||||
assertThat(lbf.getBean("testBean")).isInstanceOf(TestBean.class);
|
||||
|
||||
RootBeanDefinition bd2 = new RootBeanDefinition(NestedTestBean.class);
|
||||
bd2.setScope(BeanDefinition.SCOPE_PROTOTYPE);
|
||||
lbf.registerBeanDefinition("testBean", bd2);
|
||||
@@ -1204,8 +1181,8 @@ class DefaultListableBeanFactoryTests {
|
||||
RootBeanDefinition rbd = new RootBeanDefinition(ArrayBean.class);
|
||||
rbd.setAutowireMode(RootBeanDefinition.AUTOWIRE_BY_TYPE);
|
||||
lbf.registerBeanDefinition("arrayBean", rbd);
|
||||
|
||||
ArrayBean ab = (ArrayBean) lbf.getBean("arrayBean");
|
||||
|
||||
assertThat(ab.getResourceArray()[0]).isEqualTo(new UrlResource("http://localhost:8080"));
|
||||
assertThat(ab.getResourceArray()[1]).isEqualTo(new UrlResource("http://localhost:9090"));
|
||||
}
|
||||
@@ -1215,8 +1192,8 @@ class DefaultListableBeanFactoryTests {
|
||||
RootBeanDefinition rbd = new RootBeanDefinition(ArrayBean.class);
|
||||
rbd.setAutowireMode(RootBeanDefinition.AUTOWIRE_BY_TYPE);
|
||||
lbf.registerBeanDefinition("arrayBean", rbd);
|
||||
|
||||
ArrayBean ab = (ArrayBean) lbf.getBean("arrayBean");
|
||||
|
||||
assertThat(ab.getResourceArray()).isNull();
|
||||
}
|
||||
|
||||
@@ -1228,8 +1205,8 @@ class DefaultListableBeanFactoryTests {
|
||||
RootBeanDefinition rbd = new RootBeanDefinition(ArrayBean.class);
|
||||
rbd.setAutowireMode(RootBeanDefinition.AUTOWIRE_CONSTRUCTOR);
|
||||
lbf.registerBeanDefinition("arrayBean", rbd);
|
||||
|
||||
ArrayBean ab = (ArrayBean) lbf.getBean("arrayBean");
|
||||
|
||||
assertThat(ab.getIntegerArray()[0]).isEqualTo(4);
|
||||
assertThat(ab.getIntegerArray()[1]).isEqualTo(5);
|
||||
}
|
||||
@@ -1239,8 +1216,8 @@ class DefaultListableBeanFactoryTests {
|
||||
RootBeanDefinition rbd = new RootBeanDefinition(ArrayBean.class);
|
||||
rbd.setAutowireMode(RootBeanDefinition.AUTOWIRE_CONSTRUCTOR);
|
||||
lbf.registerBeanDefinition("arrayBean", rbd);
|
||||
|
||||
ArrayBean ab = (ArrayBean) lbf.getBean("arrayBean");
|
||||
|
||||
assertThat(ab.getIntegerArray()).isNull();
|
||||
}
|
||||
|
||||
@@ -1254,8 +1231,8 @@ class DefaultListableBeanFactoryTests {
|
||||
RootBeanDefinition rbd = new RootBeanDefinition(ArrayBean.class);
|
||||
rbd.setAutowireMode(RootBeanDefinition.AUTOWIRE_CONSTRUCTOR);
|
||||
lbf.registerBeanDefinition("arrayBean", rbd);
|
||||
|
||||
ArrayBean ab = (ArrayBean) lbf.getBean("arrayBean");
|
||||
|
||||
assertThat(ab.getIntegerArray()[0]).isEqualTo(4);
|
||||
assertThat(ab.getIntegerArray()[1]).isEqualTo(5);
|
||||
assertThat(ab.getResourceArray()[0]).isEqualTo(new UrlResource("http://localhost:8080"));
|
||||
@@ -1270,8 +1247,8 @@ class DefaultListableBeanFactoryTests {
|
||||
RootBeanDefinition rbd = new RootBeanDefinition(ArrayBean.class);
|
||||
rbd.setAutowireMode(RootBeanDefinition.AUTOWIRE_CONSTRUCTOR);
|
||||
lbf.registerBeanDefinition("arrayBean", rbd);
|
||||
|
||||
ArrayBean ab = (ArrayBean) lbf.getBean("arrayBean");
|
||||
|
||||
assertThat(ab.getIntegerArray()).isNull();
|
||||
assertThat(ab.getResourceArray()).isNull();
|
||||
}
|
||||
@@ -1288,7 +1265,6 @@ class DefaultListableBeanFactoryTests {
|
||||
pvs.add("locations", new String[]{"#{foo}"});
|
||||
rbd.setPropertyValues(pvs);
|
||||
lbf.registerBeanDefinition("myProperties", rbd);
|
||||
|
||||
Properties properties = (Properties) lbf.getBean("myProperties");
|
||||
assertThat(properties.getProperty("foo")).isEqualTo("bar");
|
||||
}
|
||||
@@ -1311,7 +1287,6 @@ class DefaultListableBeanFactoryTests {
|
||||
bd.setPropertyValues(pvs);
|
||||
lbf.registerBeanDefinition("rod", bd);
|
||||
assertThat(lbf.getBeanDefinitionCount()).isEqualTo(1);
|
||||
|
||||
// Depends on age, name and spouse (TestBean)
|
||||
Object registered = lbf.autowire(DependenciesBean.class, AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE, true);
|
||||
assertThat(lbf.getBeanDefinitionCount()).isEqualTo(1);
|
||||
@@ -1328,7 +1303,6 @@ class DefaultListableBeanFactoryTests {
|
||||
bd.setPropertyValues(pvs);
|
||||
lbf.registerBeanDefinition("rod", bd);
|
||||
assertThat(lbf.getBeanDefinitionCount()).isEqualTo(1);
|
||||
|
||||
Object registered = lbf.autowire(ConstructorDependency.class, AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR, false);
|
||||
assertThat(lbf.getBeanDefinitionCount()).isEqualTo(1);
|
||||
ConstructorDependency kerry = (ConstructorDependency) registered;
|
||||
@@ -1342,8 +1316,6 @@ class DefaultListableBeanFactoryTests {
|
||||
lbf.registerBeanDefinition("rod", bd);
|
||||
RootBeanDefinition bd2 = new RootBeanDefinition(TestBean.class);
|
||||
lbf.registerBeanDefinition("rod2", bd2);
|
||||
lbf.setParameterNameDiscoverer(new DefaultParameterNameDiscoverer());
|
||||
|
||||
assertThatExceptionOfType(UnsatisfiedDependencyException.class).isThrownBy(() ->
|
||||
lbf.autowire(ConstructorDependency.class, AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR, false))
|
||||
.withMessageContaining("rod")
|
||||
@@ -1357,7 +1329,6 @@ class DefaultListableBeanFactoryTests {
|
||||
RootBeanDefinition bd = new RootBeanDefinition(TestBean.class);
|
||||
bd.setPropertyValues(pvs);
|
||||
lbf.registerBeanDefinition("rod", bd);
|
||||
|
||||
assertThat(lbf.getBeanDefinitionCount()).isEqualTo(1);
|
||||
assertThatExceptionOfType(UnsatisfiedDependencyException.class).isThrownBy(() ->
|
||||
lbf.autowire(UnsatisfiedConstructorDependency.class, AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR, true));
|
||||
@@ -1369,7 +1340,6 @@ class DefaultListableBeanFactoryTests {
|
||||
lbf.registerBeanDefinition("spouse", bd);
|
||||
ConstructorDependenciesBean bean = (ConstructorDependenciesBean)
|
||||
lbf.autowire(ConstructorDependenciesBean.class, AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR, true);
|
||||
|
||||
Object spouse = lbf.getBean("spouse");
|
||||
assertThat(bean.getSpouse1() == spouse).isTrue();
|
||||
assertThat(BeanFactoryUtils.beanOfType(lbf, TestBean.class) == spouse).isTrue();
|
||||
@@ -1381,7 +1351,6 @@ class DefaultListableBeanFactoryTests {
|
||||
lbf.registerBeanDefinition("spouse", bd);
|
||||
DependenciesBean bean = (DependenciesBean)
|
||||
lbf.autowire(DependenciesBean.class, AutowireCapableBeanFactory.AUTOWIRE_BY_NAME, true);
|
||||
|
||||
TestBean spouse = (TestBean) lbf.getBean("spouse");
|
||||
assertThat(bean.getSpouse()).isEqualTo(spouse);
|
||||
assertThat(BeanFactoryUtils.beanOfType(lbf, TestBean.class) == spouse).isTrue();
|
||||
@@ -1391,7 +1360,6 @@ class DefaultListableBeanFactoryTests {
|
||||
void autowireBeanByNameWithDependencyCheck() {
|
||||
RootBeanDefinition bd = new RootBeanDefinition(TestBean.class);
|
||||
lbf.registerBeanDefinition("spous", bd);
|
||||
|
||||
assertThatExceptionOfType(UnsatisfiedDependencyException.class).isThrownBy(() ->
|
||||
lbf.autowire(DependenciesBean.class, AutowireCapableBeanFactory.AUTOWIRE_BY_NAME, true));
|
||||
}
|
||||
@@ -1402,7 +1370,6 @@ class DefaultListableBeanFactoryTests {
|
||||
lbf.registerBeanDefinition("spous", bd);
|
||||
DependenciesBean bean = (DependenciesBean)
|
||||
lbf.autowire(DependenciesBean.class, AutowireCapableBeanFactory.AUTOWIRE_BY_NAME, false);
|
||||
|
||||
assertThat(bean.getSpouse()).isNull();
|
||||
}
|
||||
|
||||
@@ -1414,7 +1381,6 @@ class DefaultListableBeanFactoryTests {
|
||||
RootBeanDefinition bd2 = new RootBeanDefinition(TestBean.class);
|
||||
bd2.setDependsOn("tb1");
|
||||
lbf.registerBeanDefinition("tb2", bd2);
|
||||
|
||||
assertThatExceptionOfType(BeanCreationException.class).isThrownBy(() ->
|
||||
lbf.preInstantiateSingletons())
|
||||
.withMessageContaining("Circular")
|
||||
@@ -1433,7 +1399,6 @@ class DefaultListableBeanFactoryTests {
|
||||
RootBeanDefinition bd3 = new RootBeanDefinition(TestBean.class);
|
||||
bd3.setDependsOn("tb1");
|
||||
lbf.registerBeanDefinition("tb3", bd3);
|
||||
|
||||
assertThatExceptionOfType(BeanCreationException.class).isThrownBy(
|
||||
lbf::preInstantiateSingletons)
|
||||
.withMessageContaining("Circular")
|
||||
@@ -1443,31 +1408,30 @@ class DefaultListableBeanFactoryTests {
|
||||
|
||||
@Test
|
||||
void getBeanByTypeWithNoneFound() {
|
||||
DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
|
||||
assertThatExceptionOfType(NoSuchBeanDefinitionException.class).isThrownBy(() ->
|
||||
lbf.getBean(TestBean.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void getBeanByTypeWithLateRegistration() {
|
||||
DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
|
||||
assertThatExceptionOfType(NoSuchBeanDefinitionException.class).isThrownBy(() ->
|
||||
lbf.getBean(TestBean.class));
|
||||
|
||||
RootBeanDefinition bd1 = new RootBeanDefinition(TestBean.class);
|
||||
lbf.registerBeanDefinition("bd1", bd1);
|
||||
|
||||
TestBean bean = lbf.getBean(TestBean.class);
|
||||
assertThat(bean.getBeanName()).isEqualTo("bd1");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getBeanByTypeWithLateRegistrationAgainstFrozen() {
|
||||
DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
|
||||
lbf.freezeConfiguration();
|
||||
assertThatExceptionOfType(NoSuchBeanDefinitionException.class).isThrownBy(() ->
|
||||
lbf.getBean(TestBean.class));
|
||||
|
||||
RootBeanDefinition bd1 = new RootBeanDefinition(TestBean.class);
|
||||
lbf.registerBeanDefinition("bd1", bd1);
|
||||
|
||||
TestBean bean = lbf.getBean(TestBean.class);
|
||||
assertThat(bean.getBeanName()).isEqualTo("bd1");
|
||||
}
|
||||
@@ -1477,8 +1441,7 @@ class DefaultListableBeanFactoryTests {
|
||||
DefaultListableBeanFactory parent = new DefaultListableBeanFactory();
|
||||
RootBeanDefinition bd1 = new RootBeanDefinition(TestBean.class);
|
||||
parent.registerBeanDefinition("bd1", bd1);
|
||||
lbf.setParentBeanFactory(parent);
|
||||
|
||||
DefaultListableBeanFactory lbf = new DefaultListableBeanFactory(parent);
|
||||
TestBean bean = lbf.getBean(TestBean.class);
|
||||
assertThat(bean.getBeanName()).isEqualTo("bd1");
|
||||
}
|
||||
@@ -1489,7 +1452,6 @@ class DefaultListableBeanFactoryTests {
|
||||
RootBeanDefinition bd2 = new RootBeanDefinition(TestBean.class);
|
||||
lbf.registerBeanDefinition("bd1", bd1);
|
||||
lbf.registerBeanDefinition("bd2", bd2);
|
||||
|
||||
assertThatExceptionOfType(NoUniqueBeanDefinitionException.class).isThrownBy(() ->
|
||||
lbf.getBean(TestBean.class));
|
||||
}
|
||||
@@ -1502,7 +1464,6 @@ class DefaultListableBeanFactoryTests {
|
||||
bd2.setPrimary(true);
|
||||
lbf.registerBeanDefinition("bd1", bd1);
|
||||
lbf.registerBeanDefinition("bd2", bd2);
|
||||
|
||||
TestBean bean = lbf.getBean(TestBean.class);
|
||||
assertThat(bean.getBeanName()).isEqualTo("bd2");
|
||||
assertThat(lbf.containsSingleton("bd1")).isFalse();
|
||||
@@ -1511,12 +1472,12 @@ class DefaultListableBeanFactoryTests {
|
||||
@Test
|
||||
@SuppressWarnings("rawtypes")
|
||||
void getFactoryBeanByTypeWithPrimary() {
|
||||
DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
|
||||
RootBeanDefinition bd1 = new RootBeanDefinition(NullTestBeanFactoryBean.class);
|
||||
RootBeanDefinition bd2 = new RootBeanDefinition(NullTestBeanFactoryBean.class);
|
||||
bd2.setPrimary(true);
|
||||
lbf.registerBeanDefinition("bd1", bd1);
|
||||
lbf.registerBeanDefinition("bd2", bd2);
|
||||
|
||||
NullTestBeanFactoryBean factoryBeanByType = lbf.getBean(NullTestBeanFactoryBean.class);
|
||||
NullTestBeanFactoryBean bd1FactoryBean = (NullTestBeanFactoryBean)lbf.getBean("&bd1");
|
||||
NullTestBeanFactoryBean bd2FactoryBean = (NullTestBeanFactoryBean)lbf.getBean("&bd2");
|
||||
@@ -1535,7 +1496,6 @@ class DefaultListableBeanFactoryTests {
|
||||
bd2.setPrimary(true);
|
||||
lbf.registerBeanDefinition("bd1", bd1);
|
||||
lbf.registerBeanDefinition("bd2", bd2);
|
||||
|
||||
assertThatExceptionOfType(NoUniqueBeanDefinitionException.class).isThrownBy(() ->
|
||||
lbf.getBean(TestBean.class))
|
||||
.withMessageContaining("more than one 'primary'");
|
||||
@@ -1551,7 +1511,6 @@ class DefaultListableBeanFactoryTests {
|
||||
lbf.registerBeanDefinition("bd2", bd2);
|
||||
lbf.registerBeanDefinition("bd3", bd3);
|
||||
lbf.preInstantiateSingletons();
|
||||
|
||||
TestBean bean = lbf.getBean(TestBean.class);
|
||||
assertThat(bean.getBeanName()).isEqualTo("bd1");
|
||||
}
|
||||
@@ -1568,7 +1527,6 @@ class DefaultListableBeanFactoryTests {
|
||||
lbf.registerBeanDefinition("bd3", bd3);
|
||||
lbf.registerBeanDefinition("bd4", bd4);
|
||||
lbf.preInstantiateSingletons();
|
||||
|
||||
TestBean bean = lbf.getBean(TestBeanRecipient.class).testBean;
|
||||
assertThat(bean.getBeanName()).isEqualTo("bd1");
|
||||
}
|
||||
@@ -1580,7 +1538,6 @@ class DefaultListableBeanFactoryTests {
|
||||
RootBeanDefinition bd2 = new RootBeanDefinition(HighPriorityTestBean.class);
|
||||
lbf.registerBeanDefinition("bd1", bd1);
|
||||
lbf.registerBeanDefinition("bd2", bd2);
|
||||
|
||||
assertThatExceptionOfType(NoUniqueBeanDefinitionException.class).isThrownBy(() ->
|
||||
lbf.getBean(TestBean.class))
|
||||
.withMessageContaining("Multiple beans found with the same priority")
|
||||
@@ -1594,7 +1551,6 @@ class DefaultListableBeanFactoryTests {
|
||||
RootBeanDefinition bd2 = new RootBeanDefinition(NullTestBeanFactoryBean.class);
|
||||
lbf.registerBeanDefinition("bd1", bd1);
|
||||
lbf.registerBeanDefinition("bd2", bd2);
|
||||
|
||||
TestBean bean = lbf.getBean(TestBean.class);
|
||||
assertThat(bean.getBeanName()).isEqualTo("bd1");
|
||||
}
|
||||
@@ -1607,7 +1563,6 @@ class DefaultListableBeanFactoryTests {
|
||||
bd2.setPrimary(true);
|
||||
lbf.registerBeanDefinition("bd1", bd1);
|
||||
lbf.registerBeanDefinition("bd2", bd2);
|
||||
|
||||
TestBean bean = lbf.getBean(TestBean.class);
|
||||
assertThat(bean.getBeanName()).isEqualTo("bd2");
|
||||
}
|
||||
@@ -1665,7 +1620,7 @@ class DefaultListableBeanFactoryTests {
|
||||
DefaultListableBeanFactory parent = new DefaultListableBeanFactory();
|
||||
RootBeanDefinition bd1 = createConstructorDependencyBeanDefinition(99);
|
||||
parent.registerBeanDefinition("bd1", bd1);
|
||||
lbf.setParentBeanFactory(parent);
|
||||
DefaultListableBeanFactory lbf = new DefaultListableBeanFactory(parent);
|
||||
|
||||
ConstructorDependency bean = lbf.getBean(ConstructorDependency.class);
|
||||
assertThat(bean.beanName).isEqualTo("bd1");
|
||||
@@ -1697,7 +1652,6 @@ class DefaultListableBeanFactoryTests {
|
||||
bd2.getConstructorArgumentValues().addGenericArgumentValue("43");
|
||||
lbf.registerBeanDefinition("bd1", bd1);
|
||||
lbf.registerBeanDefinition("bd2", bd2);
|
||||
|
||||
assertThatExceptionOfType(NoUniqueBeanDefinitionException.class).isThrownBy(() ->
|
||||
lbf.getBean(ConstructorDependency.class));
|
||||
assertThatExceptionOfType(NoUniqueBeanDefinitionException.class).isThrownBy(() ->
|
||||
@@ -1815,9 +1769,9 @@ class DefaultListableBeanFactoryTests {
|
||||
@SuppressWarnings("rawtypes")
|
||||
void beanProviderSerialization() throws Exception {
|
||||
lbf.setSerializationId("test");
|
||||
|
||||
ObjectProvider<ConstructorDependency> provider = lbf.getBeanProvider(ConstructorDependency.class);
|
||||
ObjectProvider deserialized = SerializationTestUtils.serializeAndDeserialize(provider);
|
||||
|
||||
assertThatExceptionOfType(NoSuchBeanDefinitionException.class).isThrownBy(
|
||||
deserialized::getObject);
|
||||
assertThatExceptionOfType(NoSuchBeanDefinitionException.class).isThrownBy(() ->
|
||||
@@ -1860,7 +1814,6 @@ class DefaultListableBeanFactoryTests {
|
||||
lbf.registerBeanDefinition("test", bd);
|
||||
DependenciesBean bean = (DependenciesBean)
|
||||
lbf.autowire(DependenciesBean.class, AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE, true);
|
||||
|
||||
TestBean test = (TestBean) lbf.getBean("test");
|
||||
assertThat(bean.getSpouse()).isEqualTo(test);
|
||||
}
|
||||
@@ -1875,10 +1828,8 @@ class DefaultListableBeanFactoryTests {
|
||||
void autowireBeanWithFactoryBeanByType() {
|
||||
RootBeanDefinition bd = new RootBeanDefinition(LazyInitFactory.class);
|
||||
lbf.registerBeanDefinition("factoryBean", bd);
|
||||
|
||||
LazyInitFactory factoryBean = (LazyInitFactory) lbf.getBean("&factoryBean");
|
||||
assertThat(factoryBean).as("The FactoryBean should have been registered.").isNotNull();
|
||||
|
||||
FactoryBeanDependentBean bean = (FactoryBeanDependentBean) lbf.autowire(FactoryBeanDependentBean.class,
|
||||
AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE, true);
|
||||
assertThat(bean.getFactoryBean()).as("The FactoryBeanDependentBean should have been autowired 'by type' with the LazyInitFactory.").isEqualTo(factoryBean);
|
||||
@@ -1886,17 +1837,16 @@ class DefaultListableBeanFactoryTests {
|
||||
|
||||
@Test
|
||||
void autowireBeanWithFactoryBeanByTypeWithPrimary() {
|
||||
DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
|
||||
RootBeanDefinition bd1 = new RootBeanDefinition(LazyInitFactory.class);
|
||||
RootBeanDefinition bd2 = new RootBeanDefinition(LazyInitFactory.class);
|
||||
bd2.setPrimary(true);
|
||||
lbf.registerBeanDefinition("bd1", bd1);
|
||||
lbf.registerBeanDefinition("bd2", bd2);
|
||||
|
||||
LazyInitFactory bd1FactoryBean = (LazyInitFactory) lbf.getBean("&bd1");
|
||||
LazyInitFactory bd2FactoryBean = (LazyInitFactory) lbf.getBean("&bd2");
|
||||
assertThat(bd1FactoryBean).isNotNull();
|
||||
assertThat(bd2FactoryBean).isNotNull();
|
||||
|
||||
FactoryBeanDependentBean bean = (FactoryBeanDependentBean) lbf.autowire(FactoryBeanDependentBean.class,
|
||||
AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE, true);
|
||||
assertThat(bean.getFactoryBean()).isNotEqualTo(bd1FactoryBean);
|
||||
@@ -1965,7 +1915,6 @@ class DefaultListableBeanFactoryTests {
|
||||
RootBeanDefinition bd = new RootBeanDefinition(LazyInitFactory.class);
|
||||
lbf.registerBeanDefinition("factoryBean", bd);
|
||||
LazyInitFactory factoryBean = (LazyInitFactory) lbf.getBean("&factoryBean");
|
||||
|
||||
assertThat(factoryBean).as("The FactoryBean should have been registered.").isNotNull();
|
||||
assertThatExceptionOfType(TypeMismatchException.class).isThrownBy(() ->
|
||||
lbf.autowire(FactoryBeanDependentBean.class, AutowireCapableBeanFactory.AUTOWIRE_BY_NAME, true));
|
||||
@@ -1977,7 +1926,6 @@ class DefaultListableBeanFactoryTests {
|
||||
RootBeanDefinition bd2 = new RootBeanDefinition(TestBean.class);
|
||||
lbf.registerBeanDefinition("test", bd);
|
||||
lbf.registerBeanDefinition("spouse", bd2);
|
||||
|
||||
assertThatExceptionOfType(UnsatisfiedDependencyException.class).isThrownBy(() ->
|
||||
lbf.autowire(DependenciesBean.class, AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE, true))
|
||||
.withMessageContaining("test")
|
||||
@@ -2018,7 +1966,6 @@ class DefaultListableBeanFactoryTests {
|
||||
bd2.setPrimary(true);
|
||||
lbf.registerBeanDefinition("test", bd);
|
||||
lbf.registerBeanDefinition("spouse", bd2);
|
||||
|
||||
assertThatExceptionOfType(UnsatisfiedDependencyException.class).isThrownBy(() ->
|
||||
lbf.autowire(DependenciesBean.class, AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE, true))
|
||||
.withCauseExactlyInstanceOf(NoUniqueBeanDefinitionException.class);
|
||||
@@ -2044,7 +1991,6 @@ class DefaultListableBeanFactoryTests {
|
||||
RootBeanDefinition bd2 = new RootBeanDefinition(HighPriorityTestBean.class);
|
||||
lbf.registerBeanDefinition("test", bd);
|
||||
lbf.registerBeanDefinition("spouse", bd2);
|
||||
|
||||
assertThatExceptionOfType(UnsatisfiedDependencyException.class).isThrownBy(() ->
|
||||
lbf.autowire(DependenciesBean.class, AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE, true))
|
||||
.withCauseExactlyInstanceOf(NoUniqueBeanDefinitionException.class)
|
||||
@@ -2084,7 +2030,6 @@ class DefaultListableBeanFactoryTests {
|
||||
lbf.registerBeanDefinition("spouse", bd);
|
||||
DependenciesBean existingBean = new DependenciesBean();
|
||||
lbf.autowireBeanProperties(existingBean, AutowireCapableBeanFactory.AUTOWIRE_BY_NAME, true);
|
||||
|
||||
TestBean spouse = (TestBean) lbf.getBean("spouse");
|
||||
assertThat(spouse).isEqualTo(existingBean.getSpouse());
|
||||
assertThat(BeanFactoryUtils.beanOfType(lbf, TestBean.class)).isSameAs(spouse);
|
||||
@@ -2095,7 +2040,6 @@ class DefaultListableBeanFactoryTests {
|
||||
RootBeanDefinition bd = new RootBeanDefinition(TestBean.class);
|
||||
lbf.registerBeanDefinition("spous", bd);
|
||||
DependenciesBean existingBean = new DependenciesBean();
|
||||
|
||||
assertThatExceptionOfType(UnsatisfiedDependencyException.class).isThrownBy(() ->
|
||||
lbf.autowireBeanProperties(existingBean, AutowireCapableBeanFactory.AUTOWIRE_BY_NAME, true));
|
||||
}
|
||||
@@ -2106,7 +2050,6 @@ class DefaultListableBeanFactoryTests {
|
||||
lbf.registerBeanDefinition("spous", bd);
|
||||
DependenciesBean existingBean = new DependenciesBean();
|
||||
lbf.autowireBeanProperties(existingBean, AutowireCapableBeanFactory.AUTOWIRE_BY_NAME, false);
|
||||
|
||||
assertThat(existingBean.getSpouse()).isNull();
|
||||
}
|
||||
|
||||
@@ -2116,7 +2059,6 @@ class DefaultListableBeanFactoryTests {
|
||||
lbf.registerBeanDefinition("test", bd);
|
||||
DependenciesBean existingBean = new DependenciesBean();
|
||||
lbf.autowireBeanProperties(existingBean, AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE, true);
|
||||
|
||||
TestBean test = (TestBean) lbf.getBean("test");
|
||||
assertThat(test).isEqualTo(existingBean.getSpouse());
|
||||
}
|
||||
@@ -2184,23 +2126,6 @@ class DefaultListableBeanFactoryTests {
|
||||
assertThat(tb.wasDestroyed()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void createBeanWithNonDefaultConstructor() {
|
||||
lbf.registerBeanDefinition("otherTestBean", new RootBeanDefinition(TestBean.class));
|
||||
TestBeanRecipient tb = lbf.createBean(TestBeanRecipient.class);
|
||||
assertThat(lbf.containsSingleton("otherTestBean")).isTrue();
|
||||
assertThat(tb.testBean).isEqualTo(lbf.getBean("otherTestBean"));
|
||||
lbf.destroyBean(tb);
|
||||
}
|
||||
|
||||
@Test
|
||||
void createBeanWithPreferredDefaultConstructor() {
|
||||
lbf.registerBeanDefinition("otherTestBean", new RootBeanDefinition(TestBean.class));
|
||||
TestBean tb = lbf.createBean(TestBean.class);
|
||||
assertThat(lbf.containsSingleton("otherTestBean")).isFalse();
|
||||
lbf.destroyBean(tb);
|
||||
}
|
||||
|
||||
@Test
|
||||
void configureBean() {
|
||||
MutablePropertyValues pvs = new MutablePropertyValues();
|
||||
@@ -2208,7 +2133,6 @@ class DefaultListableBeanFactoryTests {
|
||||
RootBeanDefinition bd = new RootBeanDefinition(TestBean.class);
|
||||
bd.setPropertyValues(pvs);
|
||||
lbf.registerBeanDefinition("test", bd);
|
||||
|
||||
TestBean tb = new TestBean();
|
||||
assertThat(tb.getAge()).isEqualTo(0);
|
||||
lbf.configureBean(tb, "test");
|
||||
@@ -2226,7 +2150,6 @@ class DefaultListableBeanFactoryTests {
|
||||
RootBeanDefinition tbd = new RootBeanDefinition(TestBean.class);
|
||||
tbd.setAutowireMode(RootBeanDefinition.AUTOWIRE_BY_NAME);
|
||||
lbf.registerBeanDefinition("test", tbd);
|
||||
|
||||
TestBean tb = new TestBean();
|
||||
lbf.configureBean(tb, "test");
|
||||
assertThat(tb.getBeanFactory()).isSameAs(lbf);
|
||||
@@ -2244,7 +2167,6 @@ class DefaultListableBeanFactoryTests {
|
||||
lbf.registerBeanDefinition("bean" + i, bd);
|
||||
}
|
||||
lbf.preInstantiateSingletons();
|
||||
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
TestBean bean = (TestBean) lbf.getBean("bean" + i);
|
||||
TestBean otherBean = (TestBean) lbf.getBean("bean" + (i < 99 ? i + 1 : 0));
|
||||
@@ -2257,7 +2179,6 @@ class DefaultListableBeanFactoryTests {
|
||||
RootBeanDefinition bd = new RootBeanDefinition(ConstructorDependencyBean.class);
|
||||
bd.setAutowireMode(RootBeanDefinition.AUTOWIRE_CONSTRUCTOR);
|
||||
lbf.registerBeanDefinition("test", bd);
|
||||
|
||||
assertThatExceptionOfType(UnsatisfiedDependencyException.class).isThrownBy(lbf::preInstantiateSingletons);
|
||||
}
|
||||
|
||||
@@ -2266,7 +2187,6 @@ class DefaultListableBeanFactoryTests {
|
||||
RootBeanDefinition bd = new RootBeanDefinition(ConstructorDependencyFactoryBean.class);
|
||||
bd.setAutowireMode(RootBeanDefinition.AUTOWIRE_CONSTRUCTOR);
|
||||
lbf.registerBeanDefinition("test", bd);
|
||||
|
||||
assertThatExceptionOfType(UnsatisfiedDependencyException.class).isThrownBy(lbf::preInstantiateSingletons);
|
||||
}
|
||||
|
||||
@@ -2275,7 +2195,6 @@ class DefaultListableBeanFactoryTests {
|
||||
RootBeanDefinition bd = new RootBeanDefinition(ConstructorDependencyFactoryBean.class);
|
||||
bd.setAutowireMode(RootBeanDefinition.AUTOWIRE_CONSTRUCTOR);
|
||||
lbf.registerBeanDefinition("test", bd);
|
||||
|
||||
assertThatExceptionOfType(UnsatisfiedDependencyException.class).isThrownBy(() -> lbf.getBeansOfType(String.class));
|
||||
}
|
||||
|
||||
@@ -2303,14 +2222,12 @@ class DefaultListableBeanFactoryTests {
|
||||
RootBeanDefinition bd = new RootBeanDefinition(ConstructorDependencyWithClassResolution.class);
|
||||
bd.getConstructorArgumentValues().addGenericArgumentValue("java.lang.Strin");
|
||||
lbf.registerBeanDefinition("test", bd);
|
||||
|
||||
assertThatExceptionOfType(UnsatisfiedDependencyException.class).isThrownBy(lbf::preInstantiateSingletons);
|
||||
}
|
||||
|
||||
@Test
|
||||
void beanDefinitionWithInterface() {
|
||||
lbf.registerBeanDefinition("test", new RootBeanDefinition(ITestBean.class));
|
||||
|
||||
assertThatExceptionOfType(BeanCreationException.class).isThrownBy(() ->
|
||||
lbf.getBean("test"))
|
||||
.withMessageContaining("interface")
|
||||
@@ -2320,7 +2237,6 @@ class DefaultListableBeanFactoryTests {
|
||||
@Test
|
||||
void beanDefinitionWithAbstractClass() {
|
||||
lbf.registerBeanDefinition("test", new RootBeanDefinition(AbstractBeanFactory.class));
|
||||
|
||||
assertThatExceptionOfType(BeanCreationException.class).isThrownBy(() ->
|
||||
lbf.getBean("test"))
|
||||
.withMessageContaining("abstract")
|
||||
@@ -2364,7 +2280,6 @@ class DefaultListableBeanFactoryTests {
|
||||
void lazyInitFactory() {
|
||||
lbf.registerBeanDefinition("test", new RootBeanDefinition(LazyInitFactory.class));
|
||||
lbf.preInstantiateSingletons();
|
||||
|
||||
LazyInitFactory factory = (LazyInitFactory) lbf.getBean("&test");
|
||||
assertThat(factory.initialized).isFalse();
|
||||
}
|
||||
@@ -2373,7 +2288,6 @@ class DefaultListableBeanFactoryTests {
|
||||
void smartInitFactory() {
|
||||
lbf.registerBeanDefinition("test", new RootBeanDefinition(EagerInitFactory.class));
|
||||
lbf.preInstantiateSingletons();
|
||||
|
||||
EagerInitFactory factory = (EagerInitFactory) lbf.getBean("&test");
|
||||
assertThat(factory.initialized).isTrue();
|
||||
}
|
||||
@@ -2384,7 +2298,6 @@ class DefaultListableBeanFactoryTests {
|
||||
stringDef.setScope(BeanDefinition.SCOPE_PROTOTYPE);
|
||||
stringDef.getConstructorArgumentValues().addGenericArgumentValue(new TypedStringValue("value"));
|
||||
lbf.registerBeanDefinition("string", stringDef);
|
||||
|
||||
String val1 = lbf.getBean("string", String.class);
|
||||
String val2 = lbf.getBean("string", String.class);
|
||||
assertThat(val1).isEqualTo("value");
|
||||
@@ -2399,11 +2312,9 @@ class DefaultListableBeanFactoryTests {
|
||||
bd.setScope(BeanDefinition.SCOPE_PROTOTYPE);
|
||||
bd.getConstructorArgumentValues().addGenericArgumentValue(list);
|
||||
lbf.registerBeanDefinition("test", bd);
|
||||
|
||||
DerivedTestBean tb = (DerivedTestBean) lbf.getBean("test");
|
||||
assertThat(tb.getName()).isEqualTo("myName");
|
||||
assertThat(tb.getBeanName()).isEqualTo("myBeanName");
|
||||
|
||||
DerivedTestBean tb2 = (DerivedTestBean) lbf.getBean("test");
|
||||
assertThat(tb != tb2).isTrue();
|
||||
assertThat(tb2.getName()).isEqualTo("myName");
|
||||
@@ -2418,11 +2329,9 @@ class DefaultListableBeanFactoryTests {
|
||||
bd.setFactoryMethodName("create");
|
||||
bd.getConstructorArgumentValues().addGenericArgumentValue(list);
|
||||
lbf.registerBeanDefinition("test", bd);
|
||||
|
||||
DerivedTestBean tb = (DerivedTestBean) lbf.getBean("test");
|
||||
assertThat(tb.getName()).isEqualTo("myName");
|
||||
assertThat(tb.getBeanName()).isEqualTo("myBeanName");
|
||||
|
||||
DerivedTestBean tb2 = (DerivedTestBean) lbf.getBean("test");
|
||||
assertThat(tb != tb2).isTrue();
|
||||
assertThat(tb2.getName()).isEqualTo("myName");
|
||||
@@ -2435,7 +2344,6 @@ class DefaultListableBeanFactoryTests {
|
||||
bd.setInitMethodNames("init1", "init2");
|
||||
bd.setDestroyMethodNames("destroy2", "destroy1");
|
||||
lbf.registerBeanDefinition("test", bd);
|
||||
|
||||
BeanWithInitAndDestroyMethods bean = lbf.getBean("test", BeanWithInitAndDestroyMethods.class);
|
||||
assertThat(bean.initMethods).containsExactly("init", "init1", "init2");
|
||||
assertThat(bean.destroyMethods).isEmpty();
|
||||
@@ -2453,7 +2361,6 @@ class DefaultListableBeanFactoryTests {
|
||||
return new TestBean();
|
||||
}
|
||||
});
|
||||
|
||||
BeanWithDisposableBean.closed = false;
|
||||
lbf.preInstantiateSingletons();
|
||||
lbf.destroySingletons();
|
||||
@@ -2470,7 +2377,6 @@ class DefaultListableBeanFactoryTests {
|
||||
return new TestBean();
|
||||
}
|
||||
});
|
||||
|
||||
BeanWithDisposableBean.closed = false;
|
||||
lbf.preInstantiateSingletons();
|
||||
lbf.destroySingletons();
|
||||
@@ -2488,7 +2394,6 @@ class DefaultListableBeanFactoryTests {
|
||||
return new TestBean();
|
||||
}
|
||||
});
|
||||
|
||||
BeanWithDestroyMethod.closeCount = 0;
|
||||
lbf.preInstantiateSingletons();
|
||||
lbf.destroySingletons();
|
||||
@@ -2693,7 +2598,6 @@ class DefaultListableBeanFactoryTests {
|
||||
}
|
||||
});
|
||||
lbf.preInstantiateSingletons();
|
||||
|
||||
TestBean tb = (TestBean) lbf.getBean("test");
|
||||
assertThat(tb.getName()).as("Name was set on field by IAPP").isEqualTo(nameSetOnField);
|
||||
if (!skipPropertyPopulation) {
|
||||
@@ -2737,7 +2641,6 @@ class DefaultListableBeanFactoryTests {
|
||||
bd.setFactoryMethodName("of");
|
||||
bd.getConstructorArgumentValues().addGenericArgumentValue("CONTENT");
|
||||
lbf.registerBeanDefinition("optionalBean", bd);
|
||||
|
||||
assertThat((Optional<?>) lbf.getBean(Optional.class)).isEqualTo(Optional.of("CONTENT"));
|
||||
}
|
||||
|
||||
@@ -2746,7 +2649,6 @@ class DefaultListableBeanFactoryTests {
|
||||
RootBeanDefinition bd = new RootBeanDefinition(Optional.class);
|
||||
bd.setFactoryMethodName("empty");
|
||||
lbf.registerBeanDefinition("optionalBean", bd);
|
||||
|
||||
assertThat((Optional<?>) lbf.getBean(Optional.class)).isSameAs(Optional.empty());
|
||||
}
|
||||
|
||||
@@ -2755,21 +2657,18 @@ class DefaultListableBeanFactoryTests {
|
||||
RootBeanDefinition bd = new RootBeanDefinition(NonPublicEnumHolder.class);
|
||||
bd.getConstructorArgumentValues().addGenericArgumentValue("VALUE_1");
|
||||
lbf.registerBeanDefinition("holderBean", bd);
|
||||
|
||||
NonPublicEnumHolder holder = (NonPublicEnumHolder) lbf.getBean("holderBean");
|
||||
assertThat(holder.getNonPublicEnum()).isEqualTo(NonPublicEnum.VALUE_1);
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
private int registerBeanDefinitions(Properties p) {
|
||||
return registerBeanDefinitions(p, null);
|
||||
return (new org.springframework.beans.factory.support.PropertiesBeanDefinitionReader(lbf)).registerBeanDefinitions(p);
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
private int registerBeanDefinitions(Properties p, @Nullable String prefix) {
|
||||
for (String beanName : lbf.getBeanDefinitionNames()) {
|
||||
lbf.removeBeanDefinition(beanName);
|
||||
}
|
||||
private int registerBeanDefinitions(Properties p, String prefix) {
|
||||
return (new org.springframework.beans.factory.support.PropertiesBeanDefinitionReader(lbf)).registerBeanDefinitions(p, prefix);
|
||||
}
|
||||
|
||||
@@ -2821,7 +2720,7 @@ class DefaultListableBeanFactoryTests {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(@Nullable Object o) {
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
|
||||
+7
-43
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2023 the original author or authors.
|
||||
* Copyright 2002-2022 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.
|
||||
@@ -27,10 +27,10 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
|
||||
/**
|
||||
* Tests for {@link AbstractAutowireCapableBeanFactory} instance supplier support.
|
||||
* Tests for {@link AbstractAutowireCapableBeanFactory} instance supplier
|
||||
* support.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
* @author Juergen Hoeller
|
||||
*/
|
||||
public class BeanFactorySupplierTests {
|
||||
|
||||
@@ -43,39 +43,14 @@ public class BeanFactorySupplierTests {
|
||||
assertThat(beanFactory.getBean("test")).isEqualTo("I am supplied");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getBeanWithInnerBeanUsingRegularSupplier() {
|
||||
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
|
||||
RootBeanDefinition beanDefinition = new RootBeanDefinition();
|
||||
beanDefinition.setInstanceSupplier(() -> "I am supplied");
|
||||
RootBeanDefinition outerBean = new RootBeanDefinition(String.class);
|
||||
outerBean.getConstructorArgumentValues().addGenericArgumentValue(beanDefinition);
|
||||
beanFactory.registerBeanDefinition("test", outerBean);
|
||||
assertThat(beanFactory.getBean("test")).asString().startsWith("I am supplied");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getBeanWhenUsingInstanceSupplier() {
|
||||
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
|
||||
RootBeanDefinition beanDefinition = new RootBeanDefinition(String.class);
|
||||
beanDefinition.setInstanceSupplier(InstanceSupplier.of(registeredBean ->
|
||||
"I am bean " + registeredBean.getBeanName() + " of " + registeredBean.getBeanClass()));
|
||||
RootBeanDefinition beanDefinition = new RootBeanDefinition();
|
||||
beanDefinition.setInstanceSupplier(InstanceSupplier
|
||||
.of(registeredBean -> "I am bean " + registeredBean.getBeanName()));
|
||||
beanFactory.registerBeanDefinition("test", beanDefinition);
|
||||
assertThat(beanFactory.getBean("test")).isEqualTo("I am bean test of class java.lang.String");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getBeanWithInnerBeanUsingInstanceSupplier() {
|
||||
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
|
||||
RootBeanDefinition beanDefinition = new RootBeanDefinition(String.class);
|
||||
beanDefinition.setInstanceSupplier(InstanceSupplier.of(registeredBean ->
|
||||
"I am bean " + registeredBean.getBeanName() + " of " + registeredBean.getBeanClass()));
|
||||
RootBeanDefinition outerBean = new RootBeanDefinition(String.class);
|
||||
outerBean.getConstructorArgumentValues().addGenericArgumentValue(beanDefinition);
|
||||
beanFactory.registerBeanDefinition("test", outerBean);
|
||||
assertThat(beanFactory.getBean("test")).asString()
|
||||
.startsWith("I am bean (inner bean)")
|
||||
.endsWith(" of class java.lang.String");
|
||||
assertThat(beanFactory.getBean("test")).isEqualTo("I am bean test");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -87,17 +62,6 @@ public class BeanFactorySupplierTests {
|
||||
assertThat(beanFactory.getBean("test")).isEqualTo("I am supplied");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getBeanWithInnerBeanUsingThrowableSupplier() {
|
||||
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
|
||||
RootBeanDefinition beanDefinition = new RootBeanDefinition();
|
||||
beanDefinition.setInstanceSupplier(ThrowingSupplier.of(() -> "I am supplied"));
|
||||
RootBeanDefinition outerBean = new RootBeanDefinition(String.class);
|
||||
outerBean.getConstructorArgumentValues().addGenericArgumentValue(beanDefinition);
|
||||
beanFactory.registerBeanDefinition("test", outerBean);
|
||||
assertThat(beanFactory.getBean("test")).asString().startsWith("I am supplied");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getBeanWhenUsingThrowableSupplierThatThrowsCheckedException() {
|
||||
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
|
||||
|
||||
+2
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2023 the original author or authors.
|
||||
* Copyright 2002-2019 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.
|
||||
@@ -22,7 +22,6 @@ import java.util.List;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.testfixture.beans.TestBean;
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
@@ -195,7 +194,7 @@ public class PagedListHolderTests {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(@Nullable Object o) {
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
|
||||
+2
-4
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2023 the original author or authors.
|
||||
* Copyright 2002-2018 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.
|
||||
@@ -16,8 +16,6 @@
|
||||
|
||||
package org.springframework.beans.testfixture.beans;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
* Simple nested test bean used for testing bean factories, AOP framework etc.
|
||||
*
|
||||
@@ -45,7 +43,7 @@ public class NestedTestBean implements INestedTestBean {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(@Nullable Object obj) {
|
||||
public boolean equals(Object obj) {
|
||||
if (!(obj instanceof NestedTestBean ntb)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
+2
-4
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2023 the original author or authors.
|
||||
* Copyright 2002-2006 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.
|
||||
@@ -16,8 +16,6 @@
|
||||
|
||||
package org.springframework.beans.testfixture.beans;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
* @author Rob Harrop
|
||||
* @since 2.0
|
||||
@@ -40,7 +38,7 @@ public class Pet {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(@Nullable Object o) {
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
|
||||
+2
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2023 the original author or authors.
|
||||
* Copyright 2002-2016 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.
|
||||
@@ -18,7 +18,6 @@ package org.springframework.beans.testfixture.beans;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
/**
|
||||
@@ -64,7 +63,7 @@ public class SerializablePerson implements Person, Serializable {
|
||||
|
||||
|
||||
@Override
|
||||
public boolean equals(@Nullable Object other) {
|
||||
public boolean equals(Object other) {
|
||||
if (!(other instanceof SerializablePerson p)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
+2
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2023 the original author or authors.
|
||||
* Copyright 2002-2022 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.
|
||||
@@ -30,7 +30,6 @@ import java.util.Set;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.BeanFactoryAware;
|
||||
import org.springframework.beans.factory.BeanNameAware;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
/**
|
||||
@@ -465,7 +464,7 @@ public class TestBean implements BeanNameAware, BeanFactoryAware, ITestBean, IOt
|
||||
|
||||
|
||||
@Override
|
||||
public boolean equals(@Nullable Object other) {
|
||||
public boolean equals(Object other) {
|
||||
if (this == other) {
|
||||
return true;
|
||||
}
|
||||
|
||||
+3
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2023 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.
|
||||
@@ -133,8 +133,8 @@ public class CandidateComponentsIndexer implements Processor {
|
||||
List<TypeElement> list = new ArrayList<>();
|
||||
for (Element element : elements) {
|
||||
if ((element.getKind().isClass() || element.getKind() == ElementKind.INTERFACE) &&
|
||||
element.getModifiers().contains(Modifier.STATIC) && element instanceof TypeElement te) {
|
||||
list.add(te);
|
||||
element.getModifiers().contains(Modifier.STATIC) && element instanceof TypeElement) {
|
||||
list.add((TypeElement) element);
|
||||
}
|
||||
}
|
||||
return list;
|
||||
|
||||
+3
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2023 the original author or authors.
|
||||
* Copyright 2002-2022 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.
|
||||
@@ -73,8 +73,8 @@ class TypeHelper {
|
||||
}
|
||||
|
||||
private String getQualifiedName(Element element) {
|
||||
if (element instanceof QualifiedNameable qualifiedNameable) {
|
||||
return qualifiedNameable.getQualifiedName().toString();
|
||||
if (element instanceof QualifiedNameable) {
|
||||
return ((QualifiedNameable) element).getQualifiedName().toString();
|
||||
}
|
||||
return element.toString();
|
||||
}
|
||||
|
||||
-4
@@ -1,4 +0,0 @@
|
||||
/**
|
||||
* Core package for Spring Framework's scanned component index.
|
||||
*/
|
||||
package org.springframework.context.index.processor;
|
||||
+3
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2023 the original author or authors.
|
||||
* Copyright 2002-2020 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.
|
||||
@@ -93,8 +93,8 @@ public class CaffeineCache extends AbstractValueAdaptingCache {
|
||||
@Override
|
||||
@Nullable
|
||||
protected Object lookup(Object key) {
|
||||
if (this.cache instanceof LoadingCache<Object, Object> loadingCache) {
|
||||
return loadingCache.get(key);
|
||||
if (this.cache instanceof LoadingCache) {
|
||||
return ((LoadingCache<Object, Object>) this.cache).get(key);
|
||||
}
|
||||
return this.cache.getIfPresent(key);
|
||||
}
|
||||
|
||||
Vendored
+3
-9
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2023 the original author or authors.
|
||||
* Copyright 2002-2020 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.
|
||||
@@ -51,7 +51,6 @@ import org.springframework.util.ObjectUtils;
|
||||
* @author Juergen Hoeller
|
||||
* @author Stephane Nicoll
|
||||
* @author Sam Brannen
|
||||
* @author Brian Clozel
|
||||
* @since 4.3
|
||||
* @see CaffeineCache
|
||||
*/
|
||||
@@ -189,13 +188,8 @@ public class CaffeineCacheManager implements CacheManager {
|
||||
@Override
|
||||
@Nullable
|
||||
public Cache getCache(String name) {
|
||||
if (this.dynamic) {
|
||||
Cache cache = this.cacheMap.get(name);
|
||||
return (cache != null) ? cache : this.cacheMap.computeIfAbsent(name, this::createCaffeineCache);
|
||||
}
|
||||
else {
|
||||
return this.cacheMap.get(name);
|
||||
}
|
||||
return this.cacheMap.computeIfAbsent(name, cacheName ->
|
||||
this.dynamic ? createCaffeineCache(cacheName) : null);
|
||||
}
|
||||
|
||||
|
||||
|
||||
+3
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2023 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.
|
||||
@@ -48,8 +48,8 @@ public abstract class AbstractJCacheConfiguration extends AbstractCachingConfigu
|
||||
protected void useCachingConfigurer(CachingConfigurerSupplier cachingConfigurerSupplier) {
|
||||
super.useCachingConfigurer(cachingConfigurerSupplier);
|
||||
this.exceptionCacheResolver = cachingConfigurerSupplier.adapt(config -> {
|
||||
if (config instanceof JCacheConfigurer jcacheConfigurer) {
|
||||
return jcacheConfigurer.exceptionCacheResolver();
|
||||
if (config instanceof JCacheConfigurer) {
|
||||
return ((JCacheConfigurer) config).exceptionCacheResolver();
|
||||
}
|
||||
return null;
|
||||
});
|
||||
|
||||
Vendored
+5
-5
@@ -1,10 +1,10 @@
|
||||
/**
|
||||
* Support package for declarative JSR-107 caching configuration. Used by Spring's
|
||||
* caching configuration when it detects the JSR-107 API and Spring's JCache
|
||||
* implementation.
|
||||
* Support package for declarative JSR-107 caching configuration. Used
|
||||
* by the regular Spring's caching configuration when it detects the
|
||||
* JSR-107 API and Spring's JCache implementation.
|
||||
*
|
||||
* <p>Provides an extension of the {@code CachingConfigurer} that exposes
|
||||
* the exception cache resolver to use (see {@code JCacheConfigurer}).
|
||||
* <p>Provide an extension of the {@code CachingConfigurer} that exposes
|
||||
* the exception cache resolver to use, see {@code JCacheConfigurer}.
|
||||
*/
|
||||
@NonNullApi
|
||||
@NonNullFields
|
||||
|
||||
+3
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2023 the original author or authors.
|
||||
* Copyright 2002-2018 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.
|
||||
@@ -42,8 +42,8 @@ class DefaultCacheKeyInvocationContext<A extends Annotation> extends DefaultCach
|
||||
public DefaultCacheKeyInvocationContext(AbstractJCacheKeyOperation<A> operation, Object target, Object[] args) {
|
||||
super(operation, target, args);
|
||||
this.keyParameters = operation.getKeyParameters(args);
|
||||
if (operation instanceof CachePutOperation cachePutOperation) {
|
||||
this.valueParameter = cachePutOperation.getValueParameter(args);
|
||||
if (operation instanceof CachePutOperation) {
|
||||
this.valueParameter = ((CachePutOperation) operation).getValueParameter(args);
|
||||
}
|
||||
else {
|
||||
this.valueParameter = null;
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2023 the original author or authors.
|
||||
* Copyright 2002-2018 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.
|
||||
|
||||
+5
-5
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2023 the original author or authors.
|
||||
* Copyright 2002-2018 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.
|
||||
@@ -71,11 +71,11 @@ public class AdaptableJobFactory implements JobFactory {
|
||||
* @see DelegatingJob
|
||||
*/
|
||||
protected Job adaptJob(Object jobObject) throws Exception {
|
||||
if (jobObject instanceof Job job) {
|
||||
return job;
|
||||
if (jobObject instanceof Job) {
|
||||
return (Job) jobObject;
|
||||
}
|
||||
else if (jobObject instanceof Runnable runnable) {
|
||||
return new DelegatingJob(runnable);
|
||||
else if (jobObject instanceof Runnable) {
|
||||
return new DelegatingJob((Runnable) jobObject);
|
||||
}
|
||||
else {
|
||||
throw new IllegalArgumentException(
|
||||
|
||||
+3
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2023 the original author or authors.
|
||||
* Copyright 2002-2019 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.
|
||||
@@ -267,9 +267,9 @@ public class MethodInvokingJobDetailFactoryBean extends ArgumentConvertingMethod
|
||||
context.setResult(this.methodInvoker.invoke());
|
||||
}
|
||||
catch (InvocationTargetException ex) {
|
||||
if (ex.getTargetException() instanceof JobExecutionException jobExecutionException) {
|
||||
if (ex.getTargetException() instanceof JobExecutionException) {
|
||||
// -> JobExecutionException, to be logged at info level by Quartz
|
||||
throw jobExecutionException;
|
||||
throw (JobExecutionException) ex.getTargetException();
|
||||
}
|
||||
else {
|
||||
// -> "unhandled exception", to be logged at error level by Quartz
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user