|
|
|
@ -17,10 +17,10 @@ |
|
|
|
package org.springframework.aop.aspectj.annotation; |
|
|
|
package org.springframework.aop.aspectj.annotation; |
|
|
|
|
|
|
|
|
|
|
|
import java.util.Collections; |
|
|
|
import java.util.Collections; |
|
|
|
import java.util.HashMap; |
|
|
|
|
|
|
|
import java.util.LinkedList; |
|
|
|
import java.util.LinkedList; |
|
|
|
import java.util.List; |
|
|
|
import java.util.List; |
|
|
|
import java.util.Map; |
|
|
|
import java.util.Map; |
|
|
|
|
|
|
|
import java.util.concurrent.ConcurrentHashMap; |
|
|
|
|
|
|
|
|
|
|
|
import org.aspectj.lang.reflect.PerClauseKind; |
|
|
|
import org.aspectj.lang.reflect.PerClauseKind; |
|
|
|
|
|
|
|
|
|
|
|
@ -43,12 +43,11 @@ public class BeanFactoryAspectJAdvisorsBuilder { |
|
|
|
|
|
|
|
|
|
|
|
private final AspectJAdvisorFactory advisorFactory; |
|
|
|
private final AspectJAdvisorFactory advisorFactory; |
|
|
|
|
|
|
|
|
|
|
|
private List<String> aspectBeanNames; |
|
|
|
private volatile List<String> aspectBeanNames; |
|
|
|
|
|
|
|
|
|
|
|
private final Map<String, List<Advisor>> advisorsCache = new HashMap<>(); |
|
|
|
private final Map<String, List<Advisor>> advisorsCache = new ConcurrentHashMap<>(); |
|
|
|
|
|
|
|
|
|
|
|
private final Map<String, MetadataAwareAspectInstanceFactory> aspectFactoryCache = |
|
|
|
private final Map<String, MetadataAwareAspectInstanceFactory> aspectFactoryCache = new ConcurrentHashMap<>(); |
|
|
|
new HashMap<>(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
@ -56,7 +55,7 @@ public class BeanFactoryAspectJAdvisorsBuilder { |
|
|
|
* @param beanFactory the ListableBeanFactory to scan |
|
|
|
* @param beanFactory the ListableBeanFactory to scan |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public BeanFactoryAspectJAdvisorsBuilder(ListableBeanFactory beanFactory) { |
|
|
|
public BeanFactoryAspectJAdvisorsBuilder(ListableBeanFactory beanFactory) { |
|
|
|
this(beanFactory, new ReflectiveAspectJAdvisorFactory()); |
|
|
|
this(beanFactory, new ReflectiveAspectJAdvisorFactory(beanFactory)); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
@ -80,56 +79,57 @@ public class BeanFactoryAspectJAdvisorsBuilder { |
|
|
|
* @see #isEligibleBean |
|
|
|
* @see #isEligibleBean |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public List<Advisor> buildAspectJAdvisors() { |
|
|
|
public List<Advisor> buildAspectJAdvisors() { |
|
|
|
List<String> aspectNames = null; |
|
|
|
List<String> aspectNames = this.aspectBeanNames; |
|
|
|
|
|
|
|
|
|
|
|
synchronized (this) { |
|
|
|
if (aspectNames == null) { |
|
|
|
aspectNames = this.aspectBeanNames; |
|
|
|
synchronized (this) { |
|
|
|
if (aspectNames == null) { |
|
|
|
aspectNames = this.aspectBeanNames; |
|
|
|
List<Advisor> advisors = new LinkedList<>(); |
|
|
|
if (aspectNames == null) { |
|
|
|
aspectNames = new LinkedList<>(); |
|
|
|
List<Advisor> advisors = new LinkedList<>(); |
|
|
|
String[] beanNames = |
|
|
|
aspectNames = new LinkedList<>(); |
|
|
|
BeanFactoryUtils.beanNamesForTypeIncludingAncestors(this.beanFactory, Object.class, true, false); |
|
|
|
String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors( |
|
|
|
for (String beanName : beanNames) { |
|
|
|
this.beanFactory, Object.class, true, false); |
|
|
|
if (!isEligibleBean(beanName)) { |
|
|
|
for (String beanName : beanNames) { |
|
|
|
continue; |
|
|
|
if (!isEligibleBean(beanName)) { |
|
|
|
} |
|
|
|
continue; |
|
|
|
// We must be careful not to instantiate beans eagerly as in this
|
|
|
|
} |
|
|
|
// case they would be cached by the Spring container but would not
|
|
|
|
// We must be careful not to instantiate beans eagerly as in this case they
|
|
|
|
// have been weaved
|
|
|
|
// would be cached by the Spring container but would not have been weaved.
|
|
|
|
Class<?> beanType = this.beanFactory.getType(beanName); |
|
|
|
Class<?> beanType = this.beanFactory.getType(beanName); |
|
|
|
if (beanType == null) { |
|
|
|
if (beanType == null) { |
|
|
|
continue; |
|
|
|
continue; |
|
|
|
} |
|
|
|
} |
|
|
|
if (this.advisorFactory.isAspect(beanType)) { |
|
|
|
if (this.advisorFactory.isAspect(beanType)) { |
|
|
|
aspectNames.add(beanName); |
|
|
|
aspectNames.add(beanName); |
|
|
|
AspectMetadata amd = new AspectMetadata(beanType, beanName); |
|
|
|
AspectMetadata amd = new AspectMetadata(beanType, beanName); |
|
|
|
if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) { |
|
|
|
if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) { |
|
|
|
MetadataAwareAspectInstanceFactory factory = |
|
|
|
MetadataAwareAspectInstanceFactory factory = |
|
|
|
new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName); |
|
|
|
new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName); |
|
|
|
List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory); |
|
|
|
List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory); |
|
|
|
if (this.beanFactory.isSingleton(beanName)) { |
|
|
|
if (this.beanFactory.isSingleton(beanName)) { |
|
|
|
this.advisorsCache.put(beanName, classAdvisors); |
|
|
|
this.advisorsCache.put(beanName, classAdvisors); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else { |
|
|
|
|
|
|
|
this.aspectFactoryCache.put(beanName, factory); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
advisors.addAll(classAdvisors); |
|
|
|
} |
|
|
|
} |
|
|
|
else { |
|
|
|
else { |
|
|
|
|
|
|
|
// Per target or per this.
|
|
|
|
|
|
|
|
if (this.beanFactory.isSingleton(beanName)) { |
|
|
|
|
|
|
|
throw new IllegalArgumentException("Bean with name '" + beanName + |
|
|
|
|
|
|
|
"' is a singleton, but aspect instantiation model is not singleton"); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
MetadataAwareAspectInstanceFactory factory = |
|
|
|
|
|
|
|
new PrototypeAspectInstanceFactory(this.beanFactory, beanName); |
|
|
|
this.aspectFactoryCache.put(beanName, factory); |
|
|
|
this.aspectFactoryCache.put(beanName, factory); |
|
|
|
|
|
|
|
advisors.addAll(this.advisorFactory.getAdvisors(factory)); |
|
|
|
} |
|
|
|
} |
|
|
|
advisors.addAll(classAdvisors); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else { |
|
|
|
|
|
|
|
// Per target or per this.
|
|
|
|
|
|
|
|
if (this.beanFactory.isSingleton(beanName)) { |
|
|
|
|
|
|
|
throw new IllegalArgumentException("Bean with name '" + beanName + |
|
|
|
|
|
|
|
"' is a singleton, but aspect instantiation model is not singleton"); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
MetadataAwareAspectInstanceFactory factory = |
|
|
|
|
|
|
|
new PrototypeAspectInstanceFactory(this.beanFactory, beanName); |
|
|
|
|
|
|
|
this.aspectFactoryCache.put(beanName, factory); |
|
|
|
|
|
|
|
advisors.addAll(this.advisorFactory.getAdvisors(factory)); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
this.aspectBeanNames = aspectNames; |
|
|
|
|
|
|
|
return advisors; |
|
|
|
} |
|
|
|
} |
|
|
|
this.aspectBeanNames = aspectNames; |
|
|
|
|
|
|
|
return advisors; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|