Javaassist是通过操作class字节码文件来修改类的,如果需要Javaassist实现AOP,需要用到Javaassist的ProxyFactory、ProxyObject、MethodHandler三个类,通过这种方法就可以so easy的完成了,我们还可以自己写一个AOP的框架,通过Javassit同cglib一样,可以不依赖于接口的方式来实现代理操作
这个简单实现,是直接使用的代码的api,没有做类的设计,只是简单将如何做Aop的主要代码写出来了,下面的我写了如何通过父类代理,来简化代理操作。
直接调用Javassist的api来做的,没有做封装的操作,我们可以自己建立一个拦截器,类似于JDK,然后调用Javassist的方法来解决动态代理,而且Javassist的功能强大,还可以动态编辑class文件
package com.yellowcong.test; import java.lang.reflect.Method; import javassist.util.proxy.MethodHandler; import javassist.util.proxy.ProxyFactory; import javassist.util.proxy.ProxyObject; /** * *作者:yellowcong *日期:2017/09/01 *時間:8:23:56 *描述: */ public class Demo8 { public static void main(String[] args) throws Exception, IllegalAccessException { //代理对象 ProxyFactory factory = new ProxyFactory(); //设定需要代理的类 factory.setSuperclass(TestDemo.class); //创建class Class<?> clazz = factory.createClass(); //实例化对象 TestDemo testDemo = (com.yellowcong.test.TestDemo) clazz.newInstance(); //设置代理对象 ((ProxyObject)testDemo).setHandler(new MethodHandler() { /** * @param obj 原来的对象 * @param method 这个是原来类的方法 * @param process JavaAssist获取的进程,是修改后的类方法 * @param args 参数 */ @Override public Object invoke(Object obj, Method method, Method process, Object[] args) throws Throwable { Object result = null; System.out.println(method.getName()+"\t"+process.getName()+"执行前"); result = process.invoke(obj, args); System.out.println("执行后"); return result; } }); testDemo.say("dou"); } }代理类需要实现接口MethodHandler,里面有一个invoke的方法,同时,在getProxy类中,写了需要将代理类绑定到拦截器的类
/** * 定义接口 * @author zhangrw * @data 2017/09/01 */ class MethodInterceptor implements MethodHandler{ private Object target ; public MethodInterceptor(Object target) { this.target = target ; } /** * 执行代理方法 * @param obj * @param method * @param process * @param args * @return * @throws Throwable */ @Override public Object invoke(Object obj, Method method, Method process, Object[] args) throws Throwable { Object result = null; System.out.println(method.getName()+"\t"+process.getName()+"执行前"); result = process.invoke(obj, args); System.out.println("执行后"); return result; } /** * 获取代理对象 * @return * @throws Exception * @throws InstantiationException */ Object getProxy() throws Exception { //代理对象 ProxyFactory factory = new ProxyFactory(); //设定需要代理的类 factory.setSuperclass(this.target.getClass()); //创建class Class<?> clazz = factory.createClass(); //实例化对象 , 这个对象的字节类已经修改了, 是ProxyObject 的子类了 Object targetObj = clazz.newInstance(); //设定代理的对象,我们设定为这个类,就可以了 ((ProxyObject)targetObj).setHandler(this); return targetObj; } }定义的子拦截器,自需要覆写里面的invoke的方法就可以了,其他的方法默认就可以了
/** * 继承自共同的MethodInterceptor ,然后复写里面的invoke 方法 * @author zhangrw * @data 2017/09/01 */ class MyInterceptor extends MethodInterceptor{ public MyInterceptor(Object target) { super(target); } /** * 执行代理方法 * @param obj * @param method * @param process * @param args * @return * @throws Throwable */ @Override public Object invoke(Object obj, Method method, Method process, Object[] args) throws Throwable { Object result = null; System.out.println(method.getName()+"\t"+process.getName()+"执行前,extend"); result = process.invoke(obj, args); System.out.println("执行后,Extend"); return result; } }代理对象中,我们可以定义父类代理对象后,在使用子类代理对象,这样就可以节省一些重复代码的编写
/** * *作者:yellowcong *日期:2017/09/01 *時間:8:23:56 *描述: */ public class Demo9 { public static void main(String[] args) throws Exception, IllegalAccessException { MethodInterceptor parentProxy = new MethodInterceptor(new TestDemo()); TestDemo demo2 = (TestDemo) parentProxy.getProxy(); demo2.say("parent"); //获取代理对象 MyInterceptor proxy = new MyInterceptor(new TestDemo()); TestDemo demo = (TestDemo) proxy.getProxy(); demo.say("dobui"); } }