您的位置:首页 > 编程语言 > Java开发

Spring(八)jdk动态代理(AOP简单实现)

2016-12-08 23:37 756 查看

说明

jdk动态代理就是对“装饰者”设计模式的简化。使用前提:必须要有接口

编写过程:

1.目标类:接口+实现类

2.切面类:用于存放通知。

3.工厂类:编写工厂生成代理

4.测试

UserService 接口 三个方法

public interface UserService {
public void addUser();
public void updateUser();
public void deleteUser();
}


UserService 实现类,实现了三个方法

public class UserServiceImpl implements UserService {

@Override
public void addUser() {
System.out.println("UserServiceDaoImpl addUser");
}

@Override
public void updateUser() {
System.out.println("UserServiceDaoImpl updateUser");
}

@Override
public void deleteUser() {
System.out.println("UserServiceDaoImpl deleteUser");
}

}


切面类,共两个方法,before和end。希望在目标类的方法运行前后各调用一次。

public class MyAspect {
public void before(){
System.out.println("before");

}
public void after(){
System.out.println("after");
}
}


工厂类,用于生成代理。

其中代理类的作用就是将目标类(切入点)和切面类(通知)结合。

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class MyProxyFactory {
public static Object createUserService() {
//目标类
final UserService userServiceDao = new UserServiceImpl();
//切面类
final MyAspect myAspect = new MyAspect();
//代理类
Object proxy = Proxy.newProxyInstance(MyProxyFactory.class
.getClassLoader(), userServiceDao.getClass().getInterfaces(),
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method,
Object[] args) throws Throwable {
Object obj = null;
//前方法
myAspect.before();
//执行目标类的方法
obj = method.invoke(userServiceDao, args);
//后方法
myAspect.after();
return obj;
}
});
return proxy;
}
}


其中Proxy.newProxyInstance有三个参数。

arg1:loader,类加载器,动态代理类,运行时创建,任何类都需要类加载器加载到内存。一般使用当前类.class.getClassLoader();也可以使用目标实例.getClass().getClassLoader()

arg2:代理类要实现的所有接口。目标类例.getClass().getInterfaces();

arg3:InvocationHandler处理类,接口必须进行实现。一般采用匿名内部实现。提供的invoke方法。代理类的每一个方法执行都会调用一次invoke。invoke也有三个参数(Object proxy:代理对象, Method method:代理对象当前执行的方法,Object[] args:当前执行方法的参数)。我们可以通过method.getName来为不同的方法实现不同的功能。

测试类

public class Test {
@org.junit.Test
public void testProxy(){
UserService userService=(UserService) MyProxyFactory.createUserService();
userService.addUser();
userService.updateUser();
userService.deleteUser();
}
}


运行结果



我们可以看到虽然我们调用的UserService对象,但是在每个方法执行的前后都有输出before和after。所以我们使用工厂类实现了jdk动态代理。

我们其实可以这样理解jdk动态代理。

在底层我们在调用代理类的方法时,它会执行invoke方法。

代理类本身没有什么功能,它只是把所有的功能组合在一起。

代理类
addUser(){
invoke(this,addUser,[]);
}
updateUser(){
invoke(this,updateUser,[]);
}
deleteUser(){
invoke(this,deleteUser,[]);
}


你看懂了吗?

上面说了 我们可以通过method.getName来为特定的方法实现特定的功能。那么我们只为addUser方法执行before和after方法。

我们修改代理类的invoke方法

@Override
public Object invoke(Object proxy, Method method,
Object[] args) throws Throwable {
Object obj = null;
if("addUser".equals(method.getName())){
//前方法
myAspect.before();
//执行目标类的方法
obj = method.invoke(userServiceDao, args);
//后方法
myAspect.after();
}else{
obj = method.invoke(userServiceDao, args);
}
return obj;
}


执行结果:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: