Skip to content

Commit

Permalink
Restore *.aj whitespace
Browse files Browse the repository at this point in the history
The removal of whitespace to the *.aj files made in 1762157 cause
NoSuchMethodError for code compiled against previous versions of
spring-aspects due to a bug in AspectJ (see SPR-10178 for details).

This commit reverts all the whitespace changes made in 1762157 which
resolves the NoSuchMethodErrors.

Issue: SPR-10178
  • Loading branch information
rwinch committed Jan 15, 2013
1 parent e44b4b8 commit 6888a6f
Showing 13 changed files with 129 additions and 145 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2013 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.
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.springframework.beans.factory.aspectj;

import org.aspectj.lang.annotation.SuppressAjWarnings;
@@ -23,12 +23,12 @@ import org.springframework.beans.factory.wiring.BeanConfigurerSupport;
* Abstract superaspect for AspectJ aspects that can perform Dependency
* Injection on objects, however they may be created. Define the beanCreation()
* pointcut in subaspects.
*
*
* <p>Subaspects may also need a metadata resolution strategy, in the
* {@code BeanWiringInfoResolver} interface. The default implementation
* <code>BeanWiringInfoResolver</code> interface. The default implementation
* looks for a bean with the same name as the FQN. This is the default name
* of a bean in a Spring container if the id value is not supplied explicitly.
*
*
* @author Rob Harrop
* @author Rod Johnson
* @author Adrian Colyer
@@ -62,7 +62,7 @@ public abstract aspect AbstractBeanConfigurerAspect extends BeanConfigurerSuppor

/**
* The initialization of a new object.
*
*
* <p>WARNING: Although this pointcut is non-abstract for backwards
* compatibility reasons, it is meant to be overridden to select
* initialization of any configurable bean.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2013 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.
@@ -21,34 +21,34 @@ import org.aspectj.lang.annotation.SuppressAjWarnings;
/**
* Abstract base aspect that can perform Dependency
* Injection on objects, however they may be created.
*
*
* @author Ramnivas Laddad
* @since 2.5.2
*/
public abstract aspect AbstractDependencyInjectionAspect {
/**
* Select construction join points for objects to inject dependencies
*/
public abstract pointcut beanConstruction(Object bean);
public abstract pointcut beanConstruction(Object bean);

/**
* Select deserialization join points for objects to inject dependencies
*/
public abstract pointcut beanDeserialization(Object bean);

/**
* Select join points in a configurable bean
*/
public abstract pointcut inConfigurableBean();

/**
* Select join points in beans to be configured prior to construction?
* By default, use post-construction injection matching the default in the Configurable annotation.
*/
public pointcut preConstructionConfiguration() : if(false);

/**
* Select the most-specific initialization join point
* Select the most-specific initialization join point
* (most concrete class) for the initialization of an instance.
*/
public pointcut mostSpecificSubTypeConstruction() :
@@ -58,44 +58,44 @@ public abstract aspect AbstractDependencyInjectionAspect {
* Select least specific super type that is marked for DI (so that injection occurs only once with pre-construction inejection
*/
public abstract pointcut leastSpecificSuperTypeConstruction();

/**
* Configure the bean
*/
public abstract void configureBean(Object bean);


private pointcut preConstructionCondition() :
private pointcut preConstructionCondition() :
leastSpecificSuperTypeConstruction() && preConstructionConfiguration();

private pointcut postConstructionCondition() :
mostSpecificSubTypeConstruction() && !preConstructionConfiguration();

/**
* Pre-construction configuration.
*/
@SuppressAjWarnings("adviceDidNotMatch")
before(Object bean) :
beanConstruction(bean) && preConstructionCondition() && inConfigurableBean() {
before(Object bean) :
beanConstruction(bean) && preConstructionCondition() && inConfigurableBean() {
configureBean(bean);
}

/**
* Post-construction configuration.
*/
@SuppressAjWarnings("adviceDidNotMatch")
after(Object bean) returning :
after(Object bean) returning :
beanConstruction(bean) && postConstructionCondition() && inConfigurableBean() {
configureBean(bean);
}

/**
* Post-deserialization configuration.
*/
@SuppressAjWarnings("adviceDidNotMatch")
after(Object bean) returning :
after(Object bean) returning :
beanDeserialization(bean) && inConfigurableBean() {
configureBean(bean);
}

}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2013 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.
@@ -26,94 +26,94 @@ import java.io.Serializable;
* 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.
* </p>
* <p>
* <p>
* There are two cases that needs to be handled:
* <ol>
* <li>Normal object creation via the '{@code new}' operator: this is
* taken care of by advising {@code initialization()} join points.</li>
* <li>Normal object creation via the '<code>new</code>' operator: this is
* taken care of by advising <code>initialization()</code> join points.</li>
* <li>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 <i>introduce</i> 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
* the user's implementation for that method should take precedence over the
* introduced implementation). There are a few choices for the chosen method:
* <ul>
* <li>readObject(ObjectOutputStream): Java requires that the method must be
* {@code private}. Since aspects cannot introduce a private member,
* <code>private</p>. Since aspects cannot introduce a private member,
* while preserving its name, this option is ruled out.</li>
* <li>readResolve(): Java doesn't pose any restriction on an access specifier.
* Problem solved! There is one (minor) limitation of this approach in
* that if a user class already has this method, that method must be
* {@code public}. However, this shouldn't be a big burden, since
* use cases that need classes to implement readResolve() (custom enums,
* <li>readResolve(): Java doesn't pose any restriction on an access specifier.
* Problem solved! There is one (minor) limitation of this approach in
* that if a user class already has this method, that method must be
* <code>public</code>. However, this shouldn't be a big burden, since
* use cases that need classes to implement readResolve() (custom enums,
* for example) are unlikely to be marked as &#64;Configurable, and
* in any case asking to make that method {@code public} should not
* in any case asking to make that method <code>public</code> should not
* pose any undue burden.</li>
* </ul>
* 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.</li>
* The minor collaboration needed by user classes (i.e., that the
* implementation of <code>readResolve()</code>, if any, must be
* <code>public</code>) can be lifted as well if we were to use an
* experimental feature in AspectJ - the <code>hasmethod()</code> PCD.</li>
* </ol>
* <p>
* 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.
* </p>
*
*
* @author Ramnivas Laddad
* @since 2.5.2
*/
public abstract aspect AbstractInterfaceDrivenDependencyInjectionAspect extends AbstractDependencyInjectionAspect {
/**
* Select initialization join point as object construction
*/
public pointcut beanConstruction(Object bean) :
initialization(ConfigurableObject+.new(..)) && this(bean);
public pointcut beanConstruction(Object 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);

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()
* Declare any class implementing Serializable and ConfigurableObject as also implementing
* ConfigurableDeserializationSupport. This allows us to introduce the readResolve()
* method and select it with the beanDeserialization() pointcut.
*
*
* <p>Here is an improved version that uses the hasmethod() pointcut and lifts
* even the minor requirement on user classes:
*
* <pre class="code">declare parents: ConfigurableObject+ Serializable+
* && !hasmethod(Object readResolve() throws ObjectStreamException)
* && !hasmethod(Object readResolve() throws ObjectStreamException)
* implements ConfigurableDeserializationSupport;
* </pre>
*/
declare parents:
declare parents:
ConfigurableObject+ && Serializable+ implements ConfigurableDeserializationSupport;

/**
* A marker interface to which the {@code readResolve()} is introduced.
* A marker interface to which the <code>readResolve()</code> is introduced.
*/
static interface ConfigurableDeserializationSupport extends Serializable {
}

/**
* Introduce the {@code readResolve()} method so that we can advise its
* Introduce the <code>readResolve()</code> method so that we can advise its
* execution to configure the object.
*
*
* <p>Note if a method with the same signature already exists in a
* {@code Serializable} class of ConfigurableObject type,
* <code>Serializable</code> class of ConfigurableObject type,
* that implementation will take precedence (a good thing, since we are
* merely interested in an opportunity to detect deserialization.)
*/
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2013 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.
@@ -32,7 +32,7 @@ import org.springframework.beans.factory.wiring.BeanConfigurerSupport;
* annotation to identify which classes need autowiring.
*
* <p>The bean name to look up will be taken from the
* {@code &#64;Configurable} annotation if specified, otherwise the
* <code>&#64;Configurable</code> annotation if specified, otherwise the
* default bean name to look up will be the FQN of the class being configured.
*
* @author Rod Johnson
@@ -43,15 +43,15 @@ import org.springframework.beans.factory.wiring.BeanConfigurerSupport;
* @see org.springframework.beans.factory.annotation.Configurable
* @see org.springframework.beans.factory.annotation.AnnotationBeanWiringInfoResolver
*/
public aspect AnnotationBeanConfigurerAspect
public aspect AnnotationBeanConfigurerAspect
extends AbstractInterfaceDrivenDependencyInjectionAspect
implements BeanFactoryAware, InitializingBean, DisposableBean {

private BeanConfigurerSupport beanConfigurerSupport = new BeanConfigurerSupport();

public pointcut inConfigurableBean() : @this(Configurable);

public pointcut preConstructionConfiguration() : preConstructionConfigurationSupport(*);
public pointcut preConstructionConfiguration() : preConstructionConfigurationSupport(*);

declare parents: @Configurable * implements ConfigurableObject;

@@ -80,10 +80,10 @@ public aspect AnnotationBeanConfigurerAspect
private pointcut preConstructionConfigurationSupport(Configurable c) : @this(c) && if(c.preConstruction());

/*
* This declaration shouldn't be needed,
* This declaration shouldn't be needed,
* except for an AspectJ bug (https://bugs.eclipse.org/bugs/show_bug.cgi?id=214559)
*/
declare parents: @Configurable Serializable+
declare parents: @Configurable Serializable+
implements ConfigurableDeserializationSupport;

}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2013 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.
@@ -17,38 +17,38 @@ package org.springframework.beans.factory.aspectj;

/**
* Generic-based dependency injection aspect.
* <p>
* This aspect allows users to implement efficient, type-safe dependency injection without
* <p>
* This aspect allows users to implement efficient, type-safe dependency injection without
* the use of the &#64;Configurable annotation.
*
* The subaspect of this aspect doesn't need to include any AOP constructs.
* For example, here is a subaspect that configures the {@code PricingStrategyClient} objects.
*
* The subaspect of this aspect doesn't need to include any AOP constructs.
* For example, here is a subaspect that configures the <code>PricingStrategyClient</code> objects.
* <pre>
* aspect PricingStrategyDependencyInjectionAspect
* aspect PricingStrategyDependencyInjectionAspect
* extends GenericInterfaceDrivenDependencyInjectionAspect<PricingStrategyClient> {
* private PricingStrategy pricingStrategy;
*
* public void configure(PricingStrategyClient bean) {
* bean.setPricingStrategy(pricingStrategy);
* }
*
* public void setPricingStrategy(PricingStrategy pricingStrategy) {
* this.pricingStrategy = pricingStrategy;
*
* public void configure(PricingStrategyClient bean) {
* bean.setPricingStrategy(pricingStrategy);
* }
*
* public void setPricingStrategy(PricingStrategy pricingStrategy) {
* this.pricingStrategy = pricingStrategy;
* }
* }
* </pre>
* @author Ramnivas Laddad
* @since 3.0.0
*/
public abstract aspect GenericInterfaceDrivenDependencyInjectionAspect<I> extends AbstractInterfaceDrivenDependencyInjectionAspect {
declare parents: I implements ConfigurableObject;

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
// Unfortunately, erasure used with generics won't allow to use the same named method
protected abstract void configure(I bean);
}
Loading

0 comments on commit 6888a6f

Please sign in to comment.