Top Description Inners Fields Constructors Methods
org.springframework.context.annotation

pack-priv Class ConfigurationClassEnhancer

extends Object
Class Inheritance
Imports
java.lang.reflect.Field, .Method, .Modifier, .Proxy, java.util.Arrays, org.apache.commons.logging.Log, .LogFactory, org.springframework.aop.scope.ScopedProxyFactoryBean, org.springframework.asm.Opcodes, .Type, org.springframework.beans.factory.BeanFactory, .BeanFactoryAware, .NoSuchBeanDefinitionException, org.springframework.beans.factory.config.BeanDefinition, .BeanFactoryPostProcessor, .ConfigurableBeanFactory, org.springframework.beans.factory.support.SimpleInstantiationStrategy, org.springframework.cglib.core.ClassGenerator, .ClassLoaderAwareGeneratorStrategy, .SpringNamingPolicy, org.springframework.cglib.proxy.Callback, .CallbackFilter, .Enhancer, .Factory, .MethodInterceptor, .MethodProxy, .NoOp, org.springframework.cglib.transform.ClassEmitterTransformer, .TransformingClassGenerator, org.springframework.lang.Nullable, org.springframework.objenesis.ObjenesisException, .SpringObjenesis, org.springframework.util.Assert, .ClassUtils, .ObjectUtils, .ReflectionUtils

Enhances Configuration classes by generating a CGLIB subclass which interacts with the Spring container to respect bean scoping semantics for @Bean methods. Each such @Bean method will be overridden in the generated subclass, only delegating to the actual @Bean method implementation if the container actually requests the construction of a new instance. Otherwise, a call to such an @Bean method serves as a reference back to the container, obtaining the corresponding bean by name.
Authors
Chris Beams, Juergen Hoeller
Since
3.0
See Also
enhance, ConfigurationClassPostProcessor

Nested and Inner Type Summary

Modifier and TypeClass and Description
private static class
ConfigurationClassEnhancer.BeanFactoryAwareGeneratorStrategy

Custom extension of CGLIB's DefaultGeneratorStrategy, introducing a BeanFactory field.

private static class
ConfigurationClassEnhancer.BeanFactoryAwareMethodInterceptor

Intercepts the invocation of any BeanFactoryAware#setBeanFactory(BeanFactory) on @Configuration class instances for the purpose of recording the BeanFactory.

private static class
ConfigurationClassEnhancer.BeanMethodInterceptor

Intercepts the invocation of any Bean-annotated methods in order to ensure proper handling of bean semantics such as scoping and AOP proxying.

private static interface
private static class
ConfigurationClassEnhancer.ConditionalCallbackFilter

A CallbackFilter that works by interrogating Callbacks in the order that they are defined via ConditionalCallback.

public static interface
ConfigurationClassEnhancer.EnhancedConfiguration

Marker interface to be implemented by all @Configuration CGLIB subclasses.

Field Summary

Modifier and TypeField and Description
private static final String
private static final ConfigurationClassEnhancer.ConditionalCallbackFilter
pack-priv static final Callback[]
private static final Log
private static final SpringObjenesis

Constructor Summary

AccessConstructor and Description
pack-priv

Method Summary

Modifier and TypeMethod and Description
private Class<?>
createClass(Enhancer enhancer)

Uses enhancer to generate a subclass of superclass, ensuring that callbacks are registered for the new subclass.

public Class<?>

Returns:

the enhanced subclass
enhance
(Class<?> configClass, ClassLoader classLoader)

Loads the specified class and generates a CGLIB subclass of it equipped with container-aware callbacks capable of respecting scoping and other bean semantics.

private Enhancer
newEnhancer(Class<?> configSuperClass, ClassLoader classLoader)

Creates a new CGLIB Enhancer instance.

Inherited from java.lang.Object:
cloneequalsfinalizegetClasshashCodenotifynotifyAlltoStringwaitwaitwait

Field Detail

BEAN_FACTORY_FIELDback to summary
private static final String BEAN_FACTORY_FIELD
CALLBACK_FILTERback to summary
private static final ConfigurationClassEnhancer.ConditionalCallbackFilter CALLBACK_FILTER
CALLBACKSback to summary
pack-priv static final Callback[] CALLBACKS
loggerback to summary
private static final Log logger
objenesisback to summary
private static final SpringObjenesis objenesis

Constructor Detail

ConfigurationClassEnhancerback to summary
pack-priv ConfigurationClassEnhancer()

Method Detail

createClassback to summary
private Class<?> createClass(Enhancer enhancer)

Uses enhancer to generate a subclass of superclass, ensuring that callbacks are registered for the new subclass.

enhanceback to summary
public Class<?> enhance(Class<?> configClass, ClassLoader classLoader)

Loads the specified class and generates a CGLIB subclass of it equipped with container-aware callbacks capable of respecting scoping and other bean semantics.

Returns:Class<?>

the enhanced subclass

newEnhancerback to summary
private Enhancer newEnhancer(Class<?> configSuperClass, ClassLoader classLoader)

Creates a new CGLIB Enhancer instance.

org.springframework.context.annotation back to summary

private Class ConfigurationClassEnhancer.BeanFactoryAwareGeneratorStrategy

extends ClassLoaderAwareGeneratorStrategy
Class Inheritance

Custom extension of CGLIB's DefaultGeneratorStrategy, introducing a BeanFactory field. Also exposes the application ClassLoader as thread context ClassLoader for the time of class generation (in order for ASM to pick it up when doing common superclass resolution).

Constructor Summary

AccessConstructor and Description
public

Method Summary

Modifier and TypeMethod and Description
protected ClassGenerator
Inherited from org.springframework.cglib.core.ClassLoaderAwareGeneratorStrategy:
generate

Constructor Detail

BeanFactoryAwareGeneratorStrategyback to summary
public BeanFactoryAwareGeneratorStrategy(ClassLoader classLoader)

Method Detail

transformback to summary
protected ClassGenerator transform(ClassGenerator cg) throws Exception

Overrides org.springframework.cglib.core.DefaultGeneratorStrategy.transform.

Annotations
@Override
org.springframework.context.annotation back to summary

private Class ConfigurationClassEnhancer.BeanFactoryAwareMethodInterceptor

extends Object
implements MethodInterceptor, ConditionalCallback
Class Inheritance
  • java.lang.Object
  • org.springframework.context.annotation.ConfigurationClassEnhancer.BeanFactoryAwareMethodInterceptor
All Implemented Interfaces
org.springframework.context.annotation.ConfigurationClassEnhancer.ConditionalCallback, org.springframework.cglib.proxy.Callback, org.springframework.cglib.proxy.MethodInterceptor

Intercepts the invocation of any BeanFactoryAware#setBeanFactory(BeanFactory) on @Configuration class instances for the purpose of recording the BeanFactory.
See Also
EnhancedConfiguration

Constructor Summary

AccessConstructor and Description
private

Method Summary

Modifier and TypeMethod and Description
public Object
intercept(Object
"this", the enhanced object
obj
,
Method
intercepted Method
method
,
Object[]
argument array; primitive types are wrapped
args
,
MethodProxy
used to invoke super (non-intercepted method); may be called as many times as needed
proxy
)

Implements org.springframework.cglib.proxy.MethodInterceptor.intercept.

All generated proxied methods call this method instead of the original method.

public boolean
public static boolean
isSetBeanFactory(Method candidateMethod)

Inherited from java.lang.Object:
cloneequalsfinalizegetClasshashCodenotifynotifyAlltoStringwaitwaitwait

Constructor Detail

BeanFactoryAwareMethodInterceptorback to summary
private BeanFactoryAwareMethodInterceptor()

Method Detail

interceptback to summary
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable

Implements org.springframework.cglib.proxy.MethodInterceptor.intercept.

Doc from org.springframework.cglib.proxy.MethodInterceptor.intercept.

All generated proxied methods call this method instead of the original method. The original method may either be invoked by normal reflection using the Method object, or by using the MethodProxy (faster).

Parameters
obj:Object

"this", the enhanced object

method:Method

intercepted Method

args:Object[]

argument array; primitive types are wrapped

proxy:MethodProxy

used to invoke super (non-intercepted method); may be called as many times as needed

Returns:Object

any value compatible with the signature of the proxied method. Method returning void will ignore this value.

Annotations
@Override
@Nullable
Exceptions
Throwable:
any exception may be thrown; if so, super method will not be invoked
isMatchback to summary
public boolean isMatch(Method candidateMethod)

Implements org.springframework.context.annotation.ConfigurationClassEnhancer.ConditionalCallback.isMatch.

Annotations
@Override
isSetBeanFactoryback to summary
public static boolean isSetBeanFactory(Method candidateMethod)
org.springframework.context.annotation back to summary

private Class ConfigurationClassEnhancer.BeanMethodInterceptor

extends Object
implements MethodInterceptor, ConditionalCallback
Class Inheritance
  • java.lang.Object
  • org.springframework.context.annotation.ConfigurationClassEnhancer.BeanMethodInterceptor
All Implemented Interfaces
org.springframework.context.annotation.ConfigurationClassEnhancer.ConditionalCallback, org.springframework.cglib.proxy.Callback, org.springframework.cglib.proxy.MethodInterceptor

Intercepts the invocation of any Bean-annotated methods in order to ensure proper handling of bean semantics such as scoping and AOP proxying.
See Also
Bean, ConfigurationClassEnhancer

Constructor Summary

AccessConstructor and Description
private

Method Summary

Modifier and TypeMethod and Description
private Object
private Object
createInterfaceProxyForFactoryBean(Object factoryBean, Class<?> interfaceType, ConfigurableBeanFactory beanFactory, String beanName)

private Object
enhanceFactoryBean(Object factoryBean, Class<?> exposedType, ConfigurableBeanFactory beanFactory, String beanName)

Create a subclass proxy that intercepts calls to getObject(), delegating to the current BeanFactory instead of creating a new instance.

private boolean

Returns:

whether beanName already exists in the factory
factoryContainsBean
(ConfigurableBeanFactory beanFactory, String
name of bean to check for
beanName
)

Check the BeanFactory to see whether the bean named beanName already exists.

private ConfigurableBeanFactory
getBeanFactory(Object enhancedConfigInstance)

public Object
intercept(Object
"this", the enhanced object
enhancedConfigInstance
,
Method
intercepted Method
beanMethod
,
Object[]
argument array; primitive types are wrapped
beanMethodArgs
,
MethodProxy
used to invoke super (non-intercepted method); may be called as many times as needed
cglibMethodProxy
)

Implements org.springframework.cglib.proxy.MethodInterceptor.intercept.

Enhance a @Bean method to check the supplied BeanFactory for the existence of this bean object.

private boolean
isCurrentlyInvokedFactoryMethod(Method method)

Check whether the given method corresponds to the container's currently invoked factory method.

public boolean
private Object
resolveBeanReference(Method beanMethod, Object[] beanMethodArgs, ConfigurableBeanFactory beanFactory, String beanName)

Inherited from java.lang.Object:
cloneequalsfinalizegetClasshashCodenotifynotifyAlltoStringwaitwaitwait

Constructor Detail

BeanMethodInterceptorback to summary
private BeanMethodInterceptor()

Method Detail

createCglibProxyForFactoryBeanback to summary
private Object createCglibProxyForFactoryBean(Object factoryBean, ConfigurableBeanFactory beanFactory, String beanName)
createInterfaceProxyForFactoryBeanback to summary
private Object createInterfaceProxyForFactoryBean(Object factoryBean, Class<?> interfaceType, ConfigurableBeanFactory beanFactory, String beanName)
enhanceFactoryBeanback to summary
private Object enhanceFactoryBean(Object factoryBean, Class<?> exposedType, ConfigurableBeanFactory beanFactory, String beanName)

Create a subclass proxy that intercepts calls to getObject(), delegating to the current BeanFactory instead of creating a new instance. These proxies are created only when calling a FactoryBean from within a Bean method, allowing for proper scoping semantics even when working against the FactoryBean instance directly. If a FactoryBean instance is fetched through the container via &-dereferencing, it will not be proxied. This too is aligned with the way XML configuration works.

factoryContainsBeanback to summary
private boolean factoryContainsBean(ConfigurableBeanFactory beanFactory, String beanName)

Check the BeanFactory to see whether the bean named beanName already exists. Accounts for the fact that the requested bean may be "in creation", i.e.: we're in the middle of servicing the initial request for this bean. From an enhanced factory method's perspective, this means that the bean does not actually yet exist, and that it is now our job to create it for the first time by executing the logic in the corresponding factory method.

Said another way, this check repurposes ConfigurableBeanFactory#isCurrentlyInCreation(String) to determine whether the container is calling this method or the user is calling this method.

Parameters
beanName:String

name of bean to check for

Returns:boolean

whether beanName already exists in the factory

getBeanFactoryback to summary
private ConfigurableBeanFactory getBeanFactory(Object enhancedConfigInstance)
interceptback to summary
public Object intercept(Object enhancedConfigInstance, Method beanMethod, Object[] beanMethodArgs, MethodProxy cglibMethodProxy) throws Throwable

Implements org.springframework.cglib.proxy.MethodInterceptor.intercept.

Enhance a @Bean method to check the supplied BeanFactory for the existence of this bean object.

Parameters
enhancedConfigInstance:Object

Doc from org.springframework.cglib.proxy.MethodInterceptor.intercept.

"this", the enhanced object

beanMethod:Method

Doc from org.springframework.cglib.proxy.MethodInterceptor.intercept.

intercepted Method

beanMethodArgs:Object[]

Doc from org.springframework.cglib.proxy.MethodInterceptor.intercept.

argument array; primitive types are wrapped

cglibMethodProxy:MethodProxy

Doc from org.springframework.cglib.proxy.MethodInterceptor.intercept.

used to invoke super (non-intercepted method); may be called as many times as needed

Returns:Object

Doc from org.springframework.cglib.proxy.MethodInterceptor.intercept.

any value compatible with the signature of the proxied method. Method returning void will ignore this value.

Annotations
@Override
@Nullable
Exceptions
Throwable:
as a catch-all for any exception that may be thrown when invoking the super implementation of the proxied method i.e., the actual @Bean method
isCurrentlyInvokedFactoryMethodback to summary
private boolean isCurrentlyInvokedFactoryMethod(Method method)

Check whether the given method corresponds to the container's currently invoked factory method. Compares method name and parameter types only in order to work around a potential problem with covariant return types (currently only known to happen on Groovy classes).

isMatchback to summary
public boolean isMatch(Method candidateMethod)

Implements org.springframework.context.annotation.ConfigurationClassEnhancer.ConditionalCallback.isMatch.

Annotations
@Override
resolveBeanReferenceback to summary
private Object resolveBeanReference(Method beanMethod, Object[] beanMethodArgs, ConfigurableBeanFactory beanFactory, String beanName)
org.springframework.context.annotation back to summary

private Interface ConfigurationClassEnhancer.ConditionalCallback

extends Callback
Known Direct Implementers
org.springframework.context.annotation.ConfigurationClassEnhancer.BeanFactoryAwareMethodInterceptor, org.springframework.context.annotation.ConfigurationClassEnhancer.BeanMethodInterceptor

Conditional Callback.
See Also
ConditionalCallbackFilter

Method Summary

Modifier and TypeMethod and Description
public boolean
isMatch(Method candidateMethod)

Method Detail

isMatchback to summary
public boolean isMatch(Method candidateMethod)
org.springframework.context.annotation back to summary

private Class ConfigurationClassEnhancer.ConditionalCallbackFilter

extends Object
implements CallbackFilter
Class Inheritance
  • java.lang.Object
  • org.springframework.context.annotation.ConfigurationClassEnhancer.ConditionalCallbackFilter
All Implemented Interfaces
org.springframework.cglib.proxy.CallbackFilter

A CallbackFilter that works by interrogating Callbacks in the order that they are defined via ConditionalCallback.

Field Summary

Modifier and TypeField and Description
private final Callback[]
private final Class<?>[]

Constructor Summary

AccessConstructor and Description
public

Method Summary

Modifier and TypeMethod and Description
public int
accept(Method
the intercepted method
method
)

Implements org.springframework.cglib.proxy.CallbackFilter.accept.

Map a method to a callback.

public Class<?>[]
Inherited from java.lang.Object:
cloneequalsfinalizegetClasshashCodenotifynotifyAlltoStringwaitwaitwait

Field Detail

callbacksback to summary
private final Callback[] callbacks
callbackTypesback to summary
private final Class<?>[] callbackTypes

Constructor Detail

ConditionalCallbackFilterback to summary
public ConditionalCallbackFilter(Callback[] callbacks)

Method Detail

acceptback to summary
public int accept(Method method)

Implements org.springframework.cglib.proxy.CallbackFilter.accept.

Doc from org.springframework.cglib.proxy.CallbackFilter.accept.

Map a method to a callback.

Parameters
method:Method

the intercepted method

Returns:int

the index into the array of callbacks (as specified by Enhancer#setCallbacks) to use for the method,

Annotations
@Override
getCallbackTypesback to summary
public Class<?>[] getCallbackTypes()
org.springframework.context.annotation back to summary

public Interface ConfigurationClassEnhancer.EnhancedConfiguration

extends BeanFactoryAware

Marker interface to be implemented by all @Configuration CGLIB subclasses. Facilitates idempotent behavior for ConfigurationClassEnhancer#enhance through checking to see if candidate classes are already assignable to it, e.g. have already been enhanced.

Also extends BeanFactoryAware, as all enhanced @Configuration classes require access to the BeanFactory that created them.

Note that this interface is intended for framework-internal use only, however must remain public in order to allow access to subclasses generated from other packages (i.e. user code).

Method Summary

Inherited from org.springframework.beans.factory.BeanFactoryAware:
setBeanFactory