首页 > 编程 > Java > 正文

又一次闲来无聊,使用Java的动态代理机制来模拟AOP

2019-11-06 08:19:33
字体:
来源:转载
供稿:网友

转载地址:http://kentkwan.iteye.com/blog/739499

面向切面编程(AOP)实现了从另一个层面解决了面向对象所不能解决的对象间耦合度问题。今天闲来无聊做了个模拟AOP的小例子,有不完善的地方请指出。

首先我们定义一个接口和实现类

package com.gzmu.dynamic.PRoxy.service;import java.io.Serializable;import com.gzmu.dynamic.proxy.po.User;public interface UserService {void saveUser(User user);void updateUser(User user);void deleteUser(User user);    User getUser(Serializable id);}
package com.gzmu.dynamic.proxy.service.impl;import java.io.Serializable;import com.gzmu.dynamic.proxy.po.User;import com.gzmu.dynamic.proxy.service.UserService;public class UserServiceImpl implements UserService {    @Overridepublic void saveUser(User user) {        System.out.println("save user success!");    }    @Overridepublic void deleteUser(User user) {        System.out.println("delete user success!");    }    @Overridepublic User getUser(Serializable id) {        System.out.println("get user success!");return null;    }    @Overridepublic void updateUser(User user) {        System.out.println("update user success!");    }}

然后我们建立一个对UserService方法的拦截器。

package com.gzmu.dynamic.proxy.interceptor;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import com.gzmu.dynamic.proxy.service.impl.UserServiceImpl;public class UserServiceInterceptor implements InvocationHandler {private Object targer;private String methodName;private BeforeInterceptor beforeInterceptor;private AfterInterceptor afterInterceptor;public UserServiceInterceptor(Object targer, String methodName) {this.targer = targer;this.methodName = methodName;    }public void setBeforeInterceptor(BeforeInterceptor beforeInterceptor) {if (this.beforeInterceptor == null)this.beforeInterceptor = beforeInterceptor;    }public void setAfterInterceptor(AfterInterceptor afterInterceptor) {if (this.afterInterceptor == null)this.afterInterceptor = afterInterceptor;    }    @Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {if (method.getName().equals(methodName)) {            execute(beforeInterceptor);            Object o = method.invoke(new UserServiceImpl(), args);            execute(afterInterceptor);return o;        }return method.invoke(targer, args);    }private void execute(Interceptor interceptor) {if (interceptor != null)            interceptor.execute();    }}

因为我们想这个拦截器可以拦截到方法的调用,并且可以在方法的调用前后执行额外可以指定的操作,所以我们使用三个接口来实现这个功能。

package com.gzmu.dynamic.proxy.interceptor;public interface Interceptor {void execute();}// --------------------------------------------------------------package com.gzmu.dynamic.proxy.interceptor;public interface BeforeInterceptor extends Interceptor  {}// --------------------------------------------------------------package com.gzmu.dynamic.proxy.interceptor;public interface AfterInterceptor extends Interceptor {}

最后组装我们的拦截器来实现AOP操作

package com.gzmu.dynamic.proxy.test;import java.lang.reflect.Proxy;import org.junit.Test;import com.gzmu.dynamic.proxy.interceptor.AfterInterceptor;import com.gzmu.dynamic.proxy.interceptor.BeforeInterceptor;import com.gzmu.dynamic.proxy.interceptor.UserServiceInterceptor;import com.gzmu.dynamic.proxy.po.User;import com.gzmu.dynamic.proxy.service.UserService;import com.gzmu.dynamic.proxy.service.impl.UserServiceImpl;public class TestCase {    @Testpublic void test() {        UserServiceInterceptor interceptor = new UserServiceInterceptor(new UserServiceImpl(), "saveUser");        interceptor.setBeforeInterceptor(new BeforeInterceptor() {            @Overridepublic void execute() {                System.out.println("before saveUser...");            }        });        interceptor.setAfterInterceptor(new AfterInterceptor() {            @Overridepublic void execute() {                System.out.println("after saveUser...");            }        });        UserService serivce = (UserService) Proxy.newProxyInstance(getClass().getClassLoader(), new Class[] { UserService.class }, interceptor);        serivce.saveUser(new User());        serivce.updateUser(new User());        serivce.deleteUser(new User());        serivce.getUser(null);    }}

运行结果如下

before saveUser...save user success!after saveUser...update user success!delete user success!get user success!怎么样,超爽吧,再也不用重复的编写同样的代码了,而且能然代码组织得更加有逻辑。
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表