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

面向切面编程(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!

怎么样,超爽吧,再也不用重复的编写同样的代码了,而且能然代码组织得更加有逻辑。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值