hzzz 7 years ago
parent
commit
8cdc66fbad
  1. 97
      fine-spring/src/com/fr/third/springframework/aop/aspectj/InstantiationModelAwarePointcutAdvisorImpl.java

97
fine-spring/src/com/fr/third/springframework/aop/aspectj/InstantiationModelAwarePointcutAdvisorImpl.java

@ -16,25 +16,24 @@
package com.fr.third.springframework.aop.aspectj; package com.fr.third.springframework.aop.aspectj;
import java.lang.reflect.Method;
import org.aopalliance.aop.Advice;
import com.fr.third.aspectj.lang.reflect.PerClauseKind; import com.fr.third.aspectj.lang.reflect.PerClauseKind;
import com.fr.third.springframework.aop.Pointcut; import com.fr.third.springframework.aop.Pointcut;
import com.fr.third.springframework.aop.support.DynamicMethodMatcherPointcut; import com.fr.third.springframework.aop.support.DynamicMethodMatcherPointcut;
import com.fr.third.springframework.aop.support.Pointcuts; import com.fr.third.springframework.aop.support.Pointcuts;
import org.aopalliance.aop.Advice;
import java.lang.reflect.Method;
/** /**
* Internal implementation of AspectJPointcutAdvisor. * Internal implementation of AspectJPointcutAdvisor. Note that there will be one instance of this
* Note that there will be one instance of this advisor for each target method. * advisor for each target method.
* *
* @author Rod Johnson * @author Rod Johnson
* @author Juergen Hoeller * @author Juergen Hoeller
* @since 2.0 * @since 2.0
*/ */
class InstantiationModelAwarePointcutAdvisorImpl class InstantiationModelAwarePointcutAdvisorImpl
implements InstantiationModelAwarePointcutAdvisor, AspectJPrecedenceInformation { implements InstantiationModelAwarePointcutAdvisor, AspectJPrecedenceInformation {
private final AspectJExpressionPointcut declaredPointcut; private final AspectJExpressionPointcut declaredPointcut;
@ -58,9 +57,13 @@ class InstantiationModelAwarePointcutAdvisorImpl
private Boolean isAfterAdvice; private Boolean isAfterAdvice;
public InstantiationModelAwarePointcutAdvisorImpl(
public InstantiationModelAwarePointcutAdvisorImpl(AspectJAdvisorFactory af, AspectJExpressionPointcut ajexp, AspectJAdvisorFactory af,
MetadataAwareAspectInstanceFactory aif, Method method, int declarationOrderInAspect, String aspectName) { AspectJExpressionPointcut ajexp,
MetadataAwareAspectInstanceFactory aif,
Method method,
int declarationOrderInAspect,
String aspectName) {
this.declaredPointcut = ajexp; this.declaredPointcut = ajexp;
this.method = method; this.method = method;
@ -72,15 +75,16 @@ class InstantiationModelAwarePointcutAdvisorImpl
if (aif.getAspectMetadata().isLazilyInstantiated()) { if (aif.getAspectMetadata().isLazilyInstantiated()) {
// Static part of the pointcut is a lazy type. // Static part of the pointcut is a lazy type.
Pointcut preInstantiationPointcut = Pointcut preInstantiationPointcut =
Pointcuts.union(aif.getAspectMetadata().getPerClausePointcut(), this.declaredPointcut); Pointcuts.union(aif.getAspectMetadata().getPerClausePointcut(), this.declaredPointcut);
// Make it dynamic: must mutate from pre-instantiation to post-instantiation state. // Make it dynamic: must mutate from pre-instantiation to post-instantiation state.
// If it's not a dynamic pointcut, it may be optimized out // If it's not a dynamic pointcut, it may be optimized out
// by the Spring AOP infrastructure after the first evaluation. // by the Spring AOP infrastructure after the first evaluation.
this.pointcut = new PerTargetInstantiationModelPointcut(this.declaredPointcut, preInstantiationPointcut, aif); this.pointcut =
new PerTargetInstantiationModelPointcut(
this.declaredPointcut, preInstantiationPointcut, aif);
this.lazy = true; this.lazy = true;
} } else {
else {
// A singleton aspect. // A singleton aspect.
this.instantiatedAdvice = instantiateAdvice(this.declaredPointcut); this.instantiatedAdvice = instantiateAdvice(this.declaredPointcut);
this.pointcut = declaredPointcut; this.pointcut = declaredPointcut;
@ -88,10 +92,9 @@ class InstantiationModelAwarePointcutAdvisorImpl
} }
} }
/** /**
* The pointcut for Spring AOP to use. Actual behaviour of the pointcut will change * The pointcut for Spring AOP to use. Actual behaviour of the pointcut will change depending on
* depending on the state of the advice. * the state of the advice.
*/ */
@Override @Override
public Pointcut getPointcut() { public Pointcut getPointcut() {
@ -99,25 +102,21 @@ class InstantiationModelAwarePointcutAdvisorImpl
} }
/** /**
* This is only of interest for Spring AOP: AspectJ instantiation semantics * This is only of interest for Spring AOP: AspectJ instantiation semantics are much richer. In
* are much richer. In AspectJ terminology, all a return of {@code true} * AspectJ terminology, all a return of {@code true} means here is that the aspect is not a
* means here is that the aspect is not a SINGLETON. * SINGLETON.
*/ */
@Override @Override
public boolean isPerInstance() { public boolean isPerInstance() {
return (getAspectMetadata().getAjType().getPerClause().getKind() != PerClauseKind.SINGLETON); return (getAspectMetadata().getAjType().getPerClause().getKind() != PerClauseKind.SINGLETON);
} }
/** /** Return the AspectJ AspectMetadata for this advisor. */
* Return the AspectJ AspectMetadata for this advisor.
*/
public AspectMetadata getAspectMetadata() { public AspectMetadata getAspectMetadata() {
return this.aspectInstanceFactory.getAspectMetadata(); return this.aspectInstanceFactory.getAspectMetadata();
} }
/** /** Lazily instantiate advice if necessary. */
* Lazily instantiate advice if necessary.
*/
@Override @Override
public synchronized Advice getAdvice() { public synchronized Advice getAdvice() {
if (this.instantiatedAdvice == null) { if (this.instantiatedAdvice == null) {
@ -136,10 +135,9 @@ class InstantiationModelAwarePointcutAdvisorImpl
return (this.instantiatedAdvice != null); return (this.instantiatedAdvice != null);
} }
private Advice instantiateAdvice(AspectJExpressionPointcut pcut) { private Advice instantiateAdvice(AspectJExpressionPointcut pcut) {
return this.atAspectJAdvisorFactory.getAdvice( return this.atAspectJAdvisorFactory.getAdvice(
this.method, pcut, this.aspectInstanceFactory, this.declarationOrder, this.aspectName); this.method, pcut, this.aspectInstanceFactory, this.declarationOrder, this.aspectName);
} }
public MetadataAwareAspectInstanceFactory getAspectInstanceFactory() { public MetadataAwareAspectInstanceFactory getAspectInstanceFactory() {
@ -182,17 +180,15 @@ class InstantiationModelAwarePointcutAdvisorImpl
} }
/** /**
* Duplicates some logic from getAdvice, but importantly does not force * Duplicates some logic from getAdvice, but importantly does not force creation of the advice.
* creation of the advice.
*/ */
private void determineAdviceType() { private void determineAdviceType() {
AbstractAspectJAdvisorFactory.AspectJAnnotation<?> aspectJAnnotation = AbstractAspectJAdvisorFactory.AspectJAnnotation<?> aspectJAnnotation =
AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(this.method); AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(this.method);
if (aspectJAnnotation == null) { if (aspectJAnnotation == null) {
this.isBeforeAdvice = false; this.isBeforeAdvice = false;
this.isAfterAdvice = false; this.isAfterAdvice = false;
} } else {
else {
switch (aspectJAnnotation.getAnnotationType()) { switch (aspectJAnnotation.getAnnotationType()) {
case AtAfter: case AtAfter:
case AtAfterReturning: case AtAfterReturning:
@ -212,20 +208,20 @@ class InstantiationModelAwarePointcutAdvisorImpl
} }
} }
@Override @Override
public String toString() { public String toString() {
return "InstantiationModelAwarePointcutAdvisor: expression [" + getDeclaredPointcut().getExpression() + return "InstantiationModelAwarePointcutAdvisor: expression ["
"]; advice method [" + this.method + "]; perClauseKind=" + + getDeclaredPointcut().getExpression()
this.aspectInstanceFactory.getAspectMetadata().getAjType().getPerClause().getKind(); + "]; advice method ["
+ this.method
+ "]; perClauseKind="
+ this.aspectInstanceFactory.getAspectMetadata().getAjType().getPerClause().getKind();
} }
/** /**
* Pointcut implementation that changes its behaviour when the advice is instantiated. * Pointcut implementation that changes its behaviour when the advice is instantiated. Note that
* Note that this is a <i>dynamic</i> pointcut. Otherwise it might * this is a <i>dynamic</i> pointcut. Otherwise it might be optimized out if it does not at first
* be optimized out if it does not at first match statically. * match statically.
*/ */
private class PerTargetInstantiationModelPointcut extends DynamicMethodMatcherPointcut { private class PerTargetInstantiationModelPointcut extends DynamicMethodMatcherPointcut {
@ -235,20 +231,24 @@ class InstantiationModelAwarePointcutAdvisorImpl
private LazySingletonAspectInstanceFactoryDecorator aspectInstanceFactory; private LazySingletonAspectInstanceFactoryDecorator aspectInstanceFactory;
private PerTargetInstantiationModelPointcut(AspectJExpressionPointcut declaredPointcut, private PerTargetInstantiationModelPointcut(
Pointcut preInstantiationPointcut, MetadataAwareAspectInstanceFactory aspectInstanceFactory) { AspectJExpressionPointcut declaredPointcut,
Pointcut preInstantiationPointcut,
MetadataAwareAspectInstanceFactory aspectInstanceFactory) {
this.declaredPointcut = declaredPointcut; this.declaredPointcut = declaredPointcut;
this.preInstantiationPointcut = preInstantiationPointcut; this.preInstantiationPointcut = preInstantiationPointcut;
if (aspectInstanceFactory instanceof LazySingletonAspectInstanceFactoryDecorator) { if (aspectInstanceFactory instanceof LazySingletonAspectInstanceFactoryDecorator) {
this.aspectInstanceFactory = (LazySingletonAspectInstanceFactoryDecorator) aspectInstanceFactory; this.aspectInstanceFactory =
(LazySingletonAspectInstanceFactoryDecorator) aspectInstanceFactory;
} }
} }
@Override @Override
public boolean matches(Method method, Class<?> targetClass) { public boolean matches(Method method, Class<?> targetClass) {
// We're either instantiated and matching on declared pointcut, or uninstantiated matching on either pointcut // We're either instantiated and matching on declared pointcut, or uninstantiated matching on
return (isAspectMaterialized() && this.declaredPointcut.matches(method, targetClass)) || // either pointcut
this.preInstantiationPointcut.getMethodMatcher().matches(method, targetClass); return (isAspectMaterialized() && this.declaredPointcut.matches(method, targetClass))
|| this.preInstantiationPointcut.getMethodMatcher().matches(method, targetClass);
} }
@Override @Override
@ -261,5 +261,4 @@ class InstantiationModelAwarePointcutAdvisorImpl
return (this.aspectInstanceFactory == null || this.aspectInstanceFactory.isMaterialized()); return (this.aspectInstanceFactory == null || this.aspectInstanceFactory.isMaterialized());
} }
} }
} }

Loading…
Cancel
Save