diff --git a/org.springframework.aspects/src/main/java/org/springframework/beans/factory/aspectj/GenericInterfaceDrivenDependencyInjectionAspect.aj b/org.springframework.aspects/src/main/java/org/springframework/beans/factory/aspectj/GenericInterfaceDrivenDependencyInjectionAspect.aj new file mode 100644 index 0000000000..78f927ffad --- /dev/null +++ b/org.springframework.aspects/src/main/java/org/springframework/beans/factory/aspectj/GenericInterfaceDrivenDependencyInjectionAspect.aj @@ -0,0 +1,54 @@ +/* + * Copyright 2002-2008 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.beans.factory.aspectj; + +/** + * Generic-based dependency injection aspect. + *
+ * This aspect allows users to implement efficient, type-safe dependency injection without
+ * the use of the @Configurable annotation.
+ *
+ * The subaspect of this aspect doesn't need to include any AOP constructs.
+ * For example, here is a subaspect that configures the PricingStrategyClient
objects.
+ *
+ * aspect PricingStrategyDependencyInjectionAspect + * extends GenericInterfaceDrivenDependencyInjectionAspect+ * @author Ramnivas Laddad + * @since 3.0.0 + */ +public abstract aspect GenericInterfaceDrivenDependencyInjectionAspect extends AbstractInterfaceDrivenDependencyInjectionAspect { + declare parents: I implements ConfigurableObject; + + public pointcut inConfigurableBean() : within(I+); + + public final void configureBean(Object bean) { + configure((I)bean); + } + + // Unfortunately, erasure used with generics won't allow to use the same named method + protected abstract void configure(I bean); +} diff --git a/org.springframework.aspects/src/test/java/org/springframework/beans/factory/aspectj/BeanConfigurerTests.java b/org.springframework.aspects/src/test/java/org/springframework/beans/factory/aspectj/BeanConfigurerTests.java index 59c2bc88f6..0fb3768d61 100644 --- a/org.springframework.aspects/src/test/java/org/springframework/beans/factory/aspectj/BeanConfigurerTests.java +++ b/org.springframework.aspects/src/test/java/org/springframework/beans/factory/aspectj/BeanConfigurerTests.java @@ -194,6 +194,13 @@ public class BeanConfigurerTests extends TestCase { assertNotNull("Interface driven injection didn't occur for direct construction", testOrder.mailSender); } + public void testGenericInterfaceDrivenDependencyInjection() { + PricingStrategy injectedPricingStrategy = new PricingStrategy(); + PricingStrategyDependencyInjectionAspect.aspectOf().setPricingStrategy(injectedPricingStrategy); + LineItem testLineItem = new LineItem(); + assertSame("Generic interface driven injection didn't occur for direct construction", injectedPricingStrategy, testLineItem.pricingStrategy); + } + public void testInterfaceDrivenDependencyInjectionMultipleInterfaces() { MailClientDependencyInjectionAspect.aspectOf().setMailSender(new JavaMailSenderImpl()); PaymentProcessorDependencyInjectionAspect.aspectOf().setPaymentProcessor(new PaymentProcessor()); @@ -509,6 +516,18 @@ public class BeanConfigurerTests extends TestCase { } } + private static aspect PricingStrategyDependencyInjectionAspect extends GenericInterfaceDrivenDependencyInjectionAspect{ + * private PricingStrategy pricingStrategy; + * + * public void configure(PricingStrategyClient bean) { + * bean.setPricingStrategy(pricingStrategy); + * } + * + * public void setPricingStrategy(PricingStrategy pricingStrategy) { + * this.pricingStrategy = pricingStrategy; + * } + * } + *