public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware
BeanPostProcessor
implementation
that wraps each eligible bean with an AOP proxy, delegating to specified interceptors
before invoking the bean itself.
This class distinguishes between "common" interceptors: shared for all proxies it
creates, and "specific" interceptors: unique per bean instance. There need not be any
common interceptors. If there are, they are set using the interceptorNames property.
As with ProxyFactoryBean
, interceptors names
in the current factory are used rather than bean references to allow correct handling
of prototype advisors and interceptors: for example, to support stateful mixins.
Any advice type is supported for "interceptorNames"
entries.
Such auto-proxying is particularly useful if there's a large number of beans that need to be wrapped with similar proxies, i.e. delegating to the same interceptors. Instead of x repetitive proxy definitions for x target beans, you can register one single such post processor with the bean factory to achieve the same effect.
Subclasses can apply any strategy to decide if a bean is to be proxied, e.g. by type,
by name, by definition details, etc. They can also return additional interceptors that
should just be applied to the specific bean instance. A simple concrete implementation is
BeanNameAutoProxyCreator
, identifying the beans to be proxied via given names.
Any number of TargetSourceCreator
implementations can be used to create
a custom target source: for example, to pool prototype objects. Auto-proxying will
occur even if there is no advice, as long as a TargetSourceCreator specifies a custom
TargetSource
. If there are no TargetSourceCreators set,
or if none matches, a SingletonTargetSource
will be used by default to wrap the target bean instance.
setInterceptorNames(java.lang.String...)
,
getAdvicesAndAdvisorsForBean(java.lang.Class<?>, java.lang.String, org.springframework.aop.TargetSource)
,
BeanNameAutoProxyCreator
,
DefaultAdvisorAutoProxyCreator
,
Serialized FormModifier and Type | Field and Description |
---|---|
protected static Object[] |
DO_NOT_PROXY
Convenience constant for subclasses: Return value for "do not proxy".
|
protected Log |
logger
Logger available to subclasses.
|
protected static Object[] |
PROXY_WITHOUT_ADDITIONAL_INTERCEPTORS
Convenience constant for subclasses: Return value for
"proxy without additional interceptors, just the common ones".
|
HIGHEST_PRECEDENCE, LOWEST_PRECEDENCE
Constructor and Description |
---|
AbstractAutoProxyCreator() |
Modifier and Type | Method and Description |
---|---|
protected boolean |
advisorsPreFiltered()
Return whether the Advisors returned by the subclass are pre-filtered
to match the bean's target class already, allowing the ClassFilter check
to be skipped when building advisors chains for AOP invocations.
|
protected Advisor[] |
buildAdvisors(String beanName,
Object[] specificInterceptors)
Determine the advisors for the given bean, including the specific interceptors
as well as the common interceptor, all adapted to the Advisor interface.
|
protected Object |
createProxy(Class<?> beanClass,
String beanName,
Object[] specificInterceptors,
TargetSource targetSource)
Create an AOP proxy for the given bean.
|
protected void |
customizeProxyFactory(ProxyFactory proxyFactory)
Subclasses may choose to implement this: for example,
to change the interfaces exposed.
|
Constructor<?>[] |
determineCandidateConstructors(Class<?> beanClass,
String beanName)
Determine the candidate constructors to use for the given bean.
|
protected abstract Object[] |
getAdvicesAndAdvisorsForBean(Class<?> beanClass,
String beanName,
TargetSource customTargetSource)
Return whether the given bean is to be proxied, what additional
advices (e.g.
|
protected BeanFactory |
getBeanFactory()
Return the owning
BeanFactory . |
protected Object |
getCacheKey(Class<?> beanClass,
String beanName)
Build a cache key for the given bean class and bean name.
|
protected TargetSource |
getCustomTargetSource(Class<?> beanClass,
String beanName)
Create a target source for bean instances.
|
Object |
getEarlyBeanReference(Object bean,
String beanName)
Obtain a reference for early access to the specified bean,
typically for the purpose of resolving a circular reference.
|
boolean |
isFrozen()
Return whether the config is frozen, and no advice changes can be made.
|
protected boolean |
isInfrastructureClass(Class<?> beanClass)
Return whether the given bean class represents an infrastructure class
that should never be proxied.
|
Object |
postProcessAfterInitialization(Object bean,
String beanName)
Create a proxy with the configured interceptors if the bean is
identified as one to proxy by the subclass.
|
boolean |
postProcessAfterInstantiation(Object bean,
String beanName)
Perform operations after the bean has been instantiated, via a constructor or factory method,
but before Spring property population (from explicit properties or autowiring) occurs.
|
Object |
postProcessBeforeInitialization(Object bean,
String beanName)
Apply this
BeanPostProcessor to the given new bean instance before any bean
initialization callbacks (like InitializingBean's afterPropertiesSet
or a custom init-method). |
Object |
postProcessBeforeInstantiation(Class<?> beanClass,
String beanName)
Apply this BeanPostProcessor before the target bean gets instantiated.
|
PropertyValues |
postProcessProperties(PropertyValues pvs,
Object bean,
String beanName)
Post-process the given property values before the factory applies them
to the given bean, without any need for property descriptors.
|
Class<?> |
predictBeanType(Class<?> beanClass,
String beanName)
Predict the type of the bean to be eventually returned from this
processor's
InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation(java.lang.Class<?>, java.lang.String) callback. |
void |
setAdvisorAdapterRegistry(AdvisorAdapterRegistry advisorAdapterRegistry)
Specify the
AdvisorAdapterRegistry to use. |
void |
setApplyCommonInterceptorsFirst(boolean applyCommonInterceptorsFirst)
Set whether the common interceptors should be applied before bean-specific ones.
|
void |
setBeanFactory(BeanFactory beanFactory)
Callback that supplies the owning factory to a bean instance.
|
void |
setCustomTargetSourceCreators(TargetSourceCreator... targetSourceCreators)
Set custom
TargetSourceCreators to be applied in this order. |
void |
setFrozen(boolean frozen)
Set whether or not the proxy should be frozen, preventing advice
from being added to it once it is created.
|
void |
setInterceptorNames(String... interceptorNames)
Set the common interceptors.
|
protected boolean |
shouldProxyTargetClass(Class<?> beanClass,
String beanName)
Determine whether the given bean should be proxied with its target class rather than its interfaces.
|
protected boolean |
shouldSkip(Class<?> beanClass,
String beanName)
Subclasses should override this method to return
true if the
given bean should not be considered for auto-proxying by this post-processor. |
protected Object |
wrapIfNecessary(Object bean,
String beanName,
Object cacheKey)
Wrap the given bean if necessary, i.e.
|
evaluateProxyInterfaces, getOrder, getProxyClassLoader, isConfigurationCallbackInterface, isInternalLanguageInterface, setBeanClassLoader, setOrder, setProxyClassLoader
copyFrom, isExposeProxy, isOpaque, isOptimize, isProxyTargetClass, setExposeProxy, setOpaque, setOptimize, setProxyTargetClass, toString
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
postProcessPropertyValues
@Nullable protected static final Object[] DO_NOT_PROXY
protected static final Object[] PROXY_WITHOUT_ADDITIONAL_INTERCEPTORS
protected final Log logger
public void setFrozen(boolean frozen)
Overridden from the super class to prevent the proxy configuration from being frozen before the proxy is created.
setFrozen
in class ProxyConfig
public boolean isFrozen()
ProxyConfig
isFrozen
in class ProxyConfig
public void setAdvisorAdapterRegistry(AdvisorAdapterRegistry advisorAdapterRegistry)
AdvisorAdapterRegistry
to use.
Default is the global AdvisorAdapterRegistry
.
GlobalAdvisorAdapterRegistry
public void setCustomTargetSourceCreators(TargetSourceCreator... targetSourceCreators)
TargetSourceCreators
to be applied in this order.
If the list is empty, or they all return null, a SingletonTargetSource
will be created for each bean.
Note that TargetSourceCreators will kick in even for target beans
where no advices or advisors have been found. If a TargetSourceCreator
returns a TargetSource
for a specific bean, that bean will be proxied
in any case.
TargetSourceCreators
can only be invoked if this post processor is used
in a BeanFactory
and its BeanFactoryAware
callback is triggered.
targetSourceCreators
- the list of TargetSourceCreators
.
Ordering is significant: The TargetSource
returned from the first matching
TargetSourceCreator
(that is, the first that returns non-null) will be used.public void setInterceptorNames(String... interceptorNames)
If this property isn't set, there will be zero common interceptors. This is perfectly valid, if "specific" interceptors such as matching Advisors are all we want.
public void setApplyCommonInterceptorsFirst(boolean applyCommonInterceptorsFirst)
public void setBeanFactory(BeanFactory beanFactory)
BeanFactoryAware
Invoked after the population of normal bean properties
but before an initialization callback such as
InitializingBean.afterPropertiesSet()
or a custom init-method.
setBeanFactory
in interface BeanFactoryAware
beanFactory
- owning BeanFactory (never null
).
The bean can immediately call methods on the factory.BeanInitializationException
@Nullable protected BeanFactory getBeanFactory()
BeanFactory
.
May be null
, as this post-processor doesn't need to belong to a bean factory.@Nullable public Class<?> predictBeanType(Class<?> beanClass, String beanName)
SmartInstantiationAwareBeanPostProcessor
InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation(java.lang.Class<?>, java.lang.String)
callback.
The default implementation returns null
.
predictBeanType
in interface SmartInstantiationAwareBeanPostProcessor
beanClass
- the raw class of the beanbeanName
- the name of the beannull
if not predictable@Nullable public Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, String beanName)
SmartInstantiationAwareBeanPostProcessor
The default implementation returns null
.
determineCandidateConstructors
in interface SmartInstantiationAwareBeanPostProcessor
beanClass
- the raw class of the bean (never null
)beanName
- the name of the beannull
if none specifiedpublic Object getEarlyBeanReference(Object bean, String beanName)
SmartInstantiationAwareBeanPostProcessor
This callback gives post-processors a chance to expose a wrapper
early - that is, before the target bean instance is fully initialized.
The exposed object should be equivalent to the what
BeanPostProcessor.postProcessBeforeInitialization(java.lang.Object, java.lang.String)
/ BeanPostProcessor.postProcessAfterInitialization(java.lang.Object, java.lang.String)
would expose otherwise. Note that the object returned by this method will
be used as bean reference unless the post-processor returns a different
wrapper from said post-process callbacks. In other words: Those post-process
callbacks may either eventually expose the same reference or alternatively
return the raw bean instance from those subsequent callbacks (if the wrapper
for the affected bean has been built for a call to this method already,
it will be exposes as final bean reference by default).
The default implementation returns the given bean
as-is.
getEarlyBeanReference
in interface SmartInstantiationAwareBeanPostProcessor
bean
- the raw bean instancebeanName
- the name of the beanpublic Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName)
InstantiationAwareBeanPostProcessor
If a non-null object is returned by this method, the bean creation process
will be short-circuited. The only further processing applied is the
BeanPostProcessor.postProcessAfterInitialization(java.lang.Object, java.lang.String)
callback from the configured
BeanPostProcessors
.
This callback will be applied to bean definitions with their bean class, as well as to factory-method definitions in which case the returned bean type will be passed in here.
Post-processors may implement the extended
SmartInstantiationAwareBeanPostProcessor
interface in order
to predict the type of the bean object that they are going to return here.
The default implementation returns null
.
postProcessBeforeInstantiation
in interface InstantiationAwareBeanPostProcessor
beanClass
- the class of the bean to be instantiatedbeanName
- the name of the beannull
to proceed with default instantiationInstantiationAwareBeanPostProcessor.postProcessAfterInstantiation(java.lang.Object, java.lang.String)
,
AbstractBeanDefinition.getBeanClass()
,
AbstractBeanDefinition.getFactoryMethodName()
public boolean postProcessAfterInstantiation(Object bean, String beanName)
InstantiationAwareBeanPostProcessor
This is the ideal callback for performing custom field injection on the given bean instance, right before Spring's autowiring kicks in.
The default implementation returns true
.
postProcessAfterInstantiation
in interface InstantiationAwareBeanPostProcessor
bean
- the bean instance created, with properties not having been set yetbeanName
- the name of the beantrue
if properties should be set on the bean; false
if property population should be skipped. Normal implementations should return true
.
Returning false
will also prevent any subsequent InstantiationAwareBeanPostProcessor
instances being invoked on this bean instance.InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation(java.lang.Class<?>, java.lang.String)
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName)
InstantiationAwareBeanPostProcessor
Implementations should return null
(the default) if they provide a custom
InstantiationAwareBeanPostProcessor.postProcessPropertyValues(org.springframework.beans.PropertyValues, java.beans.PropertyDescriptor[], java.lang.Object, java.lang.String)
implementation, and pvs
otherwise.
In a future version of this interface (with InstantiationAwareBeanPostProcessor.postProcessPropertyValues(org.springframework.beans.PropertyValues, java.beans.PropertyDescriptor[], java.lang.Object, java.lang.String)
removed),
the default implementation will return the given pvs
as-is directly.
postProcessProperties
in interface InstantiationAwareBeanPostProcessor
pvs
- the property values that the factory is about to apply (never null
)bean
- the bean instance created, but whose properties have not yet been setbeanName
- the name of the beannull
which proceeds with the existing properties
but specifically continues with a call to InstantiationAwareBeanPostProcessor.postProcessPropertyValues(org.springframework.beans.PropertyValues, java.beans.PropertyDescriptor[], java.lang.Object, java.lang.String)
(requiring initialized PropertyDescriptor
s for the current bean class)InstantiationAwareBeanPostProcessor.postProcessPropertyValues(org.springframework.beans.PropertyValues, java.beans.PropertyDescriptor[], java.lang.Object, java.lang.String)
public Object postProcessBeforeInitialization(Object bean, String beanName)
BeanPostProcessor
BeanPostProcessor
to the given new bean instance before any bean
initialization callbacks (like InitializingBean's afterPropertiesSet
or a custom init-method). The bean will already be populated with property values.
The returned bean instance may be a wrapper around the original.
The default implementation returns the given bean
as-is.
postProcessBeforeInitialization
in interface BeanPostProcessor
bean
- the new bean instancebeanName
- the name of the beannull
, no subsequent BeanPostProcessors will be invokedInitializingBean.afterPropertiesSet()
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName)
postProcessAfterInitialization
in interface BeanPostProcessor
bean
- the new bean instancebeanName
- the name of the beannull
, no subsequent BeanPostProcessors will be invokedgetAdvicesAndAdvisorsForBean(java.lang.Class<?>, java.lang.String, org.springframework.aop.TargetSource)
protected Object getCacheKey(Class<?> beanClass, @Nullable String beanName)
Note: As of 4.2.3, this implementation does not return a concatenated
class/name String anymore but rather the most efficient cache key possible:
a plain bean name, prepended with BeanFactory.FACTORY_BEAN_PREFIX
in case of a FactoryBean
; or if no bean name specified, then the
given bean Class
as-is.
beanClass
- the bean classbeanName
- the bean nameprotected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey)
bean
- the raw bean instancebeanName
- the name of the beancacheKey
- the cache key for metadata accessprotected boolean isInfrastructureClass(Class<?> beanClass)
The default implementation considers Advices, Advisors and AopInfrastructureBeans as infrastructure classes.
beanClass
- the class of the beanAdvice
,
Advisor
,
AopInfrastructureBean
,
shouldSkip(java.lang.Class<?>, java.lang.String)
protected boolean shouldSkip(Class<?> beanClass, String beanName)
true
if the
given bean should not be considered for auto-proxying by this post-processor.
Sometimes we need to be able to avoid this happening, e.g. if it will lead to
a circular reference or if the existing target instance needs to be preserved.
This implementation returns false
unless the bean name indicates an
"original instance" according to AutowireCapableBeanFactory
conventions.
beanClass
- the class of the beanbeanName
- the name of the beanAutowireCapableBeanFactory.ORIGINAL_INSTANCE_SUFFIX
@Nullable protected TargetSource getCustomTargetSource(Class<?> beanClass, String beanName)
null
if no custom TargetSource should be used.
This implementation uses the "customTargetSourceCreators" property. Subclasses can override this method to use a different mechanism.
beanClass
- the class of the bean to create a TargetSource forbeanName
- the name of the beansetCustomTargetSourceCreators(org.springframework.aop.framework.autoproxy.TargetSourceCreator...)
protected Object createProxy(Class<?> beanClass, @Nullable String beanName, @Nullable Object[] specificInterceptors, TargetSource targetSource)
beanClass
- the class of the beanbeanName
- the name of the beanspecificInterceptors
- the set of interceptors that is
specific to this bean (may be empty, but not null)targetSource
- the TargetSource for the proxy,
already pre-configured to access the beanbuildAdvisors(java.lang.String, java.lang.Object[])
protected boolean shouldProxyTargetClass(Class<?> beanClass, @Nullable String beanName)
Checks the "preserveTargetClass" attribute
of the corresponding bean definition.
beanClass
- the class of the beanbeanName
- the name of the beanAutoProxyUtils.shouldProxyTargetClass(org.springframework.beans.factory.config.ConfigurableListableBeanFactory, java.lang.String)
protected boolean advisorsPreFiltered()
Default is false
. Subclasses may override this if they
will always return pre-filtered Advisors.
getAdvicesAndAdvisorsForBean(java.lang.Class<?>, java.lang.String, org.springframework.aop.TargetSource)
,
Advised.setPreFiltered(boolean)
protected Advisor[] buildAdvisors(@Nullable String beanName, @Nullable Object[] specificInterceptors)
beanName
- the name of the beanspecificInterceptors
- the set of interceptors that is
specific to this bean (may be empty, but not null)protected void customizeProxyFactory(ProxyFactory proxyFactory)
The default implementation is empty.
proxyFactory
- a ProxyFactory that is already configured with
TargetSource and interfaces and will be used to create the proxy
immediately after this method returns@Nullable protected abstract Object[] getAdvicesAndAdvisorsForBean(Class<?> beanClass, String beanName, @Nullable TargetSource customTargetSource) throws BeansException
beanClass
- the class of the bean to advisebeanName
- the name of the beancustomTargetSource
- the TargetSource returned by the
getCustomTargetSource(java.lang.Class<?>, java.lang.String)
method: may be ignored.
Will be null
if no custom target source is in use.null
if no proxy at all, not even with the common interceptors.
See constants DO_NOT_PROXY and PROXY_WITHOUT_ADDITIONAL_INTERCEPTORS.BeansException
- in case of errorsDO_NOT_PROXY
,
PROXY_WITHOUT_ADDITIONAL_INTERCEPTORS