JDK的动态代理只要涉及到java.lang.reflect包中的两个类:Proxy和InvocationHandler。其中InvocationHandler是一个接口,可以通过实现该接口定义横切逻辑,并通过反射机制调用目标类的代码,动态将横切代码和业务逻辑编织在一起。
移除性能监视的代码:
package com.hegx.spring.aop.jdk; import com.hegx.spring.aop.Forum; import com.hegx.spring.aop.dao.ForumDao; import com.hegx.spring.aop.dao.impl.ForumDaoImpl; import com.hegx.spring.aop.service.ForumService; /** * @Author: hegx * @Description: * @Date: 14:25 2017/7/16 */ public class ForumServiceImpl implements ForumService { private ForumDao forumDao = new ForumDaoImpl(); @Override public void remove(Integer forumId) { forumDao.remove(forumId); try { Thread.currentThread().sleep(20); } catch (InterruptedException e) { e.printStackTrace(); } } @Override public void create(Forum forum) { forumDao.create(forum); try { Thread.currentThread().sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } } }
把原本性能监视的代码安置到一个新的类中PorumanceHandler:
package com.hegx.spring.aop.jdk; import com.hegx.spring.aop.PerformanceMonitor; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; /** * @Author: hegx * @Description:通过实现InvocationHandler实现该接口定义横切逻辑 * @Date: 16:14 2017/7/16 */ public class ForumanceHandler implements InvocationHandler { private Object target; public ForumanceHandler(Object target) {///target为目标业务类对象 this.target = target; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { PerformanceMonitor.begin(target.getClass().getName()+""+method.getName()); //通过反射方法调用目标业务类的目标方法 Object object = method.invoke(target,args); PerformanceMonitor.end(); return object; } }
下面我们通过Porxy结合InvacationHandler创建ForumService接口代理的实例如下代码:
package com.hegx.spring.aop.jdk; import com.hegx.spring.aop.Forum; import com.hegx.spring.aop.service.ForumService; import java.lang.reflect.Proxy; /** * @Author: hegx * @Description:创建代理实例 * @Date: 16:29 2017/7/16 */ public class TestForumServie { public static void main(String[] args) { //希望被代理的对象 ForumService target = new ForumServiceImpl(); //将目标业务类和横切代码编织在一起 ForumanceHandler handler = new ForumanceHandler(target); /** * 根据编织的业务类逻辑和性能监视横切逻辑的InvocationHandler实例创建代理实例 * * */ ForumService proxy = (ForumService) Proxy.newProxyInstance( target.getClass().getClassLoader(), target.getClass().getInterfaces(), handler ); proxy.create(new Forum()); proxy.remove(20); } }
结果打印:
begin Monitor...
创建forum成功
end Monitor...
com.hegx.spring.aop.jdk.ForumServiceImplcreate花费了2000毫秒
begin Monitor...
模拟删除Forum记录:20
end Monitor...
com.hegx.spring.aop.jdk.ForumServiceImplremove花费了20毫秒
通过上面的代码和输入的结果可知,程序的运行的运行结果和直接在业务类中编写性能监视逻辑效果是一样的,但是在这里,原来分散的横切逻辑代码已经被我们抽取到了PerformanceHandler中,当其他业务类(如UserService,SystemService等)的业务方法也需要性能监视时,我们只要按照上面的方式,分别放他们创建代理对象就可以了。