0
点赞
收藏
分享

微信扫一扫

SpringAOP联盟(10)-TargetSource目标源

TargetSource(目标源)是被代理的target(目标对象)实例的来源。TargetSource被用于获取当前MethodInvocation(方法调用)所需要的目标对象target。换句话说,proxy代理的并不是target,而是targetSource对象。

通常情况下,一个代理对象只能代理一个target,每次方法调用目标也是唯一的target。但是如果让proxy代理TargetSource,可以使得每次方法调用的target实例都不相同。(当然,这取决于TargetSource的实现)。而这种机制,可以使得方法的调用更加灵活。

1. Aop中TargetSource的使用方式

final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializable {
    //回调方法
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        MethodInvocation invocation;
        Object oldProxy = null;
        boolean setProxyContext = false;

        TargetSource targetSource = this.advised.targetSource;
        Object target = null;
            ...
            //(代码1)获取target对象
            target = targetSource.getTarget();
            Class<?> targetClass = (target != null ? target.getClass() : null);

            // 获取Advised的过滤器链
            List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
            //若MethodInterceptor的Chain为空时
            if (chain.isEmpty()) {
                Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
                retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
            }
            else {
                // 调用拦截器链...
                invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
                retVal = invocation.proceed();
            }

           ...
        }
        finally {
            if (target != null && !targetSource.isStatic()) {
                //(代码2) 释放Target对象
                targetSource.releaseTarget(target);
            }
          ...
        }
    }
}

2. TargetSource对象结构

public interface TargetSource extends TargetClassAware {
    //返回目标类型
    Class<?> getTargetClass();
    //判断getTarget()返回的是相同对象吗?在这种情况下,不需要调用eleaseTarget(Object)方法。
    //若目标对象是不可变的,AOP框架可以缓存getTarget()的返回值
    boolean isStatic();
    //获取目标对象
    Object getTarget() throws Exception;
    //释放从getTarget()方法,如果有的情况下。
    void releaseTarget(Object target) throws Exception;
}

SpringAOP的自动代理会使用SingletonTargetSource去创建TargetSource对象。

而其他子类的作用一般在手动代理时按需使用。

  • EmptyTargetSource:静态目标源,当不存在target目标对象或者连TargetClass目标类都不存在时使用。
  • HotSwappableTargetSource:动态目标源,支持热替换的目标源,支持Spring应用运行时替换目标对象。
  • JndiObjectTargetSource:Spring对JNDI管理bean的支持,static可配置。
  • SingletonTargetSource:静态对象源,Spring的AOP框架单例bean创建的目标源。换句话说,SingletonTargetSource、proxy和目标bean三者的生命周期均相同。
  • AbstractBeanFactoryBasedTargetSource:此类基于IOC容器使用,也就是说target目标对象可以通过beanName从容器中获取,而该类的实现类:
    • SimpleBeanTargetSource:直接调用getBean从容器中获取target对象;
    • LazyInitTargetSource:延迟加载目标源,子类可重写postProcessTargetObject方法;
    • AbstractPrototypeBasedTargetSource:原型bean目标源,此抽象类可确保beanName对应的bean的scope属性为prototype。其子类为简单原型、池化原型、线程隔离原型这3种实现。
  • AbstractRefreshableTargetSource:可刷新的目标源,此类的实现可根据配置的刷新延迟时间,在每次获取对象时自动刷新目标对象。
  • AbstractLazyCreationTargetSource:此类是在调用getTarget()获取时才创建目标对象,创建方法由子类实现。

推荐阅读

https://segmentfault.com/a/1190000020193616

spring-aop组件详解——TargetSource目标源

举报

相关推荐

0 条评论