JDK动态代理是通过java.lang.reflect.Proxy类来实现,我们可以调用Proxy类的newProxyInstance()方法来创建代理对象,对于使用业务接口的类,Spring,默认会使用JDK动态代理实现AOP
下面通过一个案例来演示Spring中JDK动态代理的实现过程,具体步骤如下:
1、创建一个名为chaoter03的web项目,导入Spring框架所需的JAR包到项目的lib路径中去,并发布到类路径下。
2、在src路径下,创建一个com.itheima.jdk包,在该包下创建接口UserDao,并在该接口中编写添加与删除的方法,代码如下所示:
package com.itheima.jdk;
public interface UserDao {
public void addUser();
public void deleteUser();
}
3、在com.itheima.jdk包中,创建UserDao的接口UserDaoImpl,分别实现接口中的方法,并在每个方法中添加一条输出语句
package com.itheima.jdk;
public class UserDaoImpl implements UserDao {
public void addUser() {
System.out.println("添加用户");
}
public void deleteUser() {
System.out.println("删除用户");
}
}
4、在src目录下创建一个com.itheima.aspect包,并在该包下创建切面类MyAspect。在该类中定义一个模拟权限检查的方法和一个模拟记录日志的方法,这两个方法就表示切面的通知,
package com.itheima.aspect;
public class MyAspect {
public void check_Permissions() {
System.out.println("模拟检察权限");
}
public void log() {
System.out.println("模拟记录日志");
}
}
5、在com.itheima.jdk包中,创建代理类jdkProxy,该类需要实现InvocationHandler接口,并编写代理方法,在代理方法中,需要通过Proxy类实现动态代理
package com.itheima.jdk;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import com.itheima.aspect.MyAspect;
/**
* JDK代理类
*/
public class JdkProxy implements InvocationHandler {
//声明目标类接口
private UserDao userDao;
//创建代理方法
public Object createProxy(UserDao userDao) {
this.userDao=userDao;
//类加载器
ClassLoader classLoader = JdkProxy.class.getClassLoader();
//被代理对象实现所有接口
Class[] clazz = userDao.getClass().getInterfaces();
//使用代理类,进行增强,返回的是代理后的对象
return Proxy.newProxyInstance(classLoader, clazz, this);
}
/*
* 所有动态代理类的方法调用,都会交由invoke()方法去处理
* proxy 被代理后的对象
* method 将要被直行的方法信息
* args 执行方法时需要的参数
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//声明切面
MyAspect myAspect = new MyAspect();
//增强面
myAspect.check_Permissions();
//在目标类上调用方法,并传入参数
Object obj =method.invoke(userDao, args);
//后增强
myAspect.log();
return obj;
}
}
在上面的代码中JdkProxy类实现了InvocationHandler接口,并实现了接口中的invoke方法多有动态代理类都由这个方法处理,在创建的代理方法createProxy()中使用了Proxy类的newProxyInstance()方法来创建代理对象,
6、在com.itheima.jdk包中,创建测试类JdkTest,在该类中,创建代理对象和目标对象,然后从代理对象中获得被增强后的对象,最后调用对象中的添加和删除方法,
package com.itheima.jdk;
public class JdkTest {
public static void main(String[] args) {
//创建代理对象
JdkProxy jdkProxy = new JdkProxy();
//创建目标对象
UserDao userDao =new UserDaoImpl();
//从代理对象中获得增强之后的对象
UserDao userDao2 = (UserDao) jdkProxy.createProxy(userDao);
userDao2.addUser();
userDao2.deleteUser();
}
}
7、运行之后,输出结果如下所示:
通过结果显示,JDK动态代理却是增强了userDao中的两个方法