面向切面编程(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 {
@Override
public void saveUser(User user) {
System.out.println("save user success!");
}
@Override
public void deleteUser(User user) {
System.out.println("delete user success!");
}
@Override
public User getUser(Serializable id) {
System.out.println("get user success!");
return null;
}
@Override
public 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;
}
@Override
public 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 {
@Test
public void test() {
UserServiceInterceptor interceptor = new UserServiceInterceptor(new UserServiceImpl(), "saveUser");
interceptor.setBeforeInterceptor(new BeforeInterceptor() {
@Override
public void execute() {
System.out.println("before saveUser...");
}
});
interceptor.setAfterInterceptor(new AfterInterceptor() {
@Override
public 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!