《Spring揭秘》第九章——Spring AOP一世

AOP中的Jointpoint有很多中,如 构造方法调用、字段的设置与读取、方法调用、方法执行等,在Spring AOP中,Jointpoint仅支持方法级别的Jointpoint,更确切的说是,只支持方法执行(Method ExeCution)类型的Jointpoint。

Pointcut

public interface Pointcut {

    // class过滤器,匹配将要被进行织入操作的类
    ClassFilter getClassFilter();

    // 方法过滤器,匹配将要被进行织入操作的方法
    MethodMatcher getMethodMatcher();

    Pointcut TRUE = TruePointcut.INSTANCE;

}
@FunctionalInterface
public interface ClassFilter {

    boolean matches(Class<?> clazz);
        
    ClassFilter TRUE = TrueClassFilter.INSTANCE;

}
public interface MethodMatcher {

    boolean matches(Method method, @Nullable Class<?> targetClass);
   // 方法返回true表示需要每次对方法调用的参数进行匹配 DynamicMethodMatcher
// 方法返回FALSE表示不需要关心方法调用的参数 StaticMethodMatcher
boolean isRuntime(); boolean matches(Method method, @Nullable Class<?> targetClass, Object... args); MethodMatcher TRUE = TrueMethodMatcher.INSTANCE; }

Advice

 

Advisor

Spring中没有完全明确的Aspect的概念,Advisor相当于Spring中的Aspect,但是Advisor通常只有一个Pointcut和一个Advice

Spring AOP的织入

ProxyFactory是Spring中最基础的织入器

public class ProxyFactory extends ProxyCreatorSupport {

    // ...
    public Object getProxy() {
        return createAopProxy().getProxy();
    }
    // ...
    public Object getProxy(@Nullable ClassLoader classLoader) {
        return createAopProxy().getProxy(classLoader);
    }
    // ...
}

public class ProxyCreatorSupport extends AdvisedSupport {

    private AopProxyFactory aopProxyFactory;

    public ProxyCreatorSupport() {
        this.aopProxyFactory = new DefaultAopProxyFactory();
    }

    public AopProxyFactory getAopProxyFactory() {
        return this.aopProxyFactory;
    }

    protected final synchronized AopProxy createAopProxy() {
        // ...
        return getAopProxyFactory().createAopProxy(this);
    }
    
}
public interface AopProxy {

    Object getProxy();

    Object getProxy(@Nullable ClassLoader classLoader);

}

public interface AopProxyFactory {

    AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException;

}

public class DefaultAopProxyFactory implements AopProxyFactory, Serializable {

    @Override
    public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
        if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
            Class<?> targetClass = config.getTargetClass();
            if (targetClass == null) {
                throw new AopConfigException("TargetSource cannot determine target class: " +
                        "Either an interface or a target is required for proxy creation.");
            }
            if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
                return new JdkDynamicAopProxy(config);
            }
            return new ObjenesisCglibAopProxy(config);
        }
        else {
            return new JdkDynamicAopProxy(config);
        }
    }

    private boolean hasNoUserSuppliedProxyInterfaces(AdvisedSupport config) {
        Class<?>[] ifcs = config.getProxiedInterfaces();
        return (ifcs.length == 0 || (ifcs.length == 1 && SpringProxy.class.isAssignableFrom(ifcs[0])));
    }

}

 容器中的织入器—ProxyFactoryBean

ProxyFactoryBean本质上是一个生产Proxy的FactoryBean,通过getObject()方法返回代理对象

public Object getObject() throws BeansException {
    initializeAdvisorChain();
    if (isSingleton()) {
        return getSingletonInstance();
    }
    else {
        if (this.targetName == null) {
            logger.warn("Using non-singleton proxies with singleton targets is often undesirable. " +
                    "Enable prototype proxies by setting the 'targetName' property.");
        }
        return newPrototypeInstance();
    }
}

自动代理

Spring AOP自动代理建立的实现建立在IoC容器的BeanPostProcessor概念之上,通过BeanPostProcessor,在遍历容器中所有Bean的基础上,对遍历得到的Bean进行一些操作(当对象实例化时,为其生成代理对象并返回,而不是返回实例化的目标对象本身,从而达到代理对象自动生成的目的)。

for (bean in IoC container)
{
    检查当前bean定义是否符合拦截条件;
    如果符合拦截条件,则
    {
        Object proxy = createProxyFor(bean);
        return proxy;
    }
    否则
    {
        Object instance = createInstance(bean);
        return instance;
    }
}

TargetSource

在使用ProxyFactory的时候,使用setTarget()方法指定具体的目标对象;使用ProxyFactoryBean的时候,使用setTargetName()指定目标对象在IoC容器中的Bean定义的名称。除此之外,还可以通过setTargetSource()来制定具体的目标对象。

在通常情况下,无论是通过setTarget()还是setTargetName()等方法设置的目标对象,框架内部都会通过一个TargetSource实现类对这个目标对象进行封装,也就是说框架内部会以统一的方式来处理调用链重点的目标对象。

每次方法调用都会触发TargetSource的getTarget()方法,getTarget()方法从响应的TargetSource实现类中取得具体的目标对象。这样,就可以控制每次方法调用作用到的具体目标对象:

1. 目标对象池

2. 持有多个目标对象,按照某种规则获取目标对象

3. 只持有一个目标对象

猜你喜欢

转载自www.cnblogs.com/maoshiling/p/9542992.html
今日推荐