Skip to content

Commit fffeaee

Browse files
jhoellerunknown
authored and
unknown
committed
Minor refinements along the way of researching static CGLIB callbacks
Specifically, our CallbackFilter doesn't hold an implicit reference to the containing ConfigurationClassEnhancer class anymore. Issue: SPR-10307
1 parent b00f90f commit fffeaee

File tree

1 file changed

+43
-33
lines changed

1 file changed

+43
-33
lines changed

spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassEnhancer.java

Lines changed: 43 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2012 the original author or authors.
2+
* Copyright 2002-2013 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -52,25 +52,13 @@ class ConfigurationClassEnhancer {
5252

5353
private static final Log logger = LogFactory.getLog(ConfigurationClassEnhancer.class);
5454

55-
private static final Class<?>[] CALLBACK_TYPES = {BeanMethodInterceptor.class,
56-
DisposableBeanMethodInterceptor.class, NoOp.class};
57-
58-
private static final CallbackFilter CALLBACK_FILTER = new CallbackFilter() {
59-
public int accept(Method candidateMethod) {
60-
// Set up the callback filter to return the index of the BeanMethodInterceptor when
61-
// handling a @Bean-annotated method; otherwise, return index of the NoOp callback.
62-
if (BeanAnnotationHelper.isBeanAnnotated(candidateMethod)) {
63-
return 0;
64-
}
65-
if (DisposableBeanMethodInterceptor.isDestroyMethod(candidateMethod)) {
66-
return 1;
67-
}
68-
return 2;
69-
}
70-
};
55+
private static final CallbackFilter CALLBACK_FILTER = new ConfigurationClassCallbackFilter();
7156

7257
private static final Callback DISPOSABLE_BEAN_METHOD_INTERCEPTOR = new DisposableBeanMethodInterceptor();
7358

59+
private static final Class<?>[] CALLBACK_TYPES =
60+
{BeanMethodInterceptor.class, DisposableBeanMethodInterceptor.class, NoOp.class};
61+
7462
private final Callback[] callbackInstances;
7563

7664

@@ -109,21 +97,6 @@ public Class<?> enhance(Class<?> configClass) {
10997
return enhancedClass;
11098
}
11199

112-
/**
113-
* Marker interface to be implemented by all @Configuration CGLIB subclasses.
114-
* Facilitates idempotent behavior for {@link ConfigurationClassEnhancer#enhance(Class)}
115-
* through checking to see if candidate classes are already assignable to it, e.g.
116-
* have already been enhanced.
117-
* <p>Also extends {@link DisposableBean}, as all enhanced
118-
* {@code @Configuration} classes must de-register static CGLIB callbacks on
119-
* destruction, which is handled by the (private) {@code DisposableBeanMethodInterceptor}.
120-
* <p>Note that this interface is intended for framework-internal use only, however
121-
* must remain public in order to allow access to subclasses generated from other
122-
* packages (i.e. user code).
123-
*/
124-
public interface EnhancedConfiguration extends DisposableBean {
125-
}
126-
127100
/**
128101
* Creates a new CGLIB {@link Enhancer} instance.
129102
*/
@@ -149,6 +122,43 @@ private Class<?> createClass(Enhancer enhancer) {
149122
}
150123

151124

125+
126+
/**
127+
* Marker interface to be implemented by all @Configuration CGLIB subclasses.
128+
* Facilitates idempotent behavior for {@link ConfigurationClassEnhancer#enhance(Class)}
129+
* through checking to see if candidate classes are already assignable to it, e.g.
130+
* have already been enhanced.
131+
* <p>Also extends {@link DisposableBean}, as all enhanced
132+
* {@code @Configuration} classes must de-register static CGLIB callbacks on
133+
* destruction, which is handled by the (private) {@code DisposableBeanMethodInterceptor}.
134+
* <p>Note that this interface is intended for framework-internal use only, however
135+
* must remain public in order to allow access to subclasses generated from other
136+
* packages (i.e. user code).
137+
*/
138+
public interface EnhancedConfiguration extends DisposableBean {
139+
}
140+
141+
142+
/**
143+
* CGLIB CallbackFilter implementation that points to BeanMethodInterceptor and
144+
* DisposableBeanMethodInterceptor.
145+
*/
146+
private static class ConfigurationClassCallbackFilter implements CallbackFilter {
147+
148+
public int accept(Method candidateMethod) {
149+
// Set up the callback filter to return the index of the BeanMethodInterceptor when
150+
// handling a @Bean-annotated method; otherwise, return index of the NoOp callback.
151+
if (BeanAnnotationHelper.isBeanAnnotated(candidateMethod)) {
152+
return 0;
153+
}
154+
if (DisposableBeanMethodInterceptor.isDestroyMethod(candidateMethod)) {
155+
return 1;
156+
}
157+
return 2;
158+
}
159+
}
160+
161+
152162
/**
153163
* Intercepts calls to {@link FactoryBean#getObject()}, delegating to calling
154164
* {@link BeanFactory#getBean(String)} in order to respect caching / scoping.
@@ -175,7 +185,7 @@ public Object intercept(Object obj, Method method, Object[] args, MethodProxy pr
175185
/**
176186
* Intercepts the invocation of any {@link DisposableBean#destroy()} on @Configuration
177187
* class instances for the purpose of de-registering CGLIB callbacks. This helps avoid
178-
* garbage collection issues See SPR-7901.
188+
* garbage collection issues. See SPR-7901.
179189
* @see EnhancedConfiguration
180190
*/
181191
private static class DisposableBeanMethodInterceptor implements MethodInterceptor {

0 commit comments

Comments
 (0)