前面我们已经对MethodInterceptor,advice等类给出了介绍,并给出了具体的实现,接下来的问题时框架如何知道用户启动aop换句话说 ,框架如何知道用户能够对方法启动了代理,答案就是注解,这里借助一个beanPostProcessor+java注解(EnableAop,interceptorAdvice前面已经做了介绍,这里不再重复)的方式来实现,利用beanPostProcessor的作用拦截所有bean对启动aop功能的进行代理,具体实现如下
package com.support;
import com.MethodConfig;
import com.annotations.EnableAop;
import com.annotations.InterceptorAdvice;
import com.autoproxy.JDKDynamicProxy;
import org.aopalliance.aop.Advice;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component;
import java.lang.reflect.Method;
/**
* Created by zoujianglin
* 2018/8/29 0029.
*/
@Component
public class AopBeanPostProcessor implements BeanPostProcessor {
public Object postProcessBeforeInitialization(Object bean, String s) throws BeansException {
return bean;
}
public Object postProcessAfterInitialization(Object bean, String s) throws BeansException {
if (bean.getClass().isAnnotationPresent(EnableAop.class)) {
EnableAop enableAop = bean.getClass().getAnnotation(EnableAop.class);
Class<? extends Advice>[] enableAopAdvice = enableAop.advices();
AopSupport aopSupport = new AopSupport();
Method[] methods = bean.getClass().getDeclaredMethods();
for (int i = 0; i < methods.length; i++) {
//如果是object的方法如equals,wait等,跳过,这里有待考虑需不需要跳过,
if (Object.class.equals(methods[i].getDeclaringClass())) {
continue;
}
if (methods[i].isAnnotationPresent(InterceptorAdvice.class)) {
InterceptorAdvice interceptorAdvice = methods[i].getAnnotation(InterceptorAdvice.class);
Class<? extends Advice>[] advices = interceptorAdvice.advices();
MethodConfig methodConfig = new MethodConfig(bean, methods[i], advices);
if (enableAopAdvice != null && enableAopAdvice.length > 0) {
methodConfig.addMethodInterceptorsByAdviceClass(enableAopAdvice);
}
aopSupport.addMethodConfig(methods[i].getName(), methodConfig);
}
}
aopSupport.addInterfaces(bean.getClass().getInterfaces());
aopSupport.setTarget(bean);
return new JDKDynamicProxy(aopSupport).getProxy();
} else {
return bean;
}
}
}
在上面的类中涉及到3个重要的类 分别为aopSupport,methodConfig,JDKDynamicProxy
这里对这3个类的作用做一个简要的介绍
MethodConfig:保存的某个方法的一些配置信息,如方法上的拦截器,方法所属对象等等
AopSupport:保存着被代理类的配置信息,如被代理的对象,被代理的接口等等
JDKDynamicProxy:则是用来生成代理类
首先看methodConfig的具体实现
package com;
import com.util.AdviceUtil;
import com.util.Assert;
import org.aopalliance.aop.Advice;
import org.aopalliance.intercept.MethodInterceptor;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
/**
* Created by zoujianglin
* 2018/8/29 0029.
* 保持着被代理的方法的配置
*/
public class MethodConfig {
private Object target; //被代理的目标对象
private Method method; //被代理的方法
private List<MethodInterceptor> methodInterceptors; //方法拦截器
public MethodConfig(Object target, Method method, Class<? extends Advice>[] advices) {
Assert.notNull(method, "被代理的方法不能为空");
Assert.notNull(target, "代理对象不能为空");
this.target = target;
this.method = method;
methodInterceptors = new ArrayList<MethodInterceptor>();
addMethodInterceptorsByAdviceClass(advices);
}
public MethodConfig(Object target, Method method, List<MethodInterceptor> methodInterceptors) {
Assert.notNull(method, "被代理的方法不能为空");
Assert.notNull(target, "代理对象不能为空");
this.target = target;
this.method = method;
this.methodInterceptors = methodInterceptors;
}
public Object getTarget() {
return target;
}
public void setTarget(Object target) {
this.target = target;
}
public Method getMethod() {
return method;
}
public void setMethod(Method method) {
this.method = method;
}
public List<MethodInterceptor> getMethodInterceptors() {
return methodInterceptors;
}
public void setMethodInterceptors(List<MethodInterceptor> methodInterceptors) {
this.methodInterceptors = methodInterceptors;
}
public void addMethodInterceptors(MethodInterceptor m) {
methodInterceptors.add(m);
}
public MethodInterceptor getOneMethodInterceptorByAdviceClass(Class<? extends Advice> adviceClass) {
Advice advice = null;
try {
advice = adviceClass.newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
MethodInterceptor methodInterceptor = AdviceUtil.getMethodInterceptor(advice);
return methodInterceptor;
}
public void addMethodInterceptorsByAdviceClass(Class<? extends Advice> adviceClass) {
MethodInterceptor methodInterceptor = getOneMethodInterceptorByAdviceClass(adviceClass);
Assert.notNull(methodInterceptor, "请确保" + adviceClass + "为正确类型");
methodInterceptors.add(methodInterceptor);
}
public void addMethodInterceptorsByAdviceClass(Class<? extends Advice>[] advices) {
for (int i = 0; i < advices.length; i++) {
MethodInterceptor methodInterceptor = getOneMethodInterceptorByAdviceClass(advices[i]);
methodInterceptors.add(methodInterceptor);
}
}
/*
public List<MethodInterceptor> getMethodInterceptorsByAdvicesClass(Class<? extends Advice>[] advices) {
for (int i = 0; i < advices.length; i++) {
Advice advice = null;
try {
advice = advices[i].newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
MethodInterceptor methodInterceptor = AdviceUtil.getMethodInterceptor(advice);
Assert.notNull(methodInterceptor, "请确保" + advice + "为正确类型");
methodInterceptors.add(methodInterceptor);
}
return methodInterceptors;
}
*/
}
其中涉及到的AdviceUtil 实现如下
package com.util;
import com.autoproxy.Adapter.AdviceAdapter;
import com.autoproxy.Adapter.AfterReturningAdviceAdapter;
import com.autoproxy.Adapter.MethodBeforeAdviceAdapter;
import org.aopalliance.aop.Advice;
import org.aopalliance.intercept.MethodInterceptor;
import java.util.ArrayList;
import java.util.List;
/**
* Created by zoujianglin
* 2018/8/29 0029.
*/
public class AdviceUtil {
private static List<AdviceAdapter> adviceAdapters;
static {
//注册适配器
adviceAdapters = new ArrayList<AdviceAdapter>();
adviceAdapters.add(new MethodBeforeAdviceAdapter());
adviceAdapters.add(new AfterReturningAdviceAdapter());
}
/**
* 使用第一个符合条件的适配器进行适配,并返回相应拦截器
*
* @param advice
* @return
*/
public static MethodInterceptor getMethodInterceptor(Advice advice) {
for (int i = 0; i < adviceAdapters.size(); i++) {
AdviceAdapter adviceAdapter = adviceAdapters.get(i);
if (adviceAdapter.supportsAdvice(advice)) {
return adviceAdapter.getInterceptor(advice);
}
}
return null;
}
public static void registerAdapter(AdviceAdapter adviceAdapter) {
adviceAdapters.add(adviceAdapter);
}
}
另外两个类,我会在下篇博客中进行讲解