前言
强烈推荐 B站 宝藏男孩 遇见狂神说
JDK动态代理(基于接口)
-
学习之前,主要了解**代理模式**
-
用一个简单的例子来了解:
1、创建UserDao接口
public interface UserDao {
void save();
void delete();
}
2、实现接口
public class UserDaoImpl implements UserDao {
public void save() {
System.out.println("保存");
}
public void delete() {
System.out.println("删除");
}
}
3、方面,公共的组件
public class MyAspect {
public void before(){
System.out.println("before方法");
}
public void after(){
System.out.println("after方法");
}
}
4.代理类
- InvocationHandler 接口
-
是proxy代理实例的调用处理程序实现的一个接口,需要实现
- proxy是代理对象,method目标对象方法,args目标对象方法的参数
- .Proxy类就是用来创建一个代理对象的类
public Object invoke(Object proxy, Method method, Object[] args)
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class MyProxy implements InvocationHandler {
private UserDao userDao;
private MyAspect myAspect;
public MyProxy(UserDao userDao, MyAspect myAspect) {
this.userDao = userDao;
this.myAspect = myAspect;
}
//创建代理对象
public Object getProxy(){
return Proxy.newProxyInstance(this.getClass().getClassLoader(),
userDao.getClass().getInterfaces(),this);
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
myAspect.before();
method.invoke(userDao,args);
System.out.println("方法名:"+method.getName());
myAspect.after();
return null;
}
}
5、测试
public class Test {
public static void main(String[] args) {
// 被代理类,真实类
UserDao userDao = new UserDaoImpl();
// 方面,抽出的公共方法
MyAspect aspect = new MyAspect();
// 代理类
MyProxy proxy = new MyProxy(userDao,aspect);
UserDao user = (UserDao) proxy.getProxy();
user.save();
CGLIB动态代理(基于类)
- MethodInterceptor
实现MethodInterceptor 接口,在调用目标对象的方法时,
就可以实现在调用方法之前、调用方法过程中、调用方法之后对其进行控制。
- Enhancer
Enhancer允许为非接口类型创建一个Java代理。Enhancer动态创建了给定类型的子类但是拦截了所有的方法。和Proxy不一样的是,不管是接口还是类他都能正常工作。
代理类
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
/*
* 实现MethodInterceptor 接口,在调用目标对象的方法时,
* 就可以实现在调用方法之前、调用方法过程中、调用方法之后对其进行控制。
* */
public class MyProxy<T> implements MethodInterceptor {
private T byProxy;
private MyAspect myAspect;
public MyProxy(T byProxy, MyAspect myAspect) {
this.byProxy = byProxy;
this.myAspect = myAspect;
}
public T getProxy(){
// Enhancer可以用来为无接口的类创建代理。
// 它的功能与java自带的Proxy类挺相似的
// 通过Enhancer创建代理类
Enhancer enhancer = new Enhancer();
// 设置需要代理的类
enhancer.setSuperclass(UserDaoImpl.class);
enhancer.setCallback(this);
T obj = (T)enhancer.create();
return obj;
}
/*
* Method method 调用的被代理对象的方法
*
* */
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
myAspect.before();
method.invoke(byProxy,objects);
myAspect.after();
return null;
}
}
测试
public class Test {
public static void main(String[] args) {
// 被代理对象
UserDaoImpl userDao = new UserDaoImpl();
// 方面
MyAspect myAspect = new MyAspect();
// 代理类
MyProxy<UserDaoImpl> myProxy = new MyProxy<UserDaoImpl>(userDao,myAspect);
UserDaoImpl userDao1 = myProxy.getProxy();
userDao1.save();
userDao1.delete();
}
}
总结
1、两者实现动态代理,主要是在代理类的实现接口不同,创建代理类的类不同
jdk实现InvocationHandler接口,Proxy创建代理类
cglib实现MethodInterceptor接口,Enhancer 创建代理类
共同成长,共同进步~