相关阅读
简介
由切点CacheOperationSourcePointcut
驱动的切面;
核心代码
// 缓存动作解析器
@Nullable
private CacheOperationSource cacheOperationSource;
// 基于CacheOperationSource的切点
private final CacheOperationSourcePointcut pointcut = new CacheOperationSourcePointcut() {
@Override
@Nullable
protected CacheOperationSource getCacheOperationSource() {
return cacheOperationSource;
}
};
/**
* 获取切点
*/
@Override
public Pointcut getPointcut() {
// 返回基于CacheOperationSource的切点
return this.pointcut;
}
CacheOperationSourcePointcut
简介
基于CacheOperationSource
的切点;
核心代码
/**
* 切点逻辑,是否满足插入增强
*/
@Override
public boolean matches(Method method, Class<?> targetClass) {
CacheOperationSource cas = getCacheOperationSource();
// 使用CacheOperationSource判断当前方法是否有缓存动作
return (cas != null && !CollectionUtils.isEmpty(cas.getCacheOperations(method, targetClass)));
}
/**
* 获取缓存动作解析器
* 抽象方法,由子类实现算法细节
*/
@Nullable
protected abstract CacheOperationSource getCacheOperationSource();
/**
* 类型过滤器
* 内部类
*/
private class CacheOperationSourceClassFilter implements ClassFilter {
/**
* 匹配
*/
@Override
public boolean matches(Class<?> clazz) {
if (CacheManager.class.isAssignableFrom(clazz)) {
return false;
}
// 基于CacheOperationSource实现类型过滤
CacheOperationSource cas = getCacheOperationSource();
return (cas == null || cas.isCandidateClass(clazz));
}
}
继承关系
public interface PointcutAdvisor extends Advisor
public abstract class AbstractPointcutAdvisor implements PointcutAdvisor, Ordered, Serializable
public abstract class AbstractBeanFactoryPointcutAdvisor extends AbstractPointcutAdvisor implements BeanFactoryAware
public class BeanFactoryCacheOperationSourceAdvisor extends AbstractBeanFactoryPointcutAdvisor
PointcutAdvisor
简介
切点驱动的切面的超类;
核心代码
/**
* 获取切点
*/
Pointcut getPointcut();
AbstractPointcutAdvisor
简介
PointcutAdvisor
接口的抽象基础类,子类需要实现getPointcut()
方法;
核心代码
// 顺序
@Nullable
private Integer order;
/**
* 获取顺序
*/
@Override
public int getOrder() {
if (this.order != null) {
return this.order;
}
Advice advice = getAdvice();
if (advice instanceof Ordered) {
return ((Ordered) advice).getOrder();
}
// 默认最后
return Ordered.LOWEST_PRECEDENCE;
}
AbstractBeanFactoryPointcutAdvisor
简介
支持从BeanFactory
中根据Advice
的beanName配置Advice
;
核心代码
// Advice的beanName
@Nullable
private String adviceBeanName;
// Bean工厂
@Nullable
private BeanFactory beanFactory;
// Advice
@Nullable
private transient volatile Advice advice;
// 对象锁
private transient volatile Object adviceMonitor = new Object();
/**
* 设置增强
*/
public void setAdvice(Advice advice) {
synchronized (this.adviceMonitor) {
this.advice = advice;
}
}
/**
* 获取增强
*/
public Advice getAdvice() {
Advice advice = this.advice;
if (advice != null) {
// 存在则返回
return advice;
}
// 不存在需要从BeanFactory中根据adviceBeanName获取
// 校验adviceBeanName
Assert.state(this.adviceBeanName != null, "'adviceBeanName' must be specified");
Assert.state(this.beanFactory != null, "BeanFactory must be set to resolve 'adviceBeanName'");
if (this.beanFactory.isSingleton(this.adviceBeanName)) {
// 单例则直接从Bean工厂获取
// Rely on singleton semantics provided by the factory.
advice = this.beanFactory.getBean(this.adviceBeanName, Advice.class);
this.advice = advice;
return advice;
}
else {
// 多例则需要防止重复获取
// No singleton guarantees from the factory -> let's lock locally but
// reuse the factory's singleton lock, just in case a lazy dependency
// of our advice bean happens to trigger the singleton lock implicitly...
synchronized (this.adviceMonitor) {
advice = this.advice;
if (advice == null) {
advice = this.beanFactory.getBean(this.adviceBeanName, Advice.class);
this.advice = advice;
}
return advice;
}
}
}