《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. 只持有一个目标对象
上一篇: C++数字三角形问题与dp算法
下一篇: pyhon-----获取ip的两种方法