mirror of
https://github.com/spring-projects/spring-framework
synced 2026-06-08 17:33:33 +00:00
Merge branch '7.0.x'
# Conflicts: # framework-platform/framework-platform.gradle
This commit is contained in:
@@ -31,7 +31,7 @@ dependencies {
|
||||
api("com.google.code.findbugs:findbugs:3.0.1")
|
||||
api("com.google.code.findbugs:jsr305:3.0.2")
|
||||
api("com.google.code.gson:gson:2.13.2")
|
||||
api("com.google.protobuf:protobuf-java-util:4.34.0")
|
||||
api("com.google.protobuf:protobuf-java-util:4.34.1")
|
||||
api("com.h2database:h2:2.4.240")
|
||||
api("com.jayway.jsonpath:json-path:2.10.0")
|
||||
api("com.networknt:json-schema-validator:1.5.3")
|
||||
@@ -96,10 +96,10 @@ dependencies {
|
||||
api("org.apache.httpcomponents.client5:httpclient5:5.6")
|
||||
api("org.apache.httpcomponents.core5:httpcore5-reactive:5.4.2")
|
||||
api("org.apache.poi:poi-ooxml:5.5.1")
|
||||
api("org.apache.tomcat.embed:tomcat-embed-core:11.0.18")
|
||||
api("org.apache.tomcat.embed:tomcat-embed-websocket:11.0.18")
|
||||
api("org.apache.tomcat:tomcat-util:11.0.18")
|
||||
api("org.apache.tomcat:tomcat-websocket:11.0.18")
|
||||
api("org.apache.tomcat.embed:tomcat-embed-core:11.0.20")
|
||||
api("org.apache.tomcat.embed:tomcat-embed-websocket:11.0.20")
|
||||
api("org.apache.tomcat:tomcat-util:11.0.20")
|
||||
api("org.apache.tomcat:tomcat-websocket:11.0.20")
|
||||
api("org.aspectj:aspectjrt:1.9.25")
|
||||
api("org.aspectj:aspectjtools:1.9.25")
|
||||
api("org.aspectj:aspectjweaver:1.9.25")
|
||||
|
||||
@@ -471,11 +471,29 @@ public class MBeanExporter extends MBeanRegistrationSupport implements MBeanExpo
|
||||
|
||||
@Override
|
||||
public ObjectName registerManagedResource(Object managedResource) throws MBeanExportException {
|
||||
return registerManagedResource(managedResource, (String) null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the supplied resource with JMX. If the resource is not a valid MBean already,
|
||||
* Spring will generate a management interface for it. The exact interface generated will
|
||||
* depend on the implementation and its configuration. This call also generates an
|
||||
* {@link ObjectName} for the managed resource and returns this to the caller.
|
||||
* @param managedResource the resource to expose via JMX
|
||||
* @param beanKey the corresponding bean key for {@link ObjectNamingStrategy} purposes
|
||||
* (making the generated {@code ObjectName} unique without the need for an identity key)
|
||||
* @return the {@link ObjectName} under which the resource was exposed
|
||||
* @throws MBeanExportException if Spring is unable to generate an {@link ObjectName}
|
||||
* or register the MBean
|
||||
* @since 7.0.7
|
||||
* @see ObjectNamingStrategy#getObjectName(Object, String)
|
||||
*/
|
||||
public ObjectName registerManagedResource(Object managedResource, @Nullable String beanKey) throws MBeanExportException {
|
||||
Assert.notNull(managedResource, "Managed resource must not be null");
|
||||
ObjectName objectName;
|
||||
try {
|
||||
objectName = getObjectName(managedResource, null);
|
||||
if (this.ensureUniqueRuntimeObjectNames) {
|
||||
objectName = getObjectName(managedResource, beanKey);
|
||||
if (beanKey == null && this.ensureUniqueRuntimeObjectNames) {
|
||||
objectName = JmxUtils.appendIdentityToObjectName(objectName, managedResource);
|
||||
}
|
||||
}
|
||||
|
||||
+29
@@ -67,6 +67,35 @@ class MBeanExporterOperationsTests extends AbstractMBeanServerTests {
|
||||
assertThat(infoFromServer).isEqualTo(info);
|
||||
}
|
||||
|
||||
@Test
|
||||
void registerManagedResourceWithUserSuppliedBeanKey() throws Exception {
|
||||
ObjectName objectName = ObjectNameManager.getInstance("spring:name=Foo");
|
||||
|
||||
JmxTestBean bean = new JmxTestBean();
|
||||
bean.setName("Rob Harrop");
|
||||
|
||||
MBeanExporter exporter = new MBeanExporter();
|
||||
exporter.setServer(getServer());
|
||||
exporter.registerManagedResource(bean, "spring:name=Foo");
|
||||
|
||||
String name = (String) getServer().getAttribute(objectName, "Name");
|
||||
assertThat(bean.getName()).as("Incorrect name on MBean").isEqualTo(name);
|
||||
}
|
||||
|
||||
@Test
|
||||
void registerExistingMBeanWithUserSuppliedBeanKey() throws Exception {
|
||||
ObjectName objectName = ObjectNameManager.getInstance("spring:name=Foo");
|
||||
ModelMBeanInfo info = new ModelMBeanInfoSupport("myClass", "myDescription", null, null, null, null);
|
||||
RequiredModelMBean bean = new RequiredModelMBean(info);
|
||||
|
||||
MBeanExporter exporter = new MBeanExporter();
|
||||
exporter.setServer(getServer());
|
||||
exporter.registerManagedResource(bean, "spring:name=Foo");
|
||||
|
||||
MBeanInfo infoFromServer = getServer().getMBeanInfo(objectName);
|
||||
assertThat(infoFromServer).isEqualTo(info);
|
||||
}
|
||||
|
||||
@Test
|
||||
void registerManagedResourceWithGeneratedObjectName() throws Exception {
|
||||
final ObjectName objectNameTemplate = ObjectNameManager.getInstance("spring:type=Test");
|
||||
|
||||
@@ -46,8 +46,8 @@ public abstract class TypeUtils {
|
||||
/**
|
||||
* Check if the right-hand side type may be assigned to the left-hand side
|
||||
* type following the Java generics rules.
|
||||
* @param lhsType the target type (left-hand side (LHS) type)
|
||||
* @param rhsType the value type (right-hand side (RHS) type) that should
|
||||
* @param lhsType the target type (left-hand side type)
|
||||
* @param rhsType the value type (right-hand side type) that should
|
||||
* be assigned to the target type
|
||||
* @return {@code true} if {@code rhsType} is assignable to {@code lhsType}
|
||||
* @see ClassUtils#isAssignable(Class, Class)
|
||||
@@ -56,37 +56,34 @@ public abstract class TypeUtils {
|
||||
Assert.notNull(lhsType, "Left-hand side type must not be null");
|
||||
Assert.notNull(rhsType, "Right-hand side type must not be null");
|
||||
|
||||
// all types are assignable to themselves and to class Object
|
||||
// All types are assignable to themselves and to class Object.
|
||||
if (lhsType.equals(rhsType) || Object.class == lhsType) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (lhsType instanceof Class<?> lhsClass) {
|
||||
// just comparing two classes
|
||||
// Just comparing two classes...
|
||||
if (rhsType instanceof Class<?> rhsClass) {
|
||||
return ClassUtils.isAssignable(lhsClass, rhsClass);
|
||||
}
|
||||
|
||||
if (rhsType instanceof ParameterizedType rhsParameterizedType) {
|
||||
Type rhsRaw = rhsParameterizedType.getRawType();
|
||||
|
||||
// a parameterized type is always assignable to its raw class type
|
||||
// A parameterized type is always assignable to its raw class type.
|
||||
if (rhsRaw instanceof Class<?> rhRawClass) {
|
||||
return ClassUtils.isAssignable(lhsClass, rhRawClass);
|
||||
}
|
||||
}
|
||||
else if (lhsClass.isArray() && rhsType instanceof GenericArrayType rhsGenericArrayType) {
|
||||
Type rhsComponent = rhsGenericArrayType.getGenericComponentType();
|
||||
|
||||
return isAssignable(lhsClass.componentType(), rhsComponent);
|
||||
}
|
||||
}
|
||||
|
||||
// parameterized types are only assignable to other parameterized types and class types
|
||||
// Parameterized types are only assignable to other parameterized types and class types.
|
||||
if (lhsType instanceof ParameterizedType lhsParameterizedType) {
|
||||
if (rhsType instanceof Class<?> rhsClass) {
|
||||
Type lhsRaw = lhsParameterizedType.getRawType();
|
||||
|
||||
if (lhsRaw instanceof Class<?> lhsClass) {
|
||||
return ClassUtils.isAssignable(lhsClass, rhsClass);
|
||||
}
|
||||
@@ -98,7 +95,6 @@ public abstract class TypeUtils {
|
||||
|
||||
if (lhsType instanceof GenericArrayType lhsGenericArrayType) {
|
||||
Type lhsComponent = lhsGenericArrayType.getGenericComponentType();
|
||||
|
||||
if (rhsType instanceof Class<?> rhsClass && rhsClass.isArray()) {
|
||||
return isAssignable(lhsComponent, rhsClass.componentType());
|
||||
}
|
||||
@@ -123,7 +119,6 @@ public abstract class TypeUtils {
|
||||
|
||||
Type[] lhsTypeArguments = lhsType.getActualTypeArguments();
|
||||
Type[] rhsTypeArguments = rhsType.getActualTypeArguments();
|
||||
|
||||
if (lhsTypeArguments.length != rhsTypeArguments.length) {
|
||||
return false;
|
||||
}
|
||||
@@ -131,7 +126,6 @@ public abstract class TypeUtils {
|
||||
for (int size = lhsTypeArguments.length, i = 0; i < size; ++i) {
|
||||
Type lhsArg = lhsTypeArguments[i];
|
||||
Type rhsArg = rhsTypeArguments[i];
|
||||
|
||||
if (!lhsArg.equals(rhsArg) &&
|
||||
!(lhsArg instanceof WildcardType wildcardType && isAssignable(wildcardType, rhsArg))) {
|
||||
return false;
|
||||
@@ -157,7 +151,6 @@ public abstract class TypeUtils {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
for (Type rBound : rLowerBounds) {
|
||||
if (!isAssignableBound(lBound, rBound)) {
|
||||
return false;
|
||||
@@ -171,7 +164,6 @@ public abstract class TypeUtils {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
for (Type rBound : rLowerBounds) {
|
||||
if (!isAssignableBound(rBound, lBound)) {
|
||||
return false;
|
||||
@@ -185,7 +177,6 @@ public abstract class TypeUtils {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
for (Type lBound : lLowerBounds) {
|
||||
if (!isAssignableBound(rhsType, lBound)) {
|
||||
return false;
|
||||
@@ -198,15 +189,13 @@ public abstract class TypeUtils {
|
||||
|
||||
private static @Nullable Type[] getLowerBounds(WildcardType wildcardType) {
|
||||
Type[] lowerBounds = wildcardType.getLowerBounds();
|
||||
|
||||
// supply the implicit lower bound if none are specified
|
||||
// Supply the implicit lower bound if none are specified.
|
||||
return (lowerBounds.length == 0 ? IMPLICIT_LOWER_BOUNDS : lowerBounds);
|
||||
}
|
||||
|
||||
private static Type[] getUpperBounds(WildcardType wildcardType) {
|
||||
Type[] upperBounds = wildcardType.getUpperBounds();
|
||||
|
||||
// supply the implicit upper bound if none are specified
|
||||
// Supply the implicit upper bound if none are specified.
|
||||
return (upperBounds.length == 0 ? IMPLICIT_UPPER_BOUNDS : upperBounds);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user