public class ProxyFactoryBean extends ProxyCreatorSupport implements FactoryBean<Object>, BeanClassLoaderAware, BeanFactoryAware
FactoryBean
implementation that builds an
AOP proxy based on beans in a Spring BeanFactory
.
MethodInterceptors
and
Advisors
are identified by a list of bean
names in the current bean factory, specified through the "interceptorNames" property.
The last entry in the list can be the name of a target bean or a
TargetSource
; however, it is normally preferable
to use the "targetName"/"target"/"targetSource" properties instead.
Global interceptors and advisors can be added at the factory level. The specified
ones are expanded in an interceptor list where an "xxx*" entry is included in the
list, matching the given prefix with the bean names — for example, "global*"
would match both "globalBean1" and "globalBean2"; whereas, "*" would match all
defined interceptors. The matching interceptors get applied according to their
returned order value, if they implement the Ordered
interface.
Creates a JDK proxy when proxy interfaces are given, and a CGLIB proxy for the actual target class if not. Note that the latter will only work if the target class does not have final methods, as a dynamic subclass will be created at runtime.
It's possible to cast a proxy obtained from this factory to Advised
,
or to obtain the ProxyFactoryBean reference and programmatically manipulate it.
This won't work for existing prototype references, which are independent. However,
it will work for prototypes subsequently obtained from the factory. Changes to
interception will work immediately on singletons (including existing references).
However, to change interfaces or a target it's necessary to obtain a new instance
from the factory. This means that singleton instances obtained from the factory
do not have the same object identity. However, they do have the same interceptors
and target, and changing any reference will change all objects.
setInterceptorNames(java.lang.String...)
,
setProxyInterfaces(java.lang.Class<?>[])
,
MethodInterceptor
,
Advisor
,
Advised
,
Serialized FormModifier and Type | Field and Description |
---|---|
static String |
GLOBAL_SUFFIX
This suffix in a value in an interceptor list indicates to expand globals.
|
protected Log |
logger |
EMPTY_TARGET_SOURCE
OBJECT_TYPE_ATTRIBUTE
Constructor and Description |
---|
ProxyFactoryBean() |
Modifier and Type | Method and Description |
---|---|
protected void |
adviceChanged()
Blow away and recache singleton on an advice change.
|
protected Class<?> |
createCompositeInterface(Class<?>[] interfaces)
Create a composite interface Class for the given interfaces,
implementing the given interfaces in one single Class.
|
Object |
getObject()
Return a proxy.
|
Class<?> |
getObjectType()
Return the type of the proxy.
|
protected Object |
getProxy(AopProxy aopProxy)
Return the proxy object to expose.
|
boolean |
isSingleton()
Is the object managed by this factory a singleton? That is,
will
FactoryBean.getObject() always return the same object
(a reference that can be cached)? |
void |
setAdvisorAdapterRegistry(AdvisorAdapterRegistry advisorAdapterRegistry)
Specify the AdvisorAdapterRegistry to use.
|
void |
setAutodetectInterfaces(boolean autodetectInterfaces)
Set whether to autodetect proxy interfaces if none specified.
|
void |
setBeanClassLoader(ClassLoader classLoader)
Callback that supplies the bean
class loader to
a bean instance. |
void |
setBeanFactory(BeanFactory beanFactory)
Callback that supplies the owning factory to a bean instance.
|
void |
setFrozen(boolean frozen)
Set whether this config should be frozen.
|
void |
setInterceptorNames(String... interceptorNames)
Set the list of Advice/Advisor bean names.
|
void |
setProxyClassLoader(ClassLoader classLoader)
Set the ClassLoader to generate the proxy class in.
|
void |
setProxyInterfaces(Class<?>[] proxyInterfaces)
Set the names of the interfaces we're proxying.
|
void |
setSingleton(boolean singleton)
Set the value of the singleton property.
|
void |
setTargetName(String targetName)
Set the name of the target bean.
|
addListener, createAopProxy, getAopProxyFactory, isActive, removeListener, setAopProxyFactory
addAdvice, addAdvice, addAdvisor, addAdvisor, addAdvisors, addAdvisors, addInterface, adviceIncluded, copyConfigurationFrom, copyConfigurationFrom, countAdvicesOfType, getAdvisorChainFactory, getAdvisorCount, getAdvisors, getAdvisorsInternal, getInterceptorsAndDynamicInterceptionAdvice, getProxiedInterfaces, getTargetClass, getTargetSource, indexOf, indexOf, isInterfaceProxied, isPreFiltered, removeAdvice, removeAdvisor, removeAdvisor, removeInterface, replaceAdvisor, setAdvisorChainFactory, setInterfaces, setPreFiltered, setTarget, setTargetClass, setTargetSource, toProxyConfigString, toString
copyFrom, isExposeProxy, isFrozen, isOpaque, isOptimize, isProxyTargetClass, setExposeProxy, setOpaque, setOptimize, setProxyTargetClass
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
isExposeProxy, isFrozen, isProxyTargetClass, setExposeProxy
public static final String GLOBAL_SUFFIX
protected final Log logger
public void setProxyInterfaces(Class<?>[] proxyInterfaces) throws ClassNotFoundException
This is essentially equivalent to the "setInterfaces" method, but mirrors TransactionProxyFactoryBean's "setProxyInterfaces".
public void setInterceptorNames(String... interceptorNames)
The referenced beans should be of type Interceptor, Advisor or Advice The last entry in the list can be the name of any bean in the factory. If it's neither an Advice nor an Advisor, a new SingletonTargetSource is added to wrap it. Such a target bean cannot be used if the "target" or "targetSource" or "targetName" property is set, in which case the "interceptorNames" array must contain only Advice/Advisor bean names.
NOTE: Specifying a target bean as final name in the "interceptorNames"
list is deprecated and will be removed in a future Spring version.
Use the "targetName"
property instead.
MethodInterceptor
,
Advisor
,
Advice
,
SingletonTargetSource
public void setTargetName(String targetName)
You can also specify a target object or a TargetSource object directly, via the "target"/"targetSource" property, respectively.
public void setAutodetectInterfaces(boolean autodetectInterfaces)
Default is "true". Turn this flag off to create a CGLIB proxy for the full target class if no interfaces specified.
ProxyConfig.setProxyTargetClass(boolean)
public void setSingleton(boolean singleton)
public void setAdvisorAdapterRegistry(AdvisorAdapterRegistry advisorAdapterRegistry)
GlobalAdvisorAdapterRegistry
public void setFrozen(boolean frozen)
ProxyConfig
When a config is frozen, no advice changes can be made. This is useful for optimization, and useful when we don't want callers to be able to manipulate configuration after casting to Advised.
setFrozen
in class ProxyConfig
public void setProxyClassLoader(@Nullable ClassLoader classLoader)
Default is the bean ClassLoader, i.e. the ClassLoader used by the containing BeanFactory for loading all bean classes. This can be overridden here for specific proxies.
public void setBeanClassLoader(ClassLoader classLoader)
BeanClassLoaderAware
class loader
to
a bean instance.
Invoked after the population of normal bean properties but
before an initialization callback such as
InitializingBean's
InitializingBean.afterPropertiesSet()
method or a custom init-method.
setBeanClassLoader
in interface BeanClassLoaderAware
classLoader
- the owning class loaderpublic 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 public Object getObject() throws BeansException
getObject()
for a proxy.getObject
in interface FactoryBean<Object>
BeansException
FactoryBeanNotInitializedException
public Class<?> getObjectType()
getObjectType
in interface FactoryBean<Object>
null
if not known at the time of the callTargetSource.getTargetClass()
public boolean isSingleton()
FactoryBean
FactoryBean.getObject()
always return the same object
(a reference that can be cached)?
NOTE: If a FactoryBean indicates to hold a singleton object,
the object returned from getObject()
might get cached
by the owning BeanFactory. Hence, do not return true
unless the FactoryBean always exposes the same reference.
The singleton status of the FactoryBean itself will generally be provided by the owning BeanFactory; usually, it has to be defined as singleton there.
NOTE: This method returning false
does not
necessarily indicate that returned objects are independent instances.
An implementation of the extended SmartFactoryBean
interface
may explicitly indicate independent instances through its
SmartFactoryBean.isPrototype()
method. Plain FactoryBean
implementations which do not implement this extended interface are
simply assumed to always return independent instances if the
isSingleton()
implementation returns false
.
The default implementation returns true
, since a
FactoryBean
typically manages a singleton instance.
isSingleton
in interface FactoryBean<Object>
FactoryBean.getObject()
,
SmartFactoryBean.isPrototype()
protected Class<?> createCompositeInterface(Class<?>[] interfaces)
The default implementation builds a JDK proxy class for the given interfaces.
interfaces
- the interfaces to mergeProxy.getProxyClass(java.lang.ClassLoader, java.lang.Class<?>...)
protected Object getProxy(AopProxy aopProxy)
The default implementation uses a getProxy
call with
the factory's bean class loader. Can be overridden to specify a
custom class loader.
aopProxy
- the prepared AopProxy instance to get the proxy fromAopProxy.getProxy(ClassLoader)
protected void adviceChanged()
adviceChanged
in class ProxyCreatorSupport
AdvisedSupportListener.adviceChanged(org.springframework.aop.framework.AdvisedSupport)