之前写过一篇关于Spring容器的文章,对于这块不清楚的童鞋可以移步浏览下。Spring Aop构建于Ioc之上,底层技术手段分别是基于接口的JDK动态代理,和基于类并为其创建子类的cglib动态代理,本文假设读者已经了解了AOP的基础知识。下面,我们将通过实例走一遍完整的流程。
目录
一. 用到的实例代码和配置
二. JDK动态代理
三. 穿插讲下 ProxyFactory
四. cglib动态代理
五. 小结
一、用到的实例代码和配置
接口
package com.example.demo.aop.advice;
/**
* @author linxiaohui
* @version 1.0 2018/10/23
* @since 1.0
*/
public interface Waiter {
void greetTo(String name);
void serviceTo(String name);
}
复制代码
接口实现类
package com.example.demo.aop.advice;
/**
* @author linxiaohui
* @version 1.0 2018/10/23
* @since 1.0
*/
public class KfcWaiter implements Waiter {
@Override
public void greetTo(String name) {
System.out.println("greet to " + name);
}
@Override
public void serviceTo(String name) {
System.out.println("service to " + name);
}
}
复制代码
前置增强
package com.example.demo.aop.advice;
import org.springframework.aop.MethodBeforeAdvice;
import java.lang.reflect.Method;
/**
* @author linxiaohui
* @version 1.0 2018/10/23
* @since 1.0
*/
public class GreetBeforeAdvice implements MethodBeforeAdvice {
@Override
public void before(Method method, Object[] args, Object target) throws Throwable {
System.out.println(method.getName() + "方法执行前,do something");
}
}
复制代码
后置增强
package com.example.demo.aop.advice;
import org.springframework.aop.AfterReturningAdvice;
import java.lang.reflect.Method;
/**
* @author linxiaohui
* @version 1.0 2018/10/29
* @since 1.0
*/
public class GreetAfterAdvice implements AfterReturningAdvice {
@Override
public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
System.out.println(method.getName() + "方法返回后执行。。。");
}
}
复制代码
xml配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- 配置一个前置增强和后置增强 -->
<bean id="greetBeforeAdvice" class="com.example.demo.aop.advice.GreetBeforeAdvice"/>
<bean id="grretAfterAdvice" class="com.example.demo.aop.advice.GreetAfterAdvice"/>
<!-- 需要增强的目标类 -->
<bean id="waiter" class="com.example.demo.aop.advice.KfcWaiter"/>
<!-- 定义两个增强 -->
<bean id="myAdvisor1" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
<property name="patterns" value=".*greet.*"/>
<property name="advice" ref="greetBeforeAdvice"/>
</bean>
<bean id="myAdvisor2" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
<property name="patterns" value=".*greet.*"/>
<property name="advice" ref="grretAfterAdvice"/>
</bean>
<!-- 基于Advisor自动匹配的自动代理创建器 -->
<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator">
<!-- proxyTargetClass=true,使用cglib代理,默认为false -->
<!--<property name="proxyTargetClass" value="true"/>-->
</bean>
</beans>
复制代码
在这里我们使用DefaultAdvisorAutoProxyCreator自动创建代理。我们看下它是个什么玩意
从图谱中我们可以看出,这货居然是个BeanPostProcessor,这是个Bean后置处理器(有需要发评论,可以出一篇描述spring容器的扩展点文章),在spring容器中有描述。执行点是在bean 实例化之后,执行 初始化操作的前后执行。(即容器执行getBean()的时候会执行)。
下面我们从容器的启动阶段开始,到最终生成代理类执行方法结束,完整的走一遍流程,首先,我们先看下jdk动态代理。
二、JDK动态代理
首先,贴上启动程序
package com.example.demo.aop;
import com.example.demo.aop.advice.Waiter;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* @author linxiaohui
* @version 1.0 2018/10/29
* @since 1.0
*/
public class AopSourceCodeTest {
public static void main(String[] args) {
//1、加载配置文件
ApplicationContext ctx = new ClassPathXmlApplicationContext("enhancer.xml");
//2、获取生成的代理类
Waiter waiter = ctx.getBean("waiter", Waiter.class);
//3、执行代理类方法,会执行对应的拦截器方法(执行增强方法)
waiter.greetTo("tom");
}
}
复制代码
由于本文重点讲解AOP的流程,所以spring容器的步骤,我们就在追求精简的同时,也能希望给大家提供一个完整的流程。有不清楚的,可以回到Spring容器看下。
启动容器,我们直接跳到refresh()-->finishBeanFactoryInitialization(beanFactory)-->beanFactory.preInstantiateSingletons(),这里我们只看主要代码(省略了一部分)
@Override
public void preInstantiateSingletons() throws BeansException {
if (this.logger.isDebugEnabled()) {
this.logger.debug("Pre-instantiating singletons in " + this);
}
//获取配置的bean
List beanNames = new ArrayList(this.beanDefinitionNames);
// 循环初始化
for (String beanName : beanNames) {
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
//如果是factoryBean的话,走这个流程(我们这里不管)
if (isFactoryBean(beanName)) {
final FactoryBean factory = (FactoryBean) getBean(FACTORY_BEAN_PREFIX + beanName);
boolean isEagerInit;
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
isEagerInit = AccessController.doPrivileged(new PrivilegedAction() {
@Override
public Boolean run() {
return ((SmartFactoryBean) factory).isEagerInit();
}
}, getAccessControlContext());
}
else {
isEagerInit = (factory instanceof SmartFactoryBean &&
((SmartFactoryBean) factory).isEagerInit());
}
if (isEagerInit) {
getBean(beanName);
}
}
else {
//普通bean走这个流程(看这里,我们重点关注这个)。
//**为了流程效果,我们讲解需要增强的目标类实例化,即waiter**
getBean(beanName);
}
}
}
.....略......
}
复制代码
接下来继续提供流程线路图(省略了方法参数) getBean()-->doGetBean()-->createBean()
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {
if (logger.isDebugEnabled()) {
logger.debug("Creating instance of bean '" + beanName + "'");
}
RootBeanDefinition mbdToUse = mbd;
// Make sure bean class is actually resolved at this point, and
// clone the bean definition in case of a dynamically resolved Class
// which cannot be stored in the shared merged bean definition.
Class resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
// Prepare method overrides.
try {
mbdToUse.prepareMethodOverrides();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
beanName, "Validation of method overrides failed", ex);
}
try {
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
// bean实例化前的处理,这部有可能可以直接生成代理。
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean;
}
}
catch (Throwable ex) {
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
"BeanPostProcessor before instantiation of bean failed", ex);
}
//我们重点看下这一步
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isDebugEnabled()) {
logger.debug("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
复制代码
简单说下,这里列出方法的原因,是为了提一下,resolveBeforeInstantiation()-->applyBeanPostProcessorsBeforeInstantiation-->进入AbstractAutoProxyCreator.postProcessBeforeInstantiation(),我们看下其中的一个判断条件方法,
protected boolean isInfrastructureClass(Class beanClass) {
boolean retVal = Advice.class.isAssignableFrom(beanClass) ||
Pointcut.class.isAssignableFrom(beanClass) ||
Advisor.class.isAssignableFrom(beanClass) ||
AopInfrastructureBean.class.isAssignableFrom(beanClass);
if (retVal && logger.isTraceEnabled()) {
logger.trace("Did not attempt to auto-proxy infrastructure class [" + beanClass.getName() + "]");
}
return retVal;
}
复制代码
这个方法的意思是,用于代理增强的系统基础类,不需要代理,这个时候,满足条件的基础类会被标志为false。下文会用到。 我们继续流程链路doCreateBean()-->initializeBean()-->applyBeanPostProcessorsAfterInitialization()。
protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
//markdown格式问题,把范型尖括号改了
AccessController.doPrivileged(new PrivilegedAction「Object」() {
@Override
public Object run() {
invokeAwareMethods(beanName, bean);
return null;
}
}, getAccessControlContext());
}
else {
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
//执行bean处理器的postProcessBeforeInitialization()方法
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
//执行初始化方法
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
if (mbd == null || !mbd.isSynthetic()) {
//执行bean处理器的postProcessAfterInitialization(),这一步是重点,我们继续往下走
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
复制代码
此处可以看到,我们自动创建代理的DefaultAdvisorAutoProxyCreator已经注册,我们主要关注这个处理器的方法。我们进入AbstractAutoProxyCreator
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (bean != null) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (!this.earlyProxyReferences.contains(cacheKey)) {
//关注这一步,进入方法
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
复制代码
顾名思义,如果有需要,就包装起来,就是处理增强用的
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
if (beanName != null && this.targetSourcedBeans.contains(beanName)) {
return bean;
}
if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
return bean;
}
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
// 获取增强和切面
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
//markdown格式问题,把DONOTPROXY修改成null
if (specificInterceptors != null) {
this.advisedBeans.put(cacheKey, Boolean.TRUE);、
//我们把目光集中到这里
Object proxy = createProxy(
bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
复制代码
protected Object createProxy(
Class beanClass, String beanName, Object[] specificInterceptors, TargetSource targetSource) {
if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
}
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.copyFrom(this);
if (!proxyFactory.isProxyTargetClass()) {
if (shouldProxyTargetClass(beanClass, beanName)) {
proxyFactory.setProxyTargetClass(true);
}
else {
evaluateProxyInterfaces(beanClass, proxyFactory);
}
}
Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
proxyFactory.addAdvisors(advisors);
proxyFactory.setTargetSource(targetSource);
customizeProxyFactory(proxyFactory);
proxyFactory.setFrozen(this.freezeProxy);
if (advisorsPreFiltered()) {
proxyFactory.setPreFiltered(true);
}
return proxyFactory.getProxy(getProxyClassLoader());
}
复制代码
看到这里,大家终于看到了和AOP相关的操作了,没错,他就是由ProxyFactory来处理的。下面,我们简单讲下ProxyFactory,之后,我们再继续jdk动态代理的流程
三、穿插讲下 ProxyFactory
从上文方法中,我们可以看到,createProxy()方法中,大致的步骤就是创建一个ProxyFactory实例,然后设置各种属性之后,最后调用proxyFactory.getProxy(getProxyClassLoader())生成代理类。
public Object getProxy(ClassLoader classLoader) {
return createAopProxy().getProxy(classLoader);
}
复制代码
首先我们看下createAopProxy()
protected final synchronized AopProxy createAopProxy() {
if (!this.active) {
activate();
}
//getAopProxyFactory()返回new DefaultAopProxyFactory()
// 我们在具体看下createAopProxy方法
return getAopProxyFactory().createAopProxy(this);
}
复制代码
从下面的方法中,我们可以看出,根据不同的条件,底层要么使用jdk动态代理,要么使用cglib动态代理
@Override
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
//优化,这个我没用过,书中介绍使用cglib代理 || true的时候用cglib || 目标类只有SpringProxy接口
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);
}
}
复制代码
这里我们就只是简单讲下ProxyFactory(),便于大家理解就行。下面我们分两个小节讲下两个分支,即JdkDynamicAopProxy和ObjenesisCglibAopProxy。首先,我们回到jdk的动态代理话题。
我们来看下JdkDynamicAopProxy如何创建代理
@Override
public Object getProxy(ClassLoader classLoader) {
if (logger.isDebugEnabled()) {
logger.debug("Creating JDK dynamic proxy: target source is " + this.advised.getTargetSource());
}
Class[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
//这一步直接调用jdk反射包创建代理,着重看下第三个参数,this,因为JdkDynamicAopProxy
//实现了InvocationHandler接口,所以当生成的代理类对外服务的时候,会调用本类实现的invoke()方法
return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
}
复制代码
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
MethodInvocation invocation;
Object oldProxy = null;
boolean setProxyContext = false;
//获取目标类
TargetSource targetSource = this.advised.targetSource;
Class targetClass = null;
Object target = null;
try {
//代理的接口没有实现equals方法,并且方法名是equals
if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
// 代理实现equals方法.
return equals(args[0]);
}
else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
// 代理实现hashCode() .
return hashCode();
}
else if (method.getDeclaringClass() == DecoratingProxy.class) {
// There is only getDecoratedClass() declared -> dispatch to proxy config.
return AopProxyUtils.ultimateTargetClass(this.advised);
}
else if (!this.advised.opaque && method.getDeclaringClass().isInterface() &&
method.getDeclaringClass().isAssignableFrom(Advised.class)) {
// Service invocations on ProxyConfig with the proxy config...
return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
}
Object retVal;
// 如果exposeProxy==true
if (this.advised.exposeProxy) {
// 把这个代理放入ThreadLocal中,使其在线程中可见
oldProxy = AopContext.setCurrentProxy(proxy);
setProxyContext = true;
}
// May be null. Get as late as possible to minimize the time we "own" the target,
// in case it comes from a pool.
target = targetSource.getTarget();
if (target != null) {
targetClass = target.getClass();
}
// 获取增强的拦截器链
//markdown格式问题,把范型尖括号修改了
List「Object」 chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
// 如果没有advice,那么不需要增强,直接反射调用方法
if (chain.isEmpty()) {
// We can skip creating a MethodInvocation: just invoke the target directly
// Note that the final invoker must be an InvokerInterceptor so we know it does
// nothing but a reflective operation on the target, and no hot swapping or fancy proxying.
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
}
else {
// 创建一个ReflectiveMethodInvocation
invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
// 通过拦截器链执行连接点的增强方法。我们分析下proceed()
retVal = invocation.proceed();
}
// Massage return value if necessary.
Class returnType = method.getReturnType();
if (retVal != null && retVal == target &&
returnType != Object.class && returnType.isInstance(proxy) &&
!RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
// Special case: it returned "this" and the return type of the method
// is type-compatible. Note that we can't help if the target sets
// a reference to itself in another returned object.
retVal = proxy;
}
else if (retVal == null && returnType != Void.TYPE && returnType.isPrimitive()) {
throw new AopInvocationException(
"Null return value from advice does not match primitive return type for: " + method);
}
return retVal;
}
finally {
if (target != null && !targetSource.isStatic()) {
// Must have come from TargetSource.
targetSource.releaseTarget(target);
}
if (setProxyContext) {
// Restore old proxy.
AopContext.setCurrentProxy(oldProxy);
}
}
}
复制代码
@Override
public Object proceed() throws Throwable {
// We start with an index of -1 and increment early.
// interceptorsAndDynamicMethodMatchers为增强拦截器的数量,这个条件可以确保所有的拦截器执行完之后,再通过
// 反射执行invokeJoinpoint(),即类本身的方法,比如本文中的waiter的greetTo("tom")方法
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
return invokeJoinpoint();
}
// 依次执行增强拦截器(我尝试过修改配置顺序,发现链表的顺序和配置顺序一致,不过这里不影响结果)
Object interceptorOrInterceptionAdvice =
this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
// InterceptorAndDynamicMethodMatcher类型的走这个流程,我们不管
if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
// Evaluate dynamic method matcher here: static part will already have
// been evaluated and found to match.
InterceptorAndDynamicMethodMatcher dm =
(InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
if (dm.methodMatcher.matches(this.method, this.targetClass, this.arguments)) {
return dm.interceptor.invoke(this);
}
else {
// Dynamic matching failed.
// Skip this interceptor and invoke the next in the chain.
return proceed();
}
}
else {
// 我们依次去调用拦截器链的方法,由于本文案例注册了两个拦截器,下文依次给出
// 注意invoke方法中的参数是this,用于从拦截器方法中回来
return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
}
}
复制代码
首先我们看下前置增强的拦截器方法
public class MethodBeforeAdviceInterceptor implements MethodInterceptor, Serializable {
private MethodBeforeAdvice advice;
/**
* Create a new MethodBeforeAdviceInterceptor for the given advice.
* @param advice the MethodBeforeAdvice to wrap
*/
public MethodBeforeAdviceInterceptor(MethodBeforeAdvice advice) {
Assert.notNull(advice, "Advice must not be null");
this.advice = advice;
}
@Override
public Object invoke(MethodInvocation mi) throws Throwable {
//首先执行前置增强方法,这里会跳到我们的前置增强实现类GreetBeforeAdvice,执行before()方法
// 输出 “greetTo方法执行前,do something”
this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis() );
// 然后回到ReflectiveMethodInvocation的proceed方法,继续执行剩下的增强拦截器,看下文
return mi.proceed();
}
}
复制代码
执行后置增强的拦截器方法
public class AfterReturningAdviceInterceptor implements MethodInterceptor, AfterAdvice, Serializable {
private final AfterReturningAdvice advice;
/**
* Create a new AfterReturningAdviceInterceptor for the given advice.
* @param advice the AfterReturningAdvice to wrap
*/
public AfterReturningAdviceInterceptor(AfterReturningAdvice advice) {
Assert.notNull(advice, "Advice must not be null");
this.advice = advice;
}
@Override
public Object invoke(MethodInvocation mi) throws Throwable {
//先执行类本身的方法,即proceed()-->invokeJoinpoint(),通过反射调用目标类KfcWaiter的greetTo(String name)方
//法(tips:这里要多说一句,便于大家理解,因为本文就两个增强拦截器,并且后置增强是最后一个,所以这里会直接执行目标类)
//的方法,如果后置增强拦截器不是最后一个执行,那么该方法会回到ReflectiveMethodInvocation.proceed()继续调用拦截
//器方法。上文中我也提到过,拦截器链虽然按配置顺序排列,但是不影响流程最终的执行顺序)
Object retVal = mi.proceed();
//执行后置增强拦截器的方法,这里会调用我们实现的GreetAfterAdvice,执行afterReturning方法
this.advice.afterReturning(retVal, mi.getMethod(), mi.getArguments(), mi.getThis());
//这里特别说下,后置增强是在目标类方法执行完毕之后执行,但是目标类的执行结果是在后置方法执行完毕后再返回的
return retVal;
}
}
复制代码
好了,到这里,jdk动态代理的流程就讲完了,下面我们一起看下cglib动态代理的流程。这块cglib的底层实现我没有去看过,这里只能带大家看下AOP的流程了,讲的不是那么详细,但是对于理解流程应该是没问题了。
四、cglib动态代理
![ObjenesisCglibAopProxy继承图][image5] 首先我们把xml配置文件中的proxyTargetClass属性设置为true,告诉spring我们要使用cglib来生成代理。 下面我们看下ObjenesisCglibAopProxy的getProxy()方法,由父类CglibAopProxy实现。从下面代码中可以看出,ObjenesisCglibAopProxy主要是创建cglib中的Enhancer,设置相应的属性,然后利用Enhancer生成代理
@Override
public Object getProxy(ClassLoader classLoader) {
if (logger.isDebugEnabled()) {
logger.debug("Creating CGLIB proxy: target source is " + this.advised.getTargetSource());
}
try {
Class<?> rootClass = this.advised.getTargetClass();
Assert.state(rootClass != null, "Target class must be available for creating a CGLIB proxy");
Class<?> proxySuperClass = rootClass;
//如果rootClass是cglib代理生成的子类
if (ClassUtils.isCglibProxyClass(rootClass)) {
//父类
proxySuperClass = rootClass.getSuperclass();
//获取接口
Class<?>[] additionalInterfaces = rootClass.getInterfaces();
for (Class<?> additionalInterface : additionalInterfaces) {
this.advised.addInterface(additionalInterface);
}
}
// Validate the class, writing log messages as necessary.
// 代理前校验
validateClassIfNecessary(proxySuperClass, classLoader);
// 创建并配置Enhancer.
Enhancer enhancer = createEnhancer();
if (classLoader != null) {
enhancer.setClassLoader(classLoader);
if (classLoader instanceof SmartClassLoader &&
((SmartClassLoader) classLoader).isClassReloadable(proxySuperClass)) {
enhancer.setUseCache(false);
}
}
enhancer.setSuperclass(proxySuperClass);
enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));
enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
enhancer.setStrategy(new ClassLoaderAwareUndeclaredThrowableStrategy(classLoader));
//这里,我们要讲下这个getCallbacks()方法,它确认了增强和这些增强的拦截器作为回调
Callback[] callbacks = getCallbacks(rootClass);
//回调的类型
Class<?>[] types = new Class<?>[callbacks.length];
for (int x = 0; x < types.length; x++) {
types[x] = callbacks[x].getClass();
}
// fixedInterceptorMap only populated at this point, after getCallbacks call above
// 回调过滤器,这里就是我们配置两个增强和连接点。各位打断点看下一目了然
enhancer.setCallbackFilter(new ProxyCallbackFilter(
this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset));
enhancer.setCallbackTypes(types);
// Generate the proxy class and create a proxy instance.
return createProxyClassAndInstance(enhancer, callbacks);
}
catch (CodeGenerationException ex) {
throw new AopConfigException("Could not generate CGLIB subclass of class [" +
this.advised.getTargetClass() + "]: " +
"Common causes of this problem include using a final class or a non-visible class",
ex);
}
catch (IllegalArgumentException ex) {
throw new AopConfigException("Could not generate CGLIB subclass of class [" +
this.advised.getTargetClass() + "]: " +
"Common causes of this problem include using a final class or a non-visible class",
ex);
}
catch (Throwable ex) {
// TargetSource.getTarget() failed
throw new AopConfigException("Unexpected AOP exception", ex);
}
}
复制代码
复制代码
复制代码
private Callback[] getCallbacks(Class rootClass) throws Exception {
// 一些优化参数,这里可以忽略
boolean exposeProxy = this.advised.isExposeProxy();
boolean isFrozen = this.advised.isFrozen();
boolean isStatic = this.advised.getTargetSource().isStatic();
// 选择DynamicAdvisedInterceptor作为aop拦截器,执行回调方法
Callback aopInterceptor = new DynamicAdvisedInterceptor(this.advised);
// Choose a "straight to target" interceptor. (used for calls that are
// unadvised but can return this). May be required to expose the proxy.
Callback targetInterceptor;
if (exposeProxy) {
targetInterceptor = isStatic ?
new StaticUnadvisedExposedInterceptor(this.advised.getTargetSource().getTarget()) :
new DynamicUnadvisedExposedInterceptor(this.advised.getTargetSource());
}
else {
targetInterceptor = isStatic ?
new StaticUnadvisedInterceptor(this.advised.getTargetSource().getTarget()) :
new DynamicUnadvisedInterceptor(this.advised.getTargetSource());
}
// Choose a "direct to target" dispatcher (used for
// unadvised calls to static targets that cannot return this).
Callback targetDispatcher = isStatic ?
new StaticDispatcher(this.advised.getTargetSource().getTarget()) : new SerializableNoOp();
//返回各种拦截器
Callback[] mainCallbacks = new Callback[] {
aopInterceptor, // for normal advice
targetInterceptor, // invoke target without considering advice, if optimized
new SerializableNoOp(), // no override for methods mapped to this
targetDispatcher, this.advisedDispatcher,
new EqualsInterceptor(this.advised),
new HashCodeInterceptor(this.advised)
};
Callback[] callbacks;
// If the target is a static one and the advice chain is frozen,
// then we can make some optimizations by sending the AOP calls
// direct to the target using the fixed chain for that method.
if (isStatic && isFrozen) {
Method[] methods = rootClass.getMethods();
Callback[] fixedCallbacks = new Callback[methods.length];
//markdown格式问题,把尖括号修改了
this.fixedInterceptorMap = new HashMap「String, Integer」(methods.length);
// TODO: small memory optimization here (can skip creation for methods with no advice)
for (int x = 0; x < methods.length; x++) {
//markdown格式问题,把尖括号修改了
List「Object」 chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(methods[x], rootClass);
fixedCallbacks[x] = new FixedChainStaticTargetInterceptor(
chain, this.advised.getTargetSource().getTarget(), this.advised.getTargetClass());
this.fixedInterceptorMap.put(methods[x].toString(), x);
}
// Now copy both the callbacks from mainCallbacks
// and fixedCallbacks into the callbacks array.
callbacks = new Callback[mainCallbacks.length + fixedCallbacks.length];
System.arraycopy(mainCallbacks, 0, callbacks, 0, mainCallbacks.length);
System.arraycopy(fixedCallbacks, 0, callbacks, mainCallbacks.length, fixedCallbacks.length);
this.fixedInterceptorOffset = mainCallbacks.length;
}
else {
callbacks = mainCallbacks;
}
return callbacks;
}
复制代码
![回到启动类]tips:由于base64文件太大了,文章保存不下,这张图片就不显示了
我们看到从容器中获取的waiter实例已经是经过cglib代理后生成的类。执行waiter.greetTo("tom")方法,会执行上文中注册的DynamicAdvisedInterceptor拦截器的方法intercept()。大家有没有发现逻辑简直跟上面讲解jdk的动态代理回调时候一模一样。
@Override
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
Object oldProxy = null;
boolean setProxyContext = false;
Class targetClass = null;
Object target = null;
try {
if (this.advised.exposeProxy) {
// Make invocation available if necessary.
oldProxy = AopContext.setCurrentProxy(proxy);
setProxyContext = true;
}
// May be null. Get as late as possible to minimize the time we
// "own" the target, in case it comes from a pool...
target = getTarget();
if (target != null) {
targetClass = target.getClass();
}
//获取拦截器链
//markdown格式问题,把尖括号修改了
List「Object」 chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
Object retVal;
// 无拦截器,直接通过反射调用方法
if (chain.isEmpty() && Modifier.isPublic(method.getModifiers())) {
// We can skip creating a MethodInvocation: just invoke the target directly.
// Note that the final invoker must be an InvokerInterceptor, so we know
// it does nothing but a reflective operation on the target, and no hot
// swapping or fancy proxying.
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
retVal = methodProxy.invoke(target, argsToUse);
}
else {
// 创建并执行MethodInvocation的proceed()方法。CglibMethodInvocation是
// ReflectiveMethodInvocation的子类,执行步骤和上文讲jdk代理的流程一样了,就
// 不重复唠叨了
retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();
}
retVal = processReturnType(proxy, target, method, retVal);
return retVal;
}
finally {
if (target != null) {
releaseTarget(target);
}
if (setProxyContext) {
// Restore old proxy.
AopContext.setCurrentProxy(oldProxy);
}
}
}
复制代码
五、小结
由于我刚开始用markdown,对本文代码中冲突的尖括号都特殊处理了,并由标注指出,敬请见谅。本文主要是和大家一起了解下AOP的源码实现流程,对于cglib等底层实现没有涉猎。后续我如果有需求要啃cglib的源码,那么对应的文章也会分享给大家。有什么讲解错误的,希望大家在评论区不吝指正。?