SpringAOP基础组件TargetSource

导读:本篇文章讲解 SpringAOP基础组件TargetSource,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

相关阅读

简介

TargetSource用于获取AOP调用的当前目标对象,如果没有环绕通知选择结束拦截器链本身,那么将通过反射调用该目标;
如果目标对象是静态的,则getTarget()始终返回相同的对象,从而允许在AOP框架中优化(缓存);如果是动态的,则支持池化、热交换等;

源码

public interface TargetSource extends TargetClassAware {

    // 目标对象的类型
    @Override
    @Nullable
    Class<?> getTargetClass();

    // 目标对象是否是静态的(不变的)
    boolean isStatic();

    // 获取目标对象
    @Nullable
    Object getTarget() throws Exception;

    // 释放目标对象
    void releaseTarget(Object target) throws Exception;
}

实现子类

TargetSource

EmptyTargetSource

简介

没有目标对象时的典范TargetSource,行为由实现的接口和Advisor提供;

核心代码

public final class EmptyTargetSource implements TargetSource, Serializable {

    // 典例
    public static final EmptyTargetSource INSTANCE = new EmptyTargetSource(null, true);


    public static EmptyTargetSource forClass(@Nullable Class<?> targetClass) {
        return forClass(targetClass, true);
    }

    public static EmptyTargetSource forClass(@Nullable Class<?> targetClass, boolean isStatic) {
        return (targetClass == null && isStatic ? INSTANCE : new EmptyTargetSource(targetClass, isStatic));
    }


    private final Class<?> targetClass;

    private final boolean isStatic;


    private EmptyTargetSource(@Nullable Class<?> targetClass, boolean isStatic) {
        this.targetClass = targetClass;
        this.isStatic = isStatic;
    }

    @Override
    @Nullable
    public Class<?> getTargetClass() {
        return this.targetClass;
    }

    @Override
    public boolean isStatic() {
        return this.isStatic;
    }

    @Override
    @Nullable
    public Object getTarget() {
        return null;
    }

    @Override
    public void releaseTarget(Object target) {
    }
}

HotSwappableTargetSource

简介

缓存本地目标对象,同时支持交换本地目标对象的TargetSource实现;

核心代码

public class HotSwappableTargetSource implements TargetSource, Serializable {

    // 目标对象
    private Object target;


    public HotSwappableTargetSource(Object initialTarget) {
        Assert.notNull(initialTarget, "Target object must not be null");
        this.target = initialTarget;
    }

    @Override
    public synchronized Class<?> getTargetClass() {
        return this.target.getClass();
    }

    @Override
    public final boolean isStatic() {
        return false;
    }

    @Override
    public synchronized Object getTarget() {
        return this.target;
    }

    @Override
    public void releaseTarget(Object target) {
        // nothing to do
    }

    public synchronized Object swap(Object newTarget) throws IllegalArgumentException {
        Assert.notNull(newTarget, "Target object must not be null");
        Object old = this.target;
        // 更新目标对象
        this.target = newTarget;
        // 返回旧目标对象
        return old;
    }
}

SingletonTargetSource

简介

持有指定目标对象的TargetSource实现,也是Spring AOP框架使用的TargetSource的默认实现;

核心代码

public class SingletonTargetSource implements TargetSource, Serializable {

    // 目标对象
    private final Object target;


    public SingletonTargetSource(Object target) {
        Assert.notNull(target, "Target object must not be null");
        this.target = target;
    }

    @Override
    public Class<?> getTargetClass() {
        return this.target.getClass();
    }

    @Override
    public Object getTarget() {
        return this.target;
    }

    @Override
    public void releaseTarget(Object target) {
        // nothing to do
    }

    @Override
    public boolean isStatic() {
        return true;
    }
}

AbstractRefreshableTargetSource

简介

包装一个可刷新的目标对象的TargetSource抽象实现;
子类可以决定是否需要刷新,并需要提供刷新后的目标对象;

核心代码

public abstract class AbstractRefreshableTargetSource implements TargetSource, Refreshable {

    // 目标对象
    @Nullable
    protected Object targetObject;

    // 刷新检查间隔时间(单位毫秒)
    private long refreshCheckDelay = -1;

    // 上次刷新检查时间戳
    private long lastRefreshCheck = -1;

    // 上次刷新时间戳
    private long lastRefreshTime = -1;

    // 刷新次数
    private long refreshCount = 0;


    @Override
    public synchronized Class<?> getTargetClass() {
        if (this.targetObject == null) {
            // 刷新
            refresh();
        }
        return this.targetObject.getClass();
    }

    @Override
    public boolean isStatic() {
        return false;
    }

    @Override
    @Nullable
    public final synchronized Object getTarget() {
        // 是否满足刷新条件
        if ((refreshCheckDelayElapsed() && requiresRefresh()) || this.targetObject == null) {
            refresh();
        }
        return this.targetObject;
    }

    @Override
    public void releaseTarget(Object object) {
    }

    @Override
    public final synchronized void refresh() {
        logger.debug("Attempting to refresh target");

        // 刷新目标对象
        this.targetObject = freshTarget();
        this.refreshCount++;
        this.lastRefreshTime = System.currentTimeMillis();

        logger.debug("Target refreshed successfully");
    }

    private boolean refreshCheckDelayElapsed() {
        if (this.refreshCheckDelay < 0) {
            return false;
        }

        long currentTimeMillis = System.currentTimeMillis();

        // 距上次刷新检查的时间间隔是否超过配置的间隔时间
        if (this.lastRefreshCheck < 0 || currentTimeMillis - this.lastRefreshCheck > this.refreshCheckDelay) {
            // Going to perform a refresh check - update the timestamp.
            this.lastRefreshCheck = currentTimeMillis;
            logger.debug("Refresh check delay elapsed - checking whether refresh is required");
            return true;
        }

        return false;
    }

    protected boolean requiresRefresh() {
        return true;
    }

    // 获取刷新后的目标对象,由子类实现算法细节
    protected abstract Object freshTarget();
}

AbstractBeanFactoryBasedTargetSource

简介

基于Spring BeanFactoryTargetSource的实现的基础类,目标对象为委托给Spring管理的Bean实例;
子类可以创建多例,或者懒创建单例;

核心代码

public abstract class AbstractBeanFactoryBasedTargetSource implements TargetSource, BeanFactoryAware, Serializable {

    // 目标对象的bean name
    private String targetBeanName;

    // 目标对象的类型
    private volatile Class<?> targetClass;

    private BeanFactory beanFactory;


    @Override
    public Class<?> getTargetClass() {
        Class<?> targetClass = this.targetClass;
        if (targetClass != null) {
            // 如果targetClass存在直接返回
            return targetClass;
        }
        // 否则根据targetBeanName获取targetClass
        synchronized (this) {
            targetClass = this.targetClass;
            if (targetClass == null && this.beanFactory != null) {
                // 先尝试根据targetBeanName直接获取类型
                targetClass = this.beanFactory.getType(this.targetBeanName);
                if (targetClass == null) {
                    if (logger.isTraceEnabled()) {
                        logger.trace("Getting bean with name '" + this.targetBeanName + "' for type determination");
                    }
                    // 再根据targetBeanName获取Bean
                    Object beanInstance = this.beanFactory.getBean(this.targetBeanName);
                    // 使用Bean的类型
                    targetClass = beanInstance.getClass();
                }
                this.targetClass = targetClass;
            }
            return targetClass;
        }
    }

    @Override
    public boolean isStatic() {
        return false;
    }

    @Override
    public void releaseTarget(Object target) throws Exception {
        // Nothing to do here.
    }

    // 拷贝其它AbstractBeanFactoryBasedTargetSource的配置
    protected void copyFrom(AbstractBeanFactoryBasedTargetSource other) {
        this.targetBeanName = other.targetBeanName;
        this.targetClass = other.targetClass;
        this.beanFactory = other.beanFactory;
    }
}

SimpleBeanTargetSource

简介

从Spring BeanFactory中获取目标对象的TargetSource的简单实现;
可以用于获取任何类型的目标对象:单例、多例、作用域,通常用于作用域Bean;

核心代码

public class SimpleBeanTargetSource extends AbstractBeanFactoryBasedTargetSource {

    @Override
    public Object getTarget() throws Exception {
        return getBeanFactory().getBean(getTargetBeanName());
    }
}

LazyInitTargetSource

简介

从Spring BeanFactory中懒加载单例类型的目标对象的TargetSource的实现;

核心代码

public class LazyInitTargetSource extends AbstractBeanFactoryBasedTargetSource {

    // 目标对象
    @Nullable
    private Object target;


    @Override
    @Nullable
    public synchronized Object getTarget() throws BeansException {
        // 懒初始化目标对象
        if (this.target == null) {
            this.target = getBeanFactory().getBean(getTargetBeanName());
            postProcessTargetObject(this.target);
        }
        return this.target;
    }

    // 子类可重写实现当目标对象第一次加载时的额外处理逻辑
    protected void postProcessTargetObject(Object targetObject) {
    }
}

PrototypeTargetSource

简介

每次获取时从Spring BeanFactory中创建目标对象,释放时销毁目标对象的TargetSource实现;

核心方法

public class PrototypeTargetSource extends AbstractPrototypeBasedTargetSource {

    @Override
    public Object getTarget() throws BeansException {
        // 创建多例类型目标对象
        return newPrototypeInstance();
    }

    @Override
    public void releaseTarget(Object target) {
        // 销毁多例类型目标对象
        destroyPrototypeInstance(target);
    }
}

ThreadLocalTargetSource

简介

基于线程模型的TargetSource实现,每个线程都拥有自己的目标对象副本,目标对象之间不存在竞争;
无法保证不同线程的调用中处理相同的目标对象,但是在单个线程的重复调用过程中可以依赖目标对象的状态;

核心代码

public class ThreadLocalTargetSource extends AbstractPrototypeBasedTargetSource
        implements ThreadLocalTargetSourceStats, DisposableBean {

    // 线程本地的目标对象
    private final ThreadLocal<Object> targetInThread =
            new NamedThreadLocal<>("Thread-local instance of bean '" + getTargetBeanName() + "'");

    // 创建的目标对象集合
    private final Set<Object> targetSet = new HashSet<>();

    // 调用次数
    private int invocationCount;

    // 命中次数
    private int hitCount;


    @Override
    public Object getTarget() throws BeansException {
        ++this.invocationCount;
        Object target = this.targetInThread.get();
        // 本线程未缓存目标对象
        if (target == null) {
            if (logger.isDebugEnabled()) {
                logger.debug("No target for prototype '" + getTargetBeanName() + "' bound to thread: " +
                        "creating one and binding it to thread '" + Thread.currentThread().getName() + "'");
            }
            // 创建目标对象并缓存到线程本地变量中
            target = newPrototypeInstance();
            this.targetInThread.set(target);
            synchronized (this.targetSet) {
                // 添加到创建的目标对象集合中
                this.targetSet.add(target);
            }
        }
        else {
            ++this.hitCount;
        }
        return target;
    }

    @Override
    public void destroy() {
        logger.debug("Destroying ThreadLocalTargetSource bindings");
        synchronized (this.targetSet) {
            // 销毁所有创建的目标对象
            for (Object target : this.targetSet) {
                destroyPrototypeInstance(target);
            }
            // 清空创建的目标对象集合
            this.targetSet.clear();
        }
        // Clear ThreadLocal, just in case.
        // 清空线程本地变量
        this.targetInThread.remove();
    }
}

CommonsPool2TargetSource

简介

将目标对象保存在可配置的Apache Commons2 PoolTargetSource实现;

核心代码

public class CommonsPool2TargetSource extends AbstractPoolingTargetSource implements PooledObjectFactory<Object> {
    
    @Override
    protected final void createPool() {
        logger.debug("Creating Commons object pool");
        this.pool = createObjectPool();
    }

    protected ObjectPool createObjectPool() {
        // 创建GenericObjectPool
        GenericObjectPoolConfig config = new GenericObjectPoolConfig();
        config.setMaxTotal(getMaxSize());
        config.setMaxIdle(getMaxIdle());
        config.setMinIdle(getMinIdle());
        config.setMaxWaitMillis(getMaxWait());
        config.setTimeBetweenEvictionRunsMillis(getTimeBetweenEvictionRunsMillis());
        config.setMinEvictableIdleTimeMillis(getMinEvictableIdleTimeMillis());
        config.setBlockWhenExhausted(isBlockWhenExhausted());
        return new GenericObjectPool(this, config);
    }

    @Override
    public Object getTarget() throws Exception {
        Assert.state(this.pool != null, "No Commons ObjectPool available");
        // 从池中获取目标对象
        return this.pool.borrowObject();
    }

    @Override
    public void releaseTarget(Object target) throws Exception {
        if (this.pool != null) {
            // 向池中返还目标对象
            this.pool.returnObject(target);
        }
    }

    @Override
    public void destroy() throws Exception {
        if (this.pool != null) {
            logger.debug("Closing Commons ObjectPool");
            // 关闭池
            this.pool.close();
        }
    }
}

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/4785.html

(0)
小半的头像小半

相关推荐

极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!