EnableAspectJAutoProxy features exposeProxy flag (analogous to XML namespace)

Issue: SPR-10454
This commit is contained in:
Juergen Hoeller 2016-06-20 13:50:04 +02:00
parent 01f115869b
commit 8cb9d5ebae
4 changed files with 50 additions and 5 deletions

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2012 the original author or authors. * Copyright 2002-2016 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -97,7 +97,7 @@ public abstract class AopConfigUtils {
} }
} }
static void forceAutoProxyCreatorToExposeProxy(BeanDefinitionRegistry registry) { public static void forceAutoProxyCreatorToExposeProxy(BeanDefinitionRegistry registry) {
if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) { if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {
BeanDefinition definition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME); BeanDefinition definition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);
definition.getPropertyValues().add("exposeProxy", Boolean.TRUE); definition.getPropertyValues().add("exposeProxy", Boolean.TRUE);

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2013 the original author or authors. * Copyright 2002-2016 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -27,6 +27,7 @@ import org.springframework.core.type.AnnotationMetadata;
* as appropriate based on a given @{@link EnableAspectJAutoProxy} annotation. * as appropriate based on a given @{@link EnableAspectJAutoProxy} annotation.
* *
* @author Chris Beams * @author Chris Beams
* @author Juergen Hoeller
* @since 3.1 * @since 3.1
* @see EnableAspectJAutoProxy * @see EnableAspectJAutoProxy
*/ */
@ -43,11 +44,14 @@ class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry); AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
AnnotationAttributes enableAJAutoProxy = AnnotationAttributes enableAspectJAutoProxy =
AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class); AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);
if (enableAJAutoProxy.getBoolean("proxyTargetClass")) { if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry); AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
} }
if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
}
} }
} }

View File

@ -102,6 +102,7 @@ import java.lang.annotation.Target;
* }</pre> * }</pre>
* *
* @author Chris Beams * @author Chris Beams
* @author Juergen Hoeller
* @since 3.1 * @since 3.1
* @see org.aspectj.lang.annotation.Aspect * @see org.aspectj.lang.annotation.Aspect
*/ */
@ -117,4 +118,12 @@ public @interface EnableAspectJAutoProxy {
*/ */
boolean proxyTargetClass() default false; boolean proxyTargetClass() default false;
/**
* Indicate that the proxy should be exposed by the AOP framework as a {@code ThreadLocal}
* for retrieval via the {@link org.springframework.aop.framework.AopContext} class.
* Off by default, i.e. no guarantees that {@code AopContext} access will work.
* @since 4.3.1
*/
boolean exposeProxy() default false;
} }

View File

@ -20,11 +20,13 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy;
import example.scannable.FooService; import example.scannable.FooService;
import example.scannable.FooServiceImpl;
import example.scannable.ServiceInvocationCounter; import example.scannable.ServiceInvocationCounter;
import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before; import org.aspectj.lang.annotation.Before;
import org.junit.Test; import org.junit.Test;
import org.springframework.aop.framework.AopContext;
import org.springframework.aop.support.AopUtils; import org.springframework.aop.support.AopUtils;
import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContext;
import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.ConfigurableApplicationContext;
@ -54,6 +56,14 @@ public class EnableAspectJAutoProxyTests {
assertThat(AopUtils.isCglibProxy(ctx.getBean(FooService.class)), is(true)); assertThat(AopUtils.isCglibProxy(ctx.getBean(FooService.class)), is(true));
} }
@Test
public void withExposedProxy() {
ApplicationContext ctx = new AnnotationConfigApplicationContext(ConfigWithExposedProxy.class);
aspectIsApplied(ctx);
assertThat(AopUtils.isJdkDynamicProxy(ctx.getBean(FooService.class)), is(true));
}
private void aspectIsApplied(ApplicationContext ctx) { private void aspectIsApplied(ApplicationContext ctx) {
FooService fooService = ctx.getBean(FooService.class); FooService fooService = ctx.getBean(FooService.class);
ServiceInvocationCounter counter = ctx.getBean(ServiceInvocationCounter.class); ServiceInvocationCounter counter = ctx.getBean(ServiceInvocationCounter.class);
@ -101,23 +111,44 @@ public class EnableAspectJAutoProxyTests {
static class ConfigWithJdkProxy { static class ConfigWithJdkProxy {
} }
@ComponentScan("example.scannable") @ComponentScan("example.scannable")
@EnableAspectJAutoProxy(proxyTargetClass = true) @EnableAspectJAutoProxy(proxyTargetClass = true)
static class ConfigWithCglibProxy { static class ConfigWithCglibProxy {
} }
@ComponentScan("example.scannable")
@EnableAspectJAutoProxy(exposeProxy = true)
static class ConfigWithExposedProxy {
@Bean
public FooService fooServiceImpl() {
return new FooServiceImpl() {
@Override
public String foo(int id) {
assertNotNull(AopContext.currentProxy());
return super.foo(id);
}
};
}
}
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
public @interface Loggable { public @interface Loggable {
} }
@Loggable @Loggable
public static class SampleDto { public static class SampleDto {
} }
public static class SampleInputBean { public static class SampleInputBean {
} }
public static class SampleService { public static class SampleService {
// Not matched method on {@link LoggingAspect}. // Not matched method on {@link LoggingAspect}.
@ -129,6 +160,7 @@ public class EnableAspectJAutoProxyTests {
} }
} }
@Aspect @Aspect
public static class LoggingAspect { public static class LoggingAspect {