diff --git a/spring-context/src/main/java/org/springframework/context/expression/MapAccessor.java b/spring-context/src/main/java/org/springframework/context/expression/MapAccessor.java index e7374fe305f..fb51e880b14 100644 --- a/spring-context/src/main/java/org/springframework/context/expression/MapAccessor.java +++ b/spring-context/src/main/java/org/springframework/context/expression/MapAccessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2021 the original author or authors. + * Copyright 2002-2024 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. @@ -37,6 +37,27 @@ import org.springframework.util.Assert; */ public class MapAccessor implements CompilablePropertyAccessor { + private final boolean allowWrite; + + /** + * Create a new map accessor for reading as well as writing. + * @since 6.2 + * @see #MapAccessor(boolean) + */ + public MapAccessor() { + this(true); + } + + /** + * Create a new map accessor for reading and possibly also writing. + * @param allowWrite whether to allow write operations on a target instance + * @since 6.2 + * @see #canWrite + */ + public MapAccessor(boolean allowWrite) { + this.allowWrite = allowWrite; + } + @Override public Class[] getSpecificTargetClasses() { return new Class[] {Map.class}; @@ -60,7 +81,7 @@ public class MapAccessor implements CompilablePropertyAccessor { @Override public boolean canWrite(EvaluationContext context, @Nullable Object target, String name) throws AccessException { - return true; + return this.allowWrite; } @Override diff --git a/spring-context/src/test/java/org/springframework/context/expression/MapAccessorTests.java b/spring-context/src/test/java/org/springframework/context/expression/MapAccessorTests.java index 7266570b76c..8c7c63fd0f9 100644 --- a/spring-context/src/test/java/org/springframework/context/expression/MapAccessorTests.java +++ b/spring-context/src/test/java/org/springframework/context/expression/MapAccessorTests.java @@ -80,6 +80,16 @@ class MapAccessorTests { assertThat(ex.getValue(sec,testMap)).isEqualTo("bar2"); } + @Test + void mapAccessorNotWritable() { + Map testMap = getSimpleTestMap(); + StandardEvaluationContext sec = new StandardEvaluationContext(); + sec.addPropertyAccessor(new MapAccessor(false)); + SpelExpressionParser sep = new SpelExpressionParser(); + Expression ex = sep.parseExpression("foo"); + assertThat(ex.isWritable(sec, testMap)).isFalse(); + } + public static class MapGetter { Map map = new HashMap<>();