上一遍文章研究了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