Browse Source

Merge branch '7.0.x'

# Conflicts:
#	framework-platform/framework-platform.gradle
pull/36522/head
Juergen Hoeller 1 week ago
parent
commit
a5579614d9
  1. 10
      framework-platform/framework-platform.gradle
  2. 22
      spring-context/src/main/java/org/springframework/jmx/export/MBeanExporter.java
  3. 29
      spring-context/src/test/java/org/springframework/jmx/export/MBeanExporterOperationsTests.java
  4. 27
      spring-core/src/main/java/org/springframework/util/TypeUtils.java

10
framework-platform/framework-platform.gradle

@ -31,7 +31,7 @@ dependencies { @@ -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 { @@ -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")

22
spring-context/src/main/java/org/springframework/jmx/export/MBeanExporter.java

@ -471,11 +471,29 @@ public class MBeanExporter extends MBeanRegistrationSupport implements MBeanExpo @@ -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
spring-context/src/test/java/org/springframework/jmx/export/MBeanExporterOperationsTests.java

@ -67,6 +67,35 @@ class MBeanExporterOperationsTests extends AbstractMBeanServerTests { @@ -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");

27
spring-core/src/main/java/org/springframework/util/TypeUtils.java

@ -46,8 +46,8 @@ public abstract class TypeUtils { @@ -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 { @@ -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 { @@ -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 { @@ -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 { @@ -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 { @@ -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 { @@ -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 { @@ -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 { @@ -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);
}

Loading…
Cancel
Save