AOP相关概念
advice 通知: 定义在切入点织入的行为逻辑(常用device有 BeforeDevice,AfterDevice,ThorwsDevice)
pointcut 切点:决定Advice通知应该作用于那个连接点,也就是说通过Pointcut切点来定义需要增强的方法的集合
通过观察Pointcut类的继承关系(向下关系),在Point cut的基本接口定义中可以看到,需要返回一个MethodMatcher;对于Point的匹配判断,具体是有这个返回的MethodMatcher来完成。
Advisor 通知器
当我们完成对目标方法的切面增强设计和关注点的设计后,需要一个对象把他们集合起来,完成这个作用的就是Advisor。
在Spring AOP中常用的Devisor为DefaultPointcutAdvisor
Interceptor 拦截器:
Target 目标对象:被一个或者多个切面所通知的对象。也被称做被通知(advised)对象。 既然Spring AOP是通过运行时代理实现的,这个对象永远是一个被代理(proxied)对象。
Proxy 代理对象:AOP框架创建的对象,用来实现切面契约(例如通知方法执行等等)。在Spring中,AOP代理可以是JDK动态代理或者CGLIB代理。
Introduction 引入:
Weaving 织入:把切面连接到其它的应用程序类型或者对象上,并创建一个被通知的对象。这些可以在编译时(例如使用AspectJ编译器),类加载时和运行时完成。Spring和其他纯Java AOP框架一样,在运行时完成织入。
--------------------------------------------------------------------------------------------------------------------------------
|接下来我们通过ProxyFactoryBean来深入分析Spring如何通过JDK动态代理实现AOP
--------------------------------------------------------------------------------------------------------------------------------
1、ProxyFactoryBean类是一个FactoryBean的Bean,也实现了BeanFactoryAware,因此在Spring初始化ProxyFactoryBean Bean的
实例时,会将Spring的BeanFactory通过setBeanFactory(BeanFactory beanFactory) 赋值给beanFactory属性
2、由于ProxyFactoryBean是一个FactoryBean,因此提供了一个getObject()的Bean获取方法,通过此方法获取Bean的实例
一、首先会初始化通知器链AdvisorChain,通过this.initializeAdvisorChain();方法初始化
我们进入this.initializeAdvisorChain();方法内部分析通过什么样的规则初始化通知器链,ProxyFactoryBean有个advisorChainInitialized属性标识通知器链是否已经初始化,如果已经初始化了,则直接返回
通过解析interceptorNames指定的值获取通知器链,this.addAdvisorOnChainCreation(advice, name)
调用了DefaultAdvisorAdapterRegistry.wrap()
public Advisor wrap(Object adviceObject) throws UnknownAdviceTypeException {
//如果为Advisor则直接返回
if (adviceObject instanceof Advisor) {
return (Advisor)adviceObject;
} else if (!(adviceObject instanceof Advice)) {
//不是Advisor也不是Advice类型,则直接抛出未知的AdviceType异常
throw new UnknownAdviceTypeException(adviceObject);
} else {
//
Advice advice = (Advice)adviceObject;
if (advice instanceof MethodInterceptor) {
//如果为MethodInterceptor,则创建DefaultPointcutAdvisor实例封装
return new DefaultPointcutAdvisor(advice);
} else {
Iterator var3 = this.adapters.iterator();
AdvisorAdapter adapter;
do {
if (!var3.hasNext()) {
throw new UnknownAdviceTypeException(advice);
}
adapter = (AdvisorAdapter)var3.next();
//检查指定的Advice是否注册了可支持的Adapter适配器
} while(!adapter.supportsAdvice(advice));
//创建DefaultPointcutAdvisor实例封装
return new DefaultPointcutAdvisor(advice);
}
}
}
下一步添加到Advisor链列表中
private void addAdvisorOnChainCreation(Object next, String name) {
Advisor advisor = this.namedBeanToAdvisor(next);
if (this.logger.isTraceEnabled()) {
this.logger.trace("Adding advisor with name '" + name + "'");
}
//添加到Advisor链列表中
this.addAdvisor(advisor);
}
二、通知器链初始化完后,获取Bean实例
public Object getObject() throws BeansException {
//初始化通知器链
this.initializeAdvisorChain();
//判断是否是单例
if (this.isSingleton()) {
return this.getSingletonInstance();
} else {
if (this.targetName == null) {
this.logger.warn("Using non-singleton proxies with singleton targets is often undesirable. Enable prototype proxies by setting the 'targetName' property.");
}
//非单例
return this.newPrototypeInstance();
}
}
private synchronized Object getSingletonInstance() {
if (this.singletonInstance == null) {
this.targetSource = this.freshTargetSource();
if (this.autodetectInterfaces && this.getProxiedInterfaces().length == 0 && !this.isProxyTargetClass()) {
Class> targetClass = this.getTargetClass();
if (targetClass == null) {
throw new FactoryBeanNotInitializedException("Cannot determine target class for proxy");
}
this.setInterfaces(ClassUtils.getAllInterfacesForClass(targetClass, this.proxyClassLoader));
}
super.setFrozen(this.freezeProxy);
//获取代理实例
this.singletonInstance = this.getProxy(this.createAopProxy());
}
return this.singletonInstance;
}
判断使用JDK动态代理还是CGLIB代理,得到AopProxy对象后,通过调用AopProxy.getProxy()方法就能得到代理对象,以
JDKDynamicAopProxy为例,调用getProxy(),在此方法中我们就能看到我们非常眼熟的
Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);JDK动态代理创建代理对象的代码
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
if (!config.isOptimize() && !config.isProxyTargetClass() && !this.hasNoUserSuppliedProxyInterfaces(config)) {
//目标类为接口,则使用JDK动态代理
return new JdkDynamicAopProxy(config);
} else {
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.");
} else {
return (AopProxy)(targetClass.isInterface() ? new JdkDynamicAopProxy(config) : new ObjenesisCglibAopProxy(config));
}
}
}
三、有了代理对象以后,当调用代理对象的方法时则会被增强,重点分析JdkDynamicAopProxy.invoke()方法,处理回调
//创建拦截器列表
List
if (chain.isEmpty()) {
//如果没有配置通知器链,则直接调用目标方法
}
创建拦截器列表有 DefaultPointcutAdvisor 来负责,具体逻辑如下:
public List
调用ReflectiveMethodInvocation.proceed()函数迭代调用拦截器,直到拦截器链中的拦截器都完成拦截过程为止
public Object proceed() throws Throwable {
//拦截器为最后一个,则直接调用目标方法
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
return this.invokeJoinpoint();
} else {
Object interceptorOrInterceptionAdvice = this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
//检查拦截器的切入点是否匹配调用方法,如果匹配则调用拦截器的invoke(),如果不匹配则递归调用proceed()函数,直到所有拦截器都被运行过为止
InterceptorAndDynamicMethodMatcher dm = (InterceptorAndDynamicMethodMatcher)interceptorOrInterceptionAdvice;
return dm.methodMatcher.matches(this.method, this.targetClass, this.arguments) ? dm.interceptor.invoke(this) : this.proceed();
} else {
//直接调用拦截器invoke()
return ((MethodInterceptor)interceptorOrInterceptionAdvice).invoke(this);
}
}
}
~~~~到目前为止,就分析完了!