《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. 只持有一个目标对象
posted on 2018-08-30 11:34 maoshiling 阅读(348) 评论(0) 编辑 收藏 举报