前言
强烈推荐 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 创建代理类
共同成长,共同进步~