diff --git a/spring-aspects/src/main/java/org/springframework/beans/factory/aspectj/AbstractDependencyInjectionAspect.aj b/spring-aspects/src/main/java/org/springframework/beans/factory/aspectj/AbstractDependencyInjectionAspect.aj index 58bebb9176..e0a9e9fad4 100644 --- a/spring-aspects/src/main/java/org/springframework/beans/factory/aspectj/AbstractDependencyInjectionAspect.aj +++ b/spring-aspects/src/main/java/org/springframework/beans/factory/aspectj/AbstractDependencyInjectionAspect.aj @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2014 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. @@ -27,20 +27,26 @@ import org.aspectj.lang.annotation.control.CodeGenerationHint; * @since 2.5.2 */ public abstract aspect AbstractDependencyInjectionAspect { - /** - * Select construction join points for objects to inject dependencies - */ - public abstract pointcut beanConstruction(Object bean); + + private pointcut preConstructionCondition() : + leastSpecificSuperTypeConstruction() && preConstructionConfiguration(); + + private pointcut postConstructionCondition() : + mostSpecificSubTypeConstruction() && !preConstructionConfiguration(); /** - * Select deserialization join points for objects to inject dependencies + * Select least specific super type that is marked for DI + * (so that injection occurs only once with pre-construction injection). */ - public abstract pointcut beanDeserialization(Object bean); + public abstract pointcut leastSpecificSuperTypeConstruction(); /** - * Select join points in a configurable bean + * Select the most-specific initialization join point + * (most concrete class) for the initialization of an instance. */ - public abstract pointcut inConfigurableBean(); + @CodeGenerationHint(ifNameSuffix="6f1") + public pointcut mostSpecificSubTypeConstruction() : + if (thisJoinPoint.getSignature().getDeclaringType() == thisJoinPoint.getThis().getClass()); /** * Select join points in beans to be configured prior to construction? @@ -49,36 +55,27 @@ public abstract aspect AbstractDependencyInjectionAspect { public pointcut preConstructionConfiguration() : if (false); /** - * Select the most-specific initialization join point - * (most concrete class) for the initialization of an instance. + * Select construction join points for objects to inject dependencies. */ - @CodeGenerationHint(ifNameSuffix="6f1") - public pointcut mostSpecificSubTypeConstruction() : - if (thisJoinPoint.getSignature().getDeclaringType() == thisJoinPoint.getThis().getClass()); + public abstract pointcut beanConstruction(Object bean); /** - * Select least specific super type that is marked for DI (so that injection occurs only once with pre-construction inejection + * Select deserialization join points for objects to inject dependencies. */ - public abstract pointcut leastSpecificSuperTypeConstruction(); + public abstract pointcut beanDeserialization(Object bean); /** - * Configure the bean + * Select join points in a configurable bean. */ - public abstract void configureBean(Object bean); + public abstract pointcut inConfigurableBean(); - private pointcut preConstructionCondition() : - leastSpecificSuperTypeConstruction() && preConstructionConfiguration(); - - private pointcut postConstructionCondition() : - mostSpecificSubTypeConstruction() && !preConstructionConfiguration(); - /** * Pre-construction configuration. */ @SuppressAjWarnings("adviceDidNotMatch") before(Object bean) : - beanConstruction(bean) && preConstructionCondition() && inConfigurableBean() { + beanConstruction(bean) && preConstructionCondition() && inConfigurableBean() { configureBean(bean); } @@ -87,7 +84,7 @@ public abstract aspect AbstractDependencyInjectionAspect { */ @SuppressAjWarnings("adviceDidNotMatch") after(Object bean) returning : - beanConstruction(bean) && postConstructionCondition() && inConfigurableBean() { + beanConstruction(bean) && postConstructionCondition() && inConfigurableBean() { configureBean(bean); } @@ -96,8 +93,14 @@ public abstract aspect AbstractDependencyInjectionAspect { */ @SuppressAjWarnings("adviceDidNotMatch") after(Object bean) returning : - beanDeserialization(bean) && inConfigurableBean() { + beanDeserialization(bean) && inConfigurableBean() { configureBean(bean); } + + /** + * Configure the given bean. + */ + public abstract void configureBean(Object bean); + } diff --git a/spring-aspects/src/main/java/org/springframework/beans/factory/aspectj/AbstractInterfaceDrivenDependencyInjectionAspect.aj b/spring-aspects/src/main/java/org/springframework/beans/factory/aspectj/AbstractInterfaceDrivenDependencyInjectionAspect.aj index 8270d6962d..a65be5f5bb 100644 --- a/spring-aspects/src/main/java/org/springframework/beans/factory/aspectj/AbstractInterfaceDrivenDependencyInjectionAspect.aj +++ b/spring-aspects/src/main/java/org/springframework/beans/factory/aspectj/AbstractInterfaceDrivenDependencyInjectionAspect.aj @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2014 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. @@ -20,49 +20,48 @@ import java.io.ObjectStreamException; import java.io.Serializable; /** - * An aspect that injects dependency into any object whose type implements the {@link ConfigurableObject} interface. - *

- * This aspect supports injecting into domain objects when they are created for the first time as well as - * upon deserialization. Subaspects need to simply provide definition for the configureBean() method. This - * method may be implemented without relying on Spring container if so desired. - *

- *

- * There are two cases that needs to be handled: + * An aspect that injects dependency into any object whose type implements the + * {@link ConfigurableObject} interface. + * + *

This aspect supports injecting into domain objects when they are created + * for the first time as well as upon deserialization. Subaspects need to simply + * provide definition for the configureBean() method. This method may be + * implemented without relying on Spring container if so desired. + * + *

There are two cases that needs to be handled: *

    - *
  1. Normal object creation via the '{@code new}' operator: this is - * taken care of by advising {@code initialization()} join points.
  2. - *
  3. Object creation through deserialization: since no constructor is - * invoked during deserialization, the aspect needs to advise a method that a - * deserialization mechanism is going to invoke. Ideally, we should not - * require user classes to implement any specific method. This implies that - * we need to introduce the chosen method. We should also handle the cases - * where the chosen method is already implemented in classes (in which case, - * the user's implementation for that method should take precedence over the - * introduced implementation). There are a few choices for the chosen method: - * - * The minor collaboration needed by user classes (i.e., that the - * implementation of {@code readResolve()}, if any, must be - * {@code public}) can be lifted as well if we were to use an - * experimental feature in AspectJ - the {@code hasmethod()} PCD.
  4. + *
  5. Normal object creation via the '{@code new}' operator: this is + * taken care of by advising {@code initialization()} join points.
  6. + *
  7. Object creation through deserialization: since no constructor is + * invoked during deserialization, the aspect needs to advise a method that a + * deserialization mechanism is going to invoke. Ideally, we should not + * require user classes to implement any specific method. This implies that + * we need to introduce the chosen method. We should also handle the cases + * where the chosen method is already implemented in classes (in which case, + * the user's implementation for that method should take precedence over the + * introduced implementation). There are a few choices for the chosen method: + * + * The minor collaboration needed by user classes (i.e., that the implementation of + * {@code readResolve()}, if any, must be {@code public}) can be lifted as well if we + * were to use an experimental feature in AspectJ - the {@code hasmethod()} PCD.
  8. *
- - *

- * While having type implement the {@link ConfigurableObject} interface is certainly a valid choice, an alternative - * is to use a 'declare parents' statement another aspect (a subaspect of this aspect would be a logical choice) - * that declares the classes that need to be configured by supplying the {@link ConfigurableObject} interface. - *

+ * + *

While having type implement the {@link ConfigurableObject} interface is certainly + * a valid choice, an alternative is to use a 'declare parents' statement another aspect + * (a subaspect of this aspect would be a logical choice) that declares the classes that + * need to be configured by supplying the {@link ConfigurableObject} interface. * * @author Ramnivas Laddad * @since 2.5.2 @@ -72,35 +71,33 @@ public abstract aspect AbstractInterfaceDrivenDependencyInjectionAspect extends * Select initialization join point as object construction */ public pointcut beanConstruction(Object bean) : - initialization(ConfigurableObject+.new(..)) && this(bean); + initialization(ConfigurableObject+.new(..)) && this(bean); /** * Select deserialization join point made available through ITDs for ConfigurableDeserializationSupport */ public pointcut beanDeserialization(Object bean) : - execution(Object ConfigurableDeserializationSupport+.readResolve()) && - this(bean); + execution(Object ConfigurableDeserializationSupport+.readResolve()) && this(bean); public pointcut leastSpecificSuperTypeConstruction() : initialization(ConfigurableObject.new(..)); // Implementation to support re-injecting dependencies once an object is deserialized + /** * Declare any class implementing Serializable and ConfigurableObject as also implementing - * ConfigurableDeserializationSupport. This allows us to introduce the readResolve() + * ConfigurableDeserializationSupport. This allows us to introduce the {@code readResolve()} * method and select it with the beanDeserialization() pointcut. - * *

Here is an improved version that uses the hasmethod() pointcut and lifts * even the minor requirement on user classes: - * - *

declare parents: ConfigurableObject+ Serializable+
-	 *		            && !hasmethod(Object readResolve() throws ObjectStreamException)
-	 *		            implements ConfigurableDeserializationSupport;
+	 * 
+	 * declare parents: ConfigurableObject+ Serializable+
+	 * && !hasmethod(Object readResolve() throws ObjectStreamException)
+	 * implements ConfigurableDeserializationSupport;
 	 * 
*/ - declare parents: - ConfigurableObject+ && Serializable+ implements ConfigurableDeserializationSupport; + declare parents: ConfigurableObject+ && Serializable+ implements ConfigurableDeserializationSupport; /** * A marker interface to which the {@code readResolve()} is introduced. @@ -111,7 +108,6 @@ public abstract aspect AbstractInterfaceDrivenDependencyInjectionAspect extends /** * Introduce the {@code readResolve()} method so that we can advise its * execution to configure the object. - * *

Note if a method with the same signature already exists in a * {@code Serializable} class of ConfigurableObject type, * that implementation will take precedence (a good thing, since we are diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ExceptionHandlerExceptionResolver.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ExceptionHandlerExceptionResolver.java index 8ef10d0302..8b0645f807 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ExceptionHandlerExceptionResolver.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ExceptionHandlerExceptionResolver.java @@ -68,7 +68,7 @@ import org.springframework.web.servlet.handler.AbstractHandlerMethodExceptionRes * @since 3.1 */ public class ExceptionHandlerExceptionResolver extends AbstractHandlerMethodExceptionResolver - implements InitializingBean, ApplicationContextAware { + implements ApplicationContextAware, InitializingBean { private List customArgumentResolvers; @@ -289,9 +289,7 @@ public class ExceptionHandlerExceptionResolver extends AbstractHandlerMethodExce ExceptionHandlerMethodResolver resolver = new ExceptionHandlerMethodResolver(bean.getBeanType()); if (resolver.hasExceptionMappings()) { this.exceptionHandlerAdviceCache.put(bean, resolver); - if (logger.isDebugEnabled()) { - logger.debug("Detected @ExceptionHandler methods in " + bean); - } + logger.info("Detected @ExceptionHandler methods in " + bean); } } } @@ -347,7 +345,7 @@ public class ExceptionHandlerExceptionResolver extends AbstractHandlerMethodExce * and if not found, it continues searching for additional {@code @ExceptionHandler} * methods assuming some {@linkplain ControllerAdvice @ControllerAdvice} * Spring-managed beans were detected. - * @param handlerMethod the method where the exception was raised, possibly {@code null} + * @param handlerMethod the method where the exception was raised (may be {@code null}) * @param exception the raised exception * @return a method to handle the exception, or {@code null} */