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 e7374fe305fc..b523d1a54554 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. @@ -33,10 +33,30 @@ * * @author Juergen Hoeller * @author Andy Clement + * @author Yanming Zhou * @since 3.0 */ public class MapAccessor implements CompilablePropertyAccessor { + private final boolean allowWrite; + + /** + * Create a new map accessor for reading as well as writing. + * @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 + * @see #canWrite + */ + public MapAccessor(boolean allowWrite) { + this.allowWrite = allowWrite; + } + @Override public Class[] getSpecificTargetClasses() { return new Class[] {Map.class}; @@ -60,7 +80,7 @@ public TypedValue read(EvaluationContext context, @Nullable Object target, Strin @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 7266570b76cd..5f2dea2e9b5f 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 @@ -32,6 +32,7 @@ * Tests for {@link MapAccessor}. * * @author Andy Clement + * @author Yanming Zhou */ class MapAccessorTests { @@ -80,6 +81,16 @@ void mapAccessorCompilable() { 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<>();