cglib简单模拟aop

来源:互联网 发布:软件开发质量控制 编辑:程序博客网 时间:2024/05/21 09:57

cglib可用来在运行时对指定方法进行拦截,简单写了一个用cglib简单的对aop进行了模拟,其中有很多功能没有进行扩展,看过的同学可在基础上添加,首先上配置文件进行解读:

<?xml version="1.0" encoding="UTF-8"?><aop><aspect name="Worker"><class method="CountPlus" position="beforeExecution">com.cyj.cglib.Worker</class><method name="preStart">com.cyj.cglib.ExtraMethodSet</method></aspect></aop>

根元素:aop

每个aspect为一个切面,position是切点描述,此处进行化简“beforeExecution”是指在方法执行前进行拦截 ,class节点描述的是被拦截的类和方法

method描述的是添加的增强方法。

即:切面名:Worker    在com.cyj.cglib.Worker类的CountPlus方法执行前执行com.cyj.cglib.ExtraMethodSet类的preStart方法。

生成代理类的工厂如下:

package com.cyj.cglib;import java.lang.reflect.Method;import java.util.HashMap;import java.util.List;import java.util.Map;import org.dom4j.Document;import org.dom4j.DocumentException;import org.dom4j.Element;import org.dom4j.io.SAXReader;import org.junit.Test;import net.sf.cglib.proxy.Enhancer;import net.sf.cglib.proxy.MethodInterceptor;import net.sf.cglib.proxy.MethodProxy;/** * 该功能仅限测试,代理单方法,如需代理多方法可改动AOPDescription及WrapFactory的构造方法 *  * @author Administrator *  */public class WrapFacotry {private Map<String, AOPDescription> descMap;private static WrapFacotry wf = new WrapFacotry();private WrapFacotry() {this.descMap = new HashMap<String, AOPDescription>();SAXReader reader = new SAXReader();Document document = null;try {document = reader.read(WrapFacotry.class.getResourceAsStream("aop.xml"));Element root = document.getRootElement();List<Element> AOP = root.selectNodes("aspect");for (Element aop : AOP) {String key = aop.attributeValue("name");Element clazzElement = aop.element("class");String method = clazzElement.attributeValue("position");String interceptedMethodName = clazzElement.attributeValue("method");String interceptedClassName = clazzElement.getText();Element methodElement = aop.element("method");String interceptorClassName = methodElement.getText();String interceptorMethodName = methodElement.attributeValue("name");descMap.put(key, new AOPDescription(method,interceptedClassName, interceptedMethodName,interceptorClassName, interceptorMethodName));}} catch (DocumentException e) {e.printStackTrace();}}public static WrapFacotry getFactory() {return wf;}public Object getInstance(String name) throws ClassNotFoundException {final AOPDescription desc = descMap.get(name);if (desc != null) {String targetName = desc.getInterceptedClassName();Enhancer en = new Enhancer();final Class targetClass = Class.forName(targetName);en.setSuperclass(targetClass);en.setCallback(new MethodInterceptor() {@Overridepublic Object intercept(Object arg0, Method arg1,Object[] arg2, MethodProxy arg3) throws Throwable {if (arg1.getName().equals(desc.getInterceptedMethodName())) {if (desc.getMethod().equals("beforeExecution")) {Class clazz = Class.forName(desc.getInterceptorClassName());Object interceptor = clazz.newInstance();// 可在配置文件中定义参数类型Method interceptorMethod = clazz.getDeclaredMethod(desc.getInterceptorMethodName(), null);interceptorMethod.invoke(interceptor, null);}arg1.invoke(targetClass.newInstance(), arg2);if (desc.getMethod().equals("postExecution")) {Class clazz = Class.forName(desc.getInterceptorClassName());Object interceptor = clazz.newInstance();// 可在配置文件中定义参数类型Method interceptorMethod = clazz.getDeclaredMethod(desc.getInterceptorMethodName(), null);interceptorMethod.invoke(interceptor, null);}}return null;}});return en.create();}throw new ClassNotFoundException();}@Testpublic void t() {}}class AOPDescription {private String method;private String interceptedClassName;private String interceptedMethodName;private String interceptorClassName;private String interceptorMethodName;public String getMethod() {return method;}public void setMethod(String method) {this.method = method;}public String getInterceptedClassName() {return interceptedClassName;}public void setInterceptedClassName(String interceptedClassName) {this.interceptedClassName = interceptedClassName;}public String getInterceptedMethodName() {return interceptedMethodName;}public void setInterceptedMethodName(String interceptedMethodName) {this.interceptedMethodName = interceptedMethodName;}public String getInterceptorClassName() {return interceptorClassName;}public void setInterceptorClassName(String interceptorClassName) {this.interceptorClassName = interceptorClassName;}public String getInterceptorMethodName() {return interceptorMethodName;}public void setInterceptorMethodName(String interceptorMethodName) {this.interceptorMethodName = interceptorMethodName;}public AOPDescription(String method, String interceptedClassName,String interceptedMethodName, String interceptorClassName,String interceptorMethodName) {super();this.method = method;this.interceptedClassName = interceptedClassName;this.interceptedMethodName = interceptedMethodName;this.interceptorClassName = interceptorClassName;this.interceptorMethodName = interceptorMethodName;}}

其中AOPDescription是pojo仅仅是保存对切面的描述,时间原因这个工厂只能添加一个增强方法,后续可以把method放入一个list中进行执行,有兴趣的可以自行添加

方法的参数没有定义,可以在配置文件中添加类似节点,有空再说。。。

此处每次调用一个getInstance方法就会返回一个由cglib产生的类,无聊的可以建一个静态的map结构,每产生一个放入map中,第二次就可以直接从map中拿,算是一个优化吧。。。


下面上实体类,一个是被增强类,一个是增强类:

package com.cyj.cglib;public class Worker {private int count;public Worker(){this.count = 0;}public int CountPlus(){System.out.println("CountPlus");return ++count;}public int CountMinus(){System.out.println("CountMinus");return --count; }}

package com.cyj.cglib;public class ExtraMethodSet {public void printCurrentTimeMillis(){System.out.println(System.currentTimeMillis());}public void preStart(){System.out.println("Method Start");}public void postEnd(){System.out.println("Method Over");}}

测试类:

package com.cyj.cglib.test;import org.junit.Test;import com.cyj.cglib.Worker;import com.cyj.cglib.WrapFacotry;public class TestAOP {@Testpublic void t() throws ClassNotFoundException{WrapFacotry fa = WrapFacotry.getFactory();Worker worker = (Worker)fa.getInstance("Worker");worker.CountPlus();}}

好,目前为止,这个模拟aop的代码结束,大家扣脚的时间可以对这段模拟代码进行一些优化。

坚信!未来属于猥琐的扣脚大叔们!

0 0
原创粉丝点击