为了更好的理解Spring内核,手动编写一个简易版AOP。
至于AOP概念请自行百度,接下来进入正题
先写一个演示用的类NormalClass,给该类添加拦截器,并用该类的代理调用niemalAction方法的过程中拦截。
package com.mec.aop.model;
public class NormalClass {
public NormalClass() {
}
public String normalAction(String str) {
System.out.println(str);
return str;
}
}
本例分为3层实现,第一层ProxyFactory,负责产生proxy代理。为了简便,此处仅实现CGLib示例。
package com.mec.aop.core;
import java.lang.reflect.Method;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
public class ProxyFactory {
private YcProxy ycProxy;
public ProxyFactory() {
}
public YcProxy getYcProxy() {
return ycProxy;
}
public void setYcProxy(YcProxy ycProxy) {
this.ycProxy = ycProxy;
}
protected <T> T getCGLProxy(Class<?> klass, Object object) {
T proxy = cglProxy(klass, object);
ycProxy = new YcProxy();
ycProxy.setProxy(proxy);
return proxy;
}
@SuppressWarnings("unchecked")
private <T> T cglProxy(Class<?> klass, Object object) {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(klass);
enhancer.setCallback(new MethodInterceptor() {
@Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
return doInvoke(object, method, args);
}
});
return (T) enhancer.create();
}
@SuppressWarnings("unchecked")
private <T> T doInvoke(Object object, Method method, Object[] args) {
Object result = null;
//置前拦截
ycProxy.dobefore(method, args);
try {
result = method.invoke(object, args);
//滞后拦截
ycProxy.doafter(method, result);
} catch (Throwable e) {
//异常拦截
ycProxy.dodealException(method, e);
e.printStackTrace();
}
return (T) result;
}
}
第二层YcProxy,负责产生代理类的对象。每一个代理类中包含一个代理,以及与其对应的一套拦截器链。
在该类中主要实现添加和删除拦截器,以及代理的getter和setter方法以备用。还有拦截时调用的三个方法。通过遍历装有拦截器的List,使每一个拦截器均可在方法被调用时起作用。这三个方法的实质是调用的了拦截器类中的抽象方法,此方法留做接口,以便用户将来在拦截时进行操作。
YcProxy类:
/*
* @auther: yc
* time: 2018/10/16
*/
package com.mec.aop.core;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
public class YcProxy {
private Object proxy;
private List<YcIntercepter> ycIntercepters;
public YcProxy() {
ycIntercepters = new ArrayList<YcIntercepter>();
}
@SuppressWarnings("unchecked")
public <T> T getProxy() {
return (T) proxy;
}
public <T> void setProxy(T proxy) {
this.proxy = proxy;
}
public void addIntercepter(YcIntercepter intercepter) throws IntercepterAlreadyExistException {
if(ycIntercepters.contains(intercepter)) {
throw new IntercepterAlreadyExistException("拦截器"
+ intercepter.getClass().getName() + "已存在");
}
ycIntercepters.add(intercepter);
}
public void removeintercepter(YcIntercepter intercepter) {
if(!ycIntercepters.contains(intercepter)) {
return;
}
ycIntercepters.remove(intercepter);
}
public boolean dobefore(Method method, Object[] args) {
for(YcIntercepter intercepter : ycIntercepters) {
if(!intercepter.getMethod().equals(method)) {
continue;
}
if(intercepter.before(args).equals(false)) {
return false;
}
}
return true;
}
public Object doafter(Method method, Object result) {
for(YcIntercepter intercepter : ycIntercepters) {
if(!intercepter.getMethod().equals(method)) {
continue;
}
result = intercepter.after(result);
}
return result;
}
public void dodealException(Method method, Throwable e) {
for(YcIntercepter intercepter : ycIntercepters) {
if(!intercepter.getMethod().equals(method)) {
continue;
}
intercepter.dealException(e);
}
}
}
拦截器类:
package com.mec.aop.core;
import java.lang.reflect.Method;
public abstract class YcIntercepter {
private Method method;
private Class<?> klass;
public YcIntercepter() {
}
public YcIntercepter(Method method, Class<?> klass) {
super();
this.method = method;
this.klass = klass;
}
public abstract Boolean before(Object[] args);
public abstract Object after(Object result);
public abstract void dealException(Throwable e);
public Method getMethod() {
return method;
}
public void setMethod(Method method) {
this.method = method;
}
public Class<?> getKlass() {
return klass;
}
public void setKlass(Class<?> klass) {
this.klass = klass;
}
}
为该拦截器类实现一个适配器:
/*
* @auther: yc
* time: 2018/10/16
*/
package com.mec.aop.core;
import java.lang.reflect.Method;
public class YcIntercepterAdapter extends YcIntercepter{
public YcIntercepterAdapter() {
}
public YcIntercepterAdapter(Method method, Class<?> klass) {
super(method, klass);
}
@Override
public Boolean before(Object[] args) {
return true;
}
@Override
public Object after(Object result) {
return result;
}
@Override
public void dealException(Throwable e) {
}
}
第三层ClassProxyFactory,在该类中编写一个Map,将类名和代理的对象对应起来,并给出用户使用的接口:产生代理和增删拦截器。
ClassProxyFactory类:
/*
* @auther: yc
* time: 2018/10/16
*/
package com.mec.aop.core;
import java.util.HashMap;
import java.util.Map;
public class ClassProxyFactory {
private static final Map<String, YcProxy> map = new HashMap<>();
public <T> T getCGLProxy(Class<?> klass) throws Exception {
return cglProxy(klass, klass.newInstance());
}
public <T> T getCGLProxy(Object object) {
return cglProxy(object.getClass(), object);
}
private <T> T cglProxy(Class<?> klass, Object object) {
String ClassName = klass.getName();
YcProxy ycProxy = map.get(ClassName);
if(ycProxy != null) {
return ycProxy.getProxy();
}
ProxyFactory proxyFactory = new ProxyFactory();
T proxy = proxyFactory.getCGLProxy(klass, object);
map.put(ClassName, proxyFactory.getYcProxy());
return proxy;
}
public void addIntercepter(Class<?> klass, YcIntercepter intercepter) throws IntercepterAlreadyExistException {
if(!intercepter.getKlass().equals(klass)) {
return;
}
map.get(klass.getName()).addIntercepter(intercepter);
}
public void removeIntercepter(Class<?> klass, YcIntercepter intercepter) {
map.get(klass.getName()).removeintercepter(intercepter);
}
}
接下来就来测试一下结果把。在测试之前,需要编写一个类去实现拦截时的三个抽象方法,并作出相应的处理,在此我们简单的输出一下:
实现拦截器的抽象方法的类NormalActionIntercepter:
/*
* @auther: yc
* time: 2018/10/16
*/
package com.mec.aop.model;
import java.lang.reflect.Method;
import com.mec.aop.core.YcIntercepterAdapter;
public class NormalActionIntercepter extends YcIntercepterAdapter{
public NormalActionIntercepter(Method method, Class<?> klass) {
super(method, klass);
}
public NormalActionIntercepter() {
}
@Override
public Boolean before(Object[] args) {
for(Object key : args) {
System.out.println("置前拦截:" + key);
}
return true;
}
@Override
public Object after(Object result) {
System.out.println("滞后拦截:" + result);
return result;
}
}
接下来就可以编写测试来看一下结果,其实很简单,创建两个拦截器,通过ClassProxyFactoey类所提供的方法添加,然后通过代理调用normalAction方法即可。
/*
* @auther: yc
* time: 2018/10/16
*/
package Test;
import java.lang.reflect.Method;
import com.mec.aop.core.ClassProxyFactory;
import com.mec.aop.model.NormalActionIntercepter;
import com.mec.aop.model.NormalClass;
public class Test {
public static void main(String[] args) {
Class<?> klass = NormalClass.class;
Method method = null;
try {
method = klass.getDeclaredMethod("normalAction", new Class<?>[] {String.class});
} catch (NoSuchMethodException | SecurityException e1) {
e1.printStackTrace();
}
NormalActionIntercepter intercepter1 = new NormalActionIntercepter(method, klass);
NormalActionIntercepter intercepter2 = new NormalActionIntercepter(method, klass);
ClassProxyFactory classProxyFactory = new ClassProxyFactory();
//生成代理
try {
NormalClass normalClass = classProxyFactory.getCGLProxy(klass);
classProxyFactory.addIntercepter(klass, intercepter1);
classProxyFactory.addIntercepter(klass, intercepter2);
normalClass.normalAction("执行normalAction方法");
} catch (Exception e) {
e.printStackTrace();
}
}
}
下面来看一下输出结果:
两次拦截成功!希望能对你了解AOP有所帮助,欢迎交流