Skip to content

DefaultAdvisorAutoProxyCreator doesn't get the target class of existing proxy [SPR-13990] #18563

Closed
@spring-projects-issues

Description

@spring-projects-issues

Yoni Amir opened SPR-13990 and commented

I have a spring context setup like this:

<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" />

<bean id="defaultAdvisorAutoProxyCreator" class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" />

I have a custom advisor, not shown in the XML snippet above, that searches for some annotations at the class level of the beans that Spring creates.
The problem is that the PersistenceExceptionTranslationPostProcessor runs first and creates a proxy around the bean. When the DefaultAdvisorAutoProxyCreator runs, it calls getClass() on the proxied bean and passes that class (something like com.sun.proxy.$Proxy) to the advisor to test for a match. The advisor is then unable to detect the annotations.
The flawed call to getClass() is in AbstractAutoProxyCreater.wrapIfNecessary() method, just before calling getAdvicesAndAdvisorsForBean().

There is a workaround, though. Adding an order attribute and ensuring that the DefaultAdvisorAutoProxyCreator runs first works. This is because the PersistenceExceptionTranslationPostProcessor can handle beans that are already proxied - it extract the target class of the proxy. This happens in AbstractAdvisingBeanPostProcessor.postProcessAfterInitialization() method. The relevant code looks more or less like this:

if (bean instanceof Advised) {
Advised advised = (Advised) bean;
if (!advised.isFrozen() && isEligible(AopUtils.getTargetClass(bean))) {

This workaround has a limitation, though. It forces a certain order in which the interceptors run, which may not be the order that I want.

Bottom line is, I think AbstractAutoProxyCreater.wrapIfNecessary() (which is called from AbstractAutoProxyCreater.postProcessAfterInitialization() needs to use the code snippet above and act similarly to AbstractAdvisingBeanPostProcessor.postProcessAfterInitialization()


Issue Links:

Metadata

Metadata

Assignees

Labels

in: coreIssues in core modules (aop, beans, core, context, expression)status: declinedA suggestion or change that we don't feel we should currently applytype: enhancementA general enhancement

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions