From 29139dfd1a7160ec07e68259cebdf4e4ff433302 Mon Sep 17 00:00:00 2001 From: Ramnivas Laddad Date: Sun, 12 Jul 2009 05:58:55 +0000 Subject: [PATCH] Fixed SPR-5920 by implementing GenericInterfaceDrivenDependencyInjectionAspect --- ...nterfaceDrivenDependencyInjectionAspect.aj | 54 +++++++++++++++++++ .../factory/aspectj/BeanConfigurerTests.java | 35 ++++++++++++ 2 files changed, 89 insertions(+) create mode 100644 org.springframework.aspects/src/main/java/org/springframework/beans/factory/aspectj/GenericInterfaceDrivenDependencyInjectionAspect.aj 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 {
+ *     private PricingStrategy pricingStrategy;
+ *     
+ *     public void configure(PricingStrategyClient bean) { 
+ *         bean.setPricingStrategy(pricingStrategy); 
+ *     }
+ *     
+ *     public void setPricingStrategy(PricingStrategy pricingStrategy) { 
+ *         this.pricingStrategy = pricingStrategy; 
+ *     } 
+ * }
+ * 
+ * @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; + } + } + public static interface MailSenderClient { public void setMailSender(MailSender mailSender); } @@ -521,6 +540,22 @@ public class BeanConfigurerTests extends TestCase { } + public static interface PricingStrategyClient { + public void setPricingStrategy(PricingStrategy pricingStrategy); + } + + public static class PricingStrategy { + + } + + public static class LineItem implements PricingStrategyClient { + private PricingStrategy pricingStrategy; + + public void setPricingStrategy(PricingStrategy pricingStrategy) { + this.pricingStrategy = pricingStrategy; + } + } + public static class Order implements MailSenderClient, Serializable { private transient MailSender mailSender;