欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2022-12-24 11:10:27
AOP中的Jointpoint有很多中,如 构造方法调用、字段的设置与读取、方法调用、方法执行等,在Spring AOP中,Jointpoint仅支持方法级别的Jointpoint,更确切的说是,只支持方法执行(Method ExeCution)类型的Jointpoint。 Pointcut Adv ......

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; }

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

 

 

 

 

 

 

 

 

 

 

 

 

advice

 

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

advisor

spring中没有完全明确的aspect的概念,advisor相当于spring中的aspect,但是advisor通常只有一个pointcut和一个advice

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

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])));
    }

}

 

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

 

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

 容器中的织入器—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. 只持有一个目标对象