| Method from org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator Detail: |
protected boolean advisorsPreFiltered() {
return false;
}
|
protected Advisor[] buildAdvisors(String beanName,
Object[] specificInterceptors) {
// Handle prototypes correctly...
Advisor[] commonInterceptors = resolveInterceptorNames();
List allInterceptors = new ArrayList();
if (specificInterceptors != null) {
allInterceptors.addAll(Arrays.asList(specificInterceptors));
if (commonInterceptors != null) {
if (this.applyCommonInterceptorsFirst) {
allInterceptors.addAll(0, Arrays.asList(commonInterceptors));
}
else {
allInterceptors.addAll(Arrays.asList(commonInterceptors));
}
}
}
if (logger.isDebugEnabled()) {
int nrOfCommonInterceptors = (commonInterceptors != null ? commonInterceptors.length : 0);
int nrOfSpecificInterceptors = (specificInterceptors != null ? specificInterceptors.length : 0);
logger.debug("Creating implicit proxy for bean '" + beanName + "' with " + nrOfCommonInterceptors +
" common interceptors and " + nrOfSpecificInterceptors + " specific interceptors");
}
Advisor[] advisors = new Advisor[allInterceptors.size()];
for (int i = 0; i < allInterceptors.size(); i++) {
advisors[i] = this.advisorAdapterRegistry.wrap(allInterceptors.get(i));
}
return advisors;
}
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) {
ProxyFactory proxyFactory = new ProxyFactory();
// Copy our properties (proxyTargetClass etc) inherited from ProxyConfig.
proxyFactory.copyFrom(this);
if (!shouldProxyTargetClass(beanClass, beanName)) {
// Must allow for introductions; can't just set interfaces to
// the target's interfaces only.
Class[] targetInterfaces = ClassUtils.getAllInterfacesForClass(beanClass, this.proxyClassLoader);
for (int i = 0; i < targetInterfaces.length; i++) {
proxyFactory.addInterface(targetInterfaces[i]);
}
}
Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
for (int i = 0; i < advisors.length; i++) {
proxyFactory.addAdvisor(advisors[i]);
}
proxyFactory.setTargetSource(targetSource);
customizeProxyFactory(proxyFactory);
proxyFactory.setFrozen(this.freezeProxy);
if (advisorsPreFiltered()) {
proxyFactory.setPreFiltered(true);
}
return proxyFactory.getProxy(this.proxyClassLoader);
}
Create an AOP proxy for the given bean. |
protected void customizeProxyFactory(ProxyFactory proxyFactory) {
}
|
public Constructor[] determineCandidateConstructors(Class beanClass,
String beanName) throws BeansException {
return null;
}
|
abstract protected Object[] getAdvicesAndAdvisorsForBean(Class beanClass,
String beanName,
TargetSource customTargetSource) throws BeansException
Return whether the given bean is to be proxied, what additional
advices (e.g. AOP Alliance interceptors) and advisors to apply. |
protected BeanFactory getBeanFactory() {
return this.beanFactory;
}
Return the owning BeanFactory.
May be null, as this object doesn't need to belong to a bean factory. |
protected Object getCacheKey(Class beanClass,
String beanName) {
return beanClass.getName() + "_" + beanName;
}
Build a cache key for the given bean class and bean name. |
protected TargetSource getCustomTargetSource(Class beanClass,
String beanName) {
// We can't create fancy target sources for directly registered singletons.
if (this.customTargetSourceCreators != null &&
this.beanFactory != null && this.beanFactory.containsBean(beanName)) {
for (int i = 0; i < this.customTargetSourceCreators.length; i++) {
TargetSourceCreator tsc = this.customTargetSourceCreators[i];
TargetSource ts = tsc.getTargetSource(beanClass, beanName);
if (ts != null) {
// Found a matching TargetSource.
if (logger.isDebugEnabled()) {
logger.debug("TargetSourceCreator [" + tsc +
" found custom TargetSource for bean with name '" + beanName + "'");
}
return ts;
}
}
}
// No custom TargetSource found.
return null;
}
Create a target source for bean instances. Uses any TargetSourceCreators if set.
Returns null if no custom TargetSource should be used.
This implementation uses the "customTargetSourceCreators" property.
Subclasses can override this method to use a different mechanism. |
public Object getEarlyBeanReference(Object bean,
String beanName) throws BeansException {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
this.earlyProxyReferences.add(cacheKey);
return wrapIfNecessary(bean, beanName, cacheKey);
}
|
public final int getOrder() {
return this.order;
}
|
public boolean isFrozen() {
return this.freezeProxy;
}
|
protected boolean isInfrastructureClass(Class beanClass) {
boolean retVal = Advisor.class.isAssignableFrom(beanClass) ||
Advice.class.isAssignableFrom(beanClass) ||
AopInfrastructureBean.class.isAssignableFrom(beanClass);
if (retVal && logger.isTraceEnabled()) {
logger.trace("Did not attempt to auto-proxy infrastructure class [" + beanClass.getName() + "]");
}
return retVal;
}
Return whether the given bean class represents an infrastructure class
that should never be proxied.
Default implementation considers Advisors, Advices and
AbstractAutoProxyCreators as infrastructure classes. |
protected boolean isInfrastructureClass(Class beanClass,
String beanName) {
return isInfrastructureClass(beanClass);
} Deprecated! in - favor of isInfrastructureClass(beanClass)
Return whether the given bean class and bean name represents an
infrastructure class that should never be proxied. |
public Object postProcessAfterInitialization(Object bean,
String beanName) throws BeansException {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (!this.earlyProxyReferences.contains(cacheKey)) {
return wrapIfNecessary(bean, beanName, cacheKey);
}
return bean;
}
Create a proxy with the configured interceptors if the bean is
identified as one to proxy by the subclass. |
public boolean postProcessAfterInstantiation(Object bean,
String beanName) {
return true;
}
|
public Object postProcessBeforeInitialization(Object bean,
String beanName) {
return bean;
}
|
public Object postProcessBeforeInstantiation(Class beanClass,
String beanName) throws BeansException {
Object cacheKey = getCacheKey(beanClass, beanName);
if (!this.targetSourcedBeans.contains(cacheKey)) {
if (this.advisedBeans.contains(cacheKey) || this.nonAdvisedBeans.contains(cacheKey)) {
return null;
}
if (isInfrastructureClass(beanClass, beanName) || shouldSkip(beanClass, beanName)) {
this.nonAdvisedBeans.add(cacheKey);
return null;
}
}
// Create proxy here if we have a custom TargetSource.
// Suppresses unnecessary default instantiation of the target bean:
// The TargetSource will handle target instances in a custom fashion.
TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
if (targetSource != null) {
this.targetSourcedBeans.add(beanName);
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}
return null;
}
|
public PropertyValues postProcessPropertyValues(PropertyValues pvs,
PropertyDescriptor[] pds,
Object bean,
String beanName) {
return pvs;
}
|
public Class predictBeanType(Class beanClass,
String beanName) {
Object cacheKey = getCacheKey(beanClass, beanName);
return (Class) this.proxyTypes.get(cacheKey);
}
|
public void setAdvisorAdapterRegistry(AdvisorAdapterRegistry advisorAdapterRegistry) {
this.advisorAdapterRegistry = advisorAdapterRegistry;
}
Specify the AdvisorAdapterRegistry to use.
Default is the global AdvisorAdapterRegistry. |
public void setApplyCommonInterceptorsFirst(boolean applyCommonInterceptorsFirst) {
this.applyCommonInterceptorsFirst = applyCommonInterceptorsFirst;
}
Set whether the common interceptors should be applied before bean-specific ones.
Default is "true"; else, bean-specific interceptors will get applied first. |
public void setBeanClassLoader(ClassLoader classLoader) {
if (!this.classLoaderConfigured) {
this.proxyClassLoader = classLoader;
}
}
|
public void setBeanFactory(BeanFactory beanFactory) {
this.beanFactory = beanFactory;
}
|
public void setCustomTargetSourceCreators(TargetSourceCreator[] targetSourceCreators) {
this.customTargetSourceCreators = targetSourceCreators;
}
Set custom 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 used. |
public void setFrozen(boolean frozen) {
this.freezeProxy = frozen;
}
Set whether or not the proxy should be frozen, preventing advice
from being added to it once it is created.
Overridden from the super class to prevent the proxy configuration
from being frozen before the proxy is created. |
public void setInterceptorNames(String[] interceptorNames) {
this.interceptorNames = interceptorNames;
}
Set the common interceptors. These must be bean names in the current factory.
They can be of any advice or advisor type Spring supports.
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 final void setOrder(int order) {
this.order = order;
}
Set the ordering which will apply to this class's implementation
of Ordered, used when applying multiple BeanPostProcessors.
Default value is Integer.MAX_VALUE, meaning that it's non-ordered. |
public void setProxyClassLoader(ClassLoader classLoader) {
this.proxyClassLoader = classLoader;
this.classLoaderConfigured = (classLoader != null);
}
Set the ClassLoader to generate the proxy class in.
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. |
protected boolean shouldProxyTargetClass(Class beanClass,
String beanName) {
return (isProxyTargetClass() ||
(this.beanFactory instanceof ConfigurableListableBeanFactory &&
AutoProxyUtils.shouldProxyTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName)));
}
|
protected boolean shouldSkip(Class beanClass,
String beanName) {
return false;
}
Subclasses should override this method to return 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 if it will lead to
a circular reference. This implementation returns false. |
protected Object wrapIfNecessary(Object bean,
String beanName,
Object cacheKey) {
if (this.targetSourcedBeans.contains(beanName)) {
return bean;
}
if (this.nonAdvisedBeans.contains(cacheKey)) {
return bean;
}
if (isInfrastructureClass(bean.getClass(), beanName) || shouldSkip(bean.getClass(), beanName)) {
this.nonAdvisedBeans.add(cacheKey);
return bean;
}
// Create proxy if we have advice.
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
if (specificInterceptors != DO_NOT_PROXY) {
this.advisedBeans.add(cacheKey);
Object proxy = createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}
this.nonAdvisedBeans.add(cacheKey);
return bean;
}
Wrap the given bean if necessary, i.e. if it is eligible for being proxied. |