Provide a flag to disable SpEL support

This commit introduces a spring.spel.ignore system property
which when set to true avoid initializing SpEL infrastructure.

A typical use case is optimizing GraalVM native image footprint
for applications not using SpEL. In order to be effective, those
classes should be initialized at build time:

- org.springframework.context.support.AbstractApplicationContext
- org.springframework.core.SpringProperties
- org.springframework.context.event.EventListenerMethodProcessor

Closes gh-25153
This commit is contained in:
Sébastien Deleuze 2020-06-18 15:57:58 +02:00
parent dc3801043f
commit 1c75f95be0
3 changed files with 36 additions and 5 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 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.
@ -142,7 +142,7 @@ public class ApplicationListenerMethodAdapter implements GenericApplicationListe
/**
* Initialize this instance.
*/
void init(ApplicationContext applicationContext, EventExpressionEvaluator evaluator) {
void init(ApplicationContext applicationContext, @Nullable EventExpressionEvaluator evaluator) {
this.applicationContext = applicationContext;
this.evaluator = evaluator;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 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.
@ -40,6 +40,7 @@ import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ApplicationListener;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.MethodIntrospector;
import org.springframework.core.SpringProperties;
import org.springframework.core.annotation.AnnotatedElementUtils;
import org.springframework.core.annotation.AnnotationAwareOrderComparator;
import org.springframework.core.annotation.AnnotationUtils;
@ -56,6 +57,7 @@ import org.springframework.util.CollectionUtils;
*
* @author Stephane Nicoll
* @author Juergen Hoeller
* @author Sebastien Deleuze
* @since 4.2
* @see EventListenerFactory
* @see DefaultEventListenerFactory
@ -63,6 +65,14 @@ import org.springframework.util.CollectionUtils;
public class EventListenerMethodProcessor
implements SmartInitializingSingleton, ApplicationContextAware, BeanFactoryPostProcessor {
/**
* Boolean flag controlled by a {@code spring.spel.ignore} system property that instructs Spring to
* ignore SpEL, i.e. to not initialize the SpEL infrastructure.
* <p>The default is "false".
*/
private static final boolean shouldIgnoreSpel = SpringProperties.getFlag("spring.spel.ignore");
protected final Log logger = LogFactory.getLog(getClass());
@Nullable
@ -74,11 +84,21 @@ public class EventListenerMethodProcessor
@Nullable
private List<EventListenerFactory> eventListenerFactories;
private final EventExpressionEvaluator evaluator = new EventExpressionEvaluator();
@Nullable
private final EventExpressionEvaluator evaluator;
private final Set<Class<?>> nonAnnotatedClasses = Collections.newSetFromMap(new ConcurrentHashMap<>(64));
public EventListenerMethodProcessor() {
if (shouldIgnoreSpel) {
this.evaluator = null;
}
else {
this.evaluator = new EventExpressionEvaluator();
}
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) {
Assert.isTrue(applicationContext instanceof ConfigurableApplicationContext,

View File

@ -67,6 +67,7 @@ import org.springframework.context.expression.StandardBeanExpressionResolver;
import org.springframework.context.weaving.LoadTimeWeaverAware;
import org.springframework.context.weaving.LoadTimeWeaverAwareProcessor;
import org.springframework.core.ResolvableType;
import org.springframework.core.SpringProperties;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.core.convert.ConversionService;
import org.springframework.core.env.ConfigurableEnvironment;
@ -117,6 +118,7 @@ import org.springframework.util.ReflectionUtils;
* @author Mark Fisher
* @author Stephane Nicoll
* @author Sam Brannen
* @author Sebastien Deleuze
* @since January 21, 2001
* @see #refreshBeanFactory
* @see #getBeanFactory
@ -152,6 +154,13 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
*/
public static final String APPLICATION_EVENT_MULTICASTER_BEAN_NAME = "applicationEventMulticaster";
/**
* Boolean flag controlled by a {@code spring.spel.ignore} system property that instructs Spring to
* ignore SpEL, i.e. to not initialize the SpEL infrastructure.
* <p>The default is "false".
*/
private static final boolean shouldIgnoreSpel = SpringProperties.getFlag("spring.spel.ignore");
static {
// Eagerly load the ContextClosedEvent class to avoid weird classloader issues
@ -647,7 +656,9 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// Tell the internal bean factory to use the context's class loader etc.
beanFactory.setBeanClassLoader(getClassLoader());
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
if (!shouldIgnoreSpel) {
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
}
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
// Configure the bean factory with context callbacks.