思考:springAOP底层运用了什么设计模式?
生成代理类:代理设计模式、底层五个通知形成调用链采用:责任链设计模式
下面我们回顾下SpringAop实现流程:
1、配置@EnableAspectJAutoProxy 2、@Import(AspectJAutoProxyRegistrar.class)往IOC容器中注入SpringAOP切面类 3、registerAspectJAnnotationAutoProxyCreatorIfNecessary()注册切面类 4、AnnotationAwareAspectJAutoProxyCreator.class注册到IOC容器中,【AOP的入口】 5、postProcessAfterInitialization 6、wrapIfNecessary()判断该对象是否在AOP的扫包范围内 7、createAopProxy()判断被代理类是否实现了接口,如果有实现了接口的化,是采用JDK动态代理,否则情况下就使用CGLIB代理 8、使用JdkDynamicAopProxy()方法实现代理类 9、最终执行目标方法的时候,就会进入到JdkDynamicAopProxy 的invoke()方法 10、底层使用集合存放使用通知,然后再使用责任链设计模式循环的调用
如果调用了目标方法,则最终进入invoke方法
SpringBean的生命周期
主要靠的是后置处理器BeanPostProcessor:在Bean对象初始化前后做一些增强 AnnotationAwareAspectJAutoProxyCreator的祖宗是BeanPostProcessor
【0】环绕通知之前执行→【1】前置通知→目标方法→【2】后置通知→【3】环绕通知之后执行 责任链设计模式,底层通过递归算法+责任链 如何存放起来:使用集合存放这些通知,集合当中不存放我们的方法,只存放链,那么如何插入我们的目标方法?
MethodInterceptor 接口
public interface MethodInterceptor {
/**
* 定义共同通知骨架
*/
public void invoke(MethodInvocation methodInvocation) throws InvocationTargetException, IllegalAccessException;
}
BeforMethodInterceptor 前置通知
public class BeforMethodInterceptor implements MethodInterceptor {
public void invoke(MethodInvocation methodInvocation) throws InvocationTargetException, IllegalAccessException {
System.out.println(">>>>前置通知<<<<");
// 执行我们的目标方法
methodInvocation.process();// 递归调用
}
}
AfterMethodInterceptor后置通知
public class AfterMethodInterceptor implements MethodInterceptor {
public void invoke(MethodInvocation methodInvocation) throws InvocationTargetException, IllegalAccessException {
// 执行我们的前置通知
methodInvocation.process();
System.out.println(">>>后置通知<<<");
}
}
AroundMethodInterceptor 环绕通知
public class AroundMethodInterceptor implements MethodInterceptor {
public void invoke(MethodInvocation methodInvocation) throws InvocationTargetException, IllegalAccessException {
System.out.println("环绕通知在目标方法之前执行..");
methodInvocation.process();
System.out.println("环绕通知在目标方法之后执行..");
}
}
UserService
public class UserService {
public void login(String userName, Integer age) {
System.out.println("userName:" + userName + ",age:" + age);
}
}
MethodInvocation 能够把链串起来
public interface MethodInvocation {
//调用链形成
public void process() throws InvocationTargetException, IllegalAccessException;
}
DefaultMethodInvacation 实现通知串起来
public class DefaultMethodInvacation implements MethodInvocation {
/**
* 存放所有的通知
*/
private List<MethodInterceptor> listMethodInterceptor;
private Object target;// 目标对象
private Method method;// 目标方法
private Object args[];// 目标参数
// 最终使用反射机制执行目标方法
private int index;// 记录当前链调用的位置
public DefaultMethodInvacation(List<MethodInterceptor> listMethodInterceptor, Object target, Method method, Object[] args) {
this.listMethodInterceptor = listMethodInterceptor;
this.target = target;
this.method = method;
this.args = args;
}
/**
* 调用链形成
*/
@Override
public void process() throws InvocationTargetException, IllegalAccessException {
if (index == listMethodInterceptor.size()) {
method.invoke(target, args); // 执行目标
return;
}
MethodInterceptor methodInterceptor = listMethodInterceptor.get(index++);
methodInterceptor.invoke(this);
}
}
执行结果:
>>>>前置通知<<<< 环绕通知在目标方法之前执行.. userName:mayikt,age:12 环绕通知在目标方法之后执行.. >>>后置通知<<<
下面我们看下源码是如何实现的
入口:
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MyConfig.class);
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);
// Instantiate all remaining (non-lazy-init) singletons.
beanFactory.preInstantiateSingletons();
if (isEagerInit) {
this.getBean(beanName);
}
public Object getBean(String name) throws BeansException {
return this.doGetBean(name, (Class)null, (Object[])null, false);
}
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = this.applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return proxyFactory.getProxy(this.getProxyClassLoader());
public Object getProxy(@Nullable ClassLoader classLoader) {
return this.createAopProxy().getProxy(classLoader);
}
执行目标方面会进入invoke()方法
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
...
try {
....
} else {
MethodInvocation invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
retVal = invocation.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) {
InterceptorAndDynamicMethodMatcher dm = (InterceptorAndDynamicMethodMatcher)interceptorOrInterceptionAdvice;
return dm.methodMatcher.matches(this.method, this.targetClass, this.arguments) ? dm.interceptor.invoke(this) : this.proceed();
} else {
return ((MethodInterceptor)interceptorOrInterceptionAdvice).invoke(this);
}
}
}
这里就是那五个通知后面还有个TransactionInterceptor,后面会分析它
本文参考