diff --git a/org.springframework.config.java/src/main/java/org/springframework/config/java/Bean.java b/org.springframework.config.java/src/main/java/org/springframework/config/java/Bean.java index 8210b49300a..8898a08ef56 100644 --- a/org.springframework.config.java/src/main/java/org/springframework/config/java/Bean.java +++ b/org.springframework.config.java/src/main/java/org/springframework/config/java/Bean.java @@ -54,7 +54,6 @@ import org.springframework.context.annotation.Scope; * that references between beans are strongly typed and navigable. So called 'inter-bean * references' are guaranteed to respect scoping and AOP semantics. * - * * @author Rod Johnson * @author Costin Leau * @author Chris Beams @@ -97,3 +96,8 @@ public @interface Bean { } +// TODO: test @Lazy @Bean +// TODO: test @Primary @Bean +// TODO: test Bean alias scenarios +// TODO: test init/destroy method scenarios +// TODO: test dependsOn diff --git a/org.springframework.config.java/src/main/java/org/springframework/config/java/Configuration.java b/org.springframework.config.java/src/main/java/org/springframework/config/java/Configuration.java index f37775ba53c..5a70edb3b61 100644 --- a/org.springframework.config.java/src/main/java/org/springframework/config/java/Configuration.java +++ b/org.springframework.config.java/src/main/java/org/springframework/config/java/Configuration.java @@ -48,9 +48,6 @@ import org.springframework.stereotype.Component; * {@link Autowired} constructor * * - * TODO: test constructor autowiring
- * TODO: test private Configuration classes
- * TODO: test @Lazy @Configuration
* * @author Rod Johnson * @author Chris Beams @@ -66,4 +63,8 @@ import org.springframework.stereotype.Component; @Documented public @interface Configuration { -} \ No newline at end of file +} + +// TODO: test constructor autowiring
+// TODO: test private Configuration classes
+// TODO: test @Lazy @Configuration
diff --git a/org.springframework.config.java/src/main/java/org/springframework/config/java/StandardScopes.java b/org.springframework.config.java/src/main/java/org/springframework/config/java/StandardScopes.java index 5abfce7a564..a89151f5bd8 100644 --- a/org.springframework.config.java/src/main/java/org/springframework/config/java/StandardScopes.java +++ b/org.springframework.config.java/src/main/java/org/springframework/config/java/StandardScopes.java @@ -39,3 +39,5 @@ public class StandardScopes { public static final String SESSION = "session"; } + +// TODO: move StandardScopes to appropriate package diff --git a/org.springframework.config.java/src/main/java/org/springframework/config/java/support/AbstractMethodInterceptor.java b/org.springframework.config.java/src/main/java/org/springframework/config/java/support/AbstractMethodInterceptor.java deleted file mode 100644 index 104fc56e433..00000000000 --- a/org.springframework.config.java/src/main/java/org/springframework/config/java/support/AbstractMethodInterceptor.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * 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.config.java.support; - -import java.lang.reflect.Method; - -import net.sf.cglib.proxy.MethodInterceptor; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.springframework.beans.BeansException; -import org.springframework.beans.factory.BeanFactory; -import org.springframework.beans.factory.BeanFactoryAware; -import org.springframework.beans.factory.support.DefaultListableBeanFactory; -import org.springframework.util.Assert; - - -/** - * Base class for all {@link MethodInterceptor} implementations. - * - * @author Chris Beams - */ -abstract class AbstractMethodInterceptor implements BeanFactoryAware, MethodInterceptor { - protected final Log log = LogFactory.getLog(this.getClass()); - protected DefaultListableBeanFactory beanFactory; - - public void setBeanFactory(BeanFactory beanFactory) throws BeansException { - Assert.isInstanceOf(DefaultListableBeanFactory.class, beanFactory); - this.beanFactory = (DefaultListableBeanFactory) beanFactory; - } - - protected String getBeanName(Method method) { - return method.getName(); - } -} diff --git a/org.springframework.config.java/src/main/java/org/springframework/config/java/support/BeanMethodInterceptor.java b/org.springframework.config.java/src/main/java/org/springframework/config/java/support/BeanMethodInterceptor.java index df5064f885f..c76cc978e9f 100644 --- a/org.springframework.config.java/src/main/java/org/springframework/config/java/support/BeanMethodInterceptor.java +++ b/org.springframework.config.java/src/main/java/org/springframework/config/java/support/BeanMethodInterceptor.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2008 the original author or authors. + * Copyright 2002-2009 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. @@ -19,41 +19,66 @@ import static java.lang.String.*; import java.lang.reflect.Method; +import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.BeanFactory; +import org.springframework.beans.factory.BeanFactoryAware; import org.springframework.beans.factory.config.ConfigurableBeanFactory; +import org.springframework.beans.factory.support.DefaultListableBeanFactory; import org.springframework.config.java.Bean; import org.springframework.context.annotation.Scope; import org.springframework.context.annotation.ScopedProxyMode; import org.springframework.core.annotation.AnnotationUtils; +import org.springframework.util.Assert; /** * Intercepts the invocation of any {@link Bean}-annotated methods in order to ensure proper * handling of bean semantics such as scoping and AOP proxying. * + * @author Chris Beams + * @since 3.0 * @see Bean * @see BeanRegistrar - * - * @author Chris Beams */ -class BeanMethodInterceptor extends AbstractMethodInterceptor { +class BeanMethodInterceptor implements BeanFactoryAware, MethodInterceptor { + protected final Log log = LogFactory.getLog(this.getClass()); + protected DefaultListableBeanFactory beanFactory; + + public void setBeanFactory(BeanFactory beanFactory) throws BeansException { + Assert.isInstanceOf(DefaultListableBeanFactory.class, beanFactory); + this.beanFactory = (DefaultListableBeanFactory) beanFactory; + } /** * Enhances a {@link Bean @Bean} method to check the supplied BeanFactory for the * existence of this bean object. */ public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { - String beanName = getBeanName(method); + + // determine the name of the bean + String beanName; + // check to see if the user has explicitly set the bean name + Bean bean = method.getAnnotation(Bean.class); + if(bean != null && bean.name().length > 1) + beanName = bean.name()[0]; + // if not, simply return the name of the method as the bean name + else + beanName = method.getName(); + // determine whether this bean is a scoped-proxy Scope scope = AnnotationUtils.findAnnotation(method, Scope.class); boolean isScopedProxy = (scope != null && scope.proxyMode() != ScopedProxyMode.NO); - - String scopedBeanName = - BeanRegistrar.resolveHiddenScopedProxyBeanName(beanName); - if (isScopedProxy && beanFactory.isCurrentlyInCreation(scopedBeanName)) - beanName = scopedBeanName; + String scopedBeanName = BeanRegistrar.resolveHiddenScopedProxyBeanName(beanName); + if (isScopedProxy && beanFactory.isCurrentlyInCreation(scopedBeanName)) + beanName = scopedBeanName; + // to handle the case of an inter-bean method reference, we must explicitly check the + // container for already cached instances if (factoryContainsBean(beanName)) { // we have an already existing cached instance of this bean -> retrieve it Object cachedBean = beanFactory.getBean(beanName); @@ -64,6 +89,7 @@ class BeanMethodInterceptor extends AbstractMethodInterceptor { return cachedBean; } + // actually create and return the bean return proxy.invokeSuper(obj, args); } @@ -87,5 +113,4 @@ class BeanMethodInterceptor extends AbstractMethodInterceptor { return beanFactory.containsBean(beanName) && !beanFactory.isCurrentlyInCreation(beanName); } - }