上一遍文章研究了Spring AOP实现源码,现在自己也想自己实现。
假如要对以下接口BarService织入Before增强和After增强
接口定义
public interface BarService {
void doSomething();
}
接口实现
@Service
public class BarServiceImp implements BarService {
@Override
public void doSomething() {
System.out.println("执行原有业务逻辑...");
}
}
定义注解MyAspect
这个注解必须用@Component定义,因为它也是个Bean,需要Spirng管理
@Component
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface MyAspect {
String pointCut() default "";
}
MyAspect使用
MyAspect指定拦截FooServiceImp的add方法
@MyAspect(pointCut = "com.ydoing.spring.core.aop.customized.FooServiceImp.add")
public class MyLogAspect {
public void before(Object[] args) {
System.out.println("before增强,args[0]:" + args[0] + ", args[1]:" + args[1]);
}
public void after(Object[] args) {
System.out.println("after增强,args[0]:" + args[0] + ", args[1]:" + args[1]);
}
}
定义增强Advisor
public interface Advisor extends MethodInterceptor, Orderable{
boolean isMatch(Class<?> clazz, Method method);
}
Advisor本质上是个拦截器
public interface MethodInterceptor {
Object invoke(MethodInvocation methodInvocation) throws Throwable;
}
Orderable接口是用来排序
public interface Orderable {
int getOrder();
}
一般接口都用骨架类实现,建议Abstract前缀命名,这里我们Advisor的默认实现为AbstractAdvisor
public abstract class AbstractAdvisor implements Advisor {
protected int order = 0;
protected Pattern pattern;
protected Object aopObj;
protected Method aopMethod;
public AbstractAdvisor(Object aopObj, Method aopMethod) {
this.aopObj = aopObj;
this.aopMethod = aopMethod;
String reg = aopObj.getClass().getAnnotation(MyAspect.class).pointCut();
this.pattern = Pattern.compile(reg);
}
@Override
public int getOrder() {
return order;
}
public void setOrder(int order) {
this.order = order;
}
@Override
public boolean isMatch(Class<?> clazz, Method method) {
return pattern.matcher(clazz.getName() + "." + method.getName()).find();
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
AbstractAdvisor that = (AbstractAdvisor) o;
return Objects.equals(aopObj, that.aopObj) &&
Objects.equals(aopMethod, that.aopMethod);
}
@Override
public int hashCode() {
return Objects.hash(aopObj, aopMethod);
}
}
Before增强
主要直接继承AbstractAdvisor,覆盖invoke方法即可
public class BeforeAdvisor extends AbstractAdvisor {
public BeforeAdvisor(Object aopObj, Method aopMethod) {
super(aopObj, aopMethod);
setOrder(1);
}
@Override
public Object invoke(MethodInvocation methodInvocation) throws Throwable {
Object[] args = {methodInvocation.getArguments()};//将Object[]转为数组,不然报错
aopMethod.invoke(aopObj, args);
return methodInvocation.proceed();
}
}
After增强
与Before增强实现类似
public class AfterAdvisor extends AbstractAdvisor {
public AfterAdvisor(Object aopObj, Method aopMethod) {
super(aopObj, aopMethod);
setOrder(2);
}
@Override
public Object invoke(MethodInvocation methodInvocation) throws Throwable {
Object result = methodInvocation.proceed();
Object[] args = {methodInvocation.getArguments()};//将Object[]转为数组,不然报错
aopMethod.invoke(aopObj, args);
return result;
}
}
BeanPostProcessor扩展
上一遍文章讲到,AOP实现扩展了BeanPostProcessor,在Bean实例化后对Bean进行代理
@Component
public class MyAspectBeanPostProcessor implements BeanPostProcessor, ApplicationContextAware {
private ApplicationContext applicationContext;
private List<Advisor> cacheAdvisors;//缓存提升性能
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
buildAdvisors();//构建增强
Map<Method, List<Advisor>> methodListMap = getMatchAdvisor(bean);
if (methodListMap.isEmpty())
return bean;
Enhancer enhancer = new Enhancer();//创建代理
enhancer.setSuperclass(bean.getClass());
enhancer.setCallback(new MethodInterceptorImp(methodListMap));
return enhancer.create();
}
private void buildAdvisors() {
if (cacheAdvisors != null) {
return;
}
if (cacheAdvisors == null) {
cacheAdvisors = new ArrayList<>();
}
Map<String, Object> map = applicationContext.getBeansWithAnnotation(MyAspect.class);
for (Map.Entry<String, Object> entry : map.entrySet()) {
Object aopObj = entry.getValue();
Method[] methods = aopObj.getClass().getMethods();
for (Method method : methods) {
if (method.getName().equals("before")) {
Advisor advisor = new BeforeAdvisor(aopObj, method);
if (!cacheAdvisors.contains(advisor))
cacheAdvisors.add(advisor);
} else if (method.getName().equals("after")) {
Advisor advisor = new AfterAdvisor(aopObj, method);
if (!cacheAdvisors.contains(advisor))
cacheAdvisors.add(advisor);
}
}
}
}
private Map<Method, List<Advisor>> getMatchAdvisor(Object bean) {
Class<?> clazz = bean.getClass();
Method[] methods = clazz.getMethods();
Map<Method, List<Advisor>> methodListMap = new HashMap<>();
for (Method method : methods) {
for (Advisor advisor : cacheAdvisors) {
if (advisor.isMatch(clazz, method)) {
List<Advisor> advisors = methodListMap.get(method);
if (advisors == null) {
advisors = new ArrayList<>();
methodListMap.put(method, advisors);
}
advisors.add(advisor);
}
}
}
return methodListMap;
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
}
Enhancer的回调实现
public class MethodInterceptorImp implements MethodInterceptor {
private Map<Method, List<Advisor>> methodListMap;
public MethodInterceptorImp(Map<Method, List<Advisor>> methodListMap) {
this.methodListMap = methodListMap;
}
@Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
List<Advisor> advisors = methodListMap.get(method);
if (advisors == null){
return proxy.invokeSuper(obj, args);
}
Collections.sort(advisors, new Comparator<Advisor>() {
@Override
public int compare(Advisor o1, Advisor o2) {
return o2.getOrder() - o1.getOrder();
}
});
MethodInvocation methodInvocation = new MethodInvocation(obj, method, args, proxy, advisors);
return methodInvocation.proceed();
}
}
链式调用
MethodInvocation主要是封装多个Advisor,形成递归链式调用
public class MethodInvocation implements Proceed{
private Object target;
private Method method;
private Object[] arguments;
private MethodProxy methodProxy;
private List<Advisor> advisors;
public MethodInvocation(Object target, Method method, Object[] arguments, MethodProxy proxy, List<Advisor> advisors) {
this.target = target;
this.method = method;
this.arguments = arguments;
this.methodProxy = proxy;
this.advisors = advisors;
}
private int currentInterceptorIndex = -1;
@Override
public Object proceed() throws Throwable {
if (currentInterceptorIndex == advisors.size() - 1){
return methodProxy.invokeSuper(target, arguments);
}
++currentInterceptorIndex;
Advisor advisor = advisors.get(currentInterceptorIndex);
return advisor.invoke(this);
}
public Object[] getArguments() {
return arguments;
}
}
Proceed接口
public interface Proceed {
Object proceed() throws Throwable;
}
测试
Spring的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"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/
<context:component-scan base-package="com.ydoing.spring.core.aop.customized"/>
</beans>
测试运行
public class App {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
FooService service = context.getBean(FooService.class);
service.add(1, 2);
}
}
输出
before增强,args[0]:1, args[1]:2
原有业务逻辑,result:3
after增强,args[0]:1, args[1]:2