1.创建方法接口,目标类和代理类实现这个接口
2. 代理类中包含目标类的成员变量,通过构造函数进行传参
// 传统静态代理
public class UserProxy implements UserService {
private UserService userService;
public UserProxy(UserService userService) {
this.userService = userService;
}
@Override
public User getUserByName(String username, Integer age) {
getCurDate();
User user = userService.getUserByName(username, age);
Commit();
return user;
}
@Override
public int getUserCounts() {
getCurDate();
int count = userService.getUserCounts();
Commit();
return count;
}
// 代理类增强方法
public void getCurDate() {
Date date = new Date();
SimpleDateFormat dft = new SimpleDateFormat("yyyy-MM-dd");
String curDate = dft.format(date);
System.out.println(curDate);
}
public void Commit() {
System.out.println("事务提交");
}
}
问题:代码冗余,增强的功能需要添加在所有需要的方法中,当目标类增多的时候,需要为每个目标类都要创建代理类;否则,使用成员变量的方式也会造成一个类中方法量过多,不易管理
二、JDK动态代理使用java虚拟机的类加载机制:
- 通过一个类的全限定名来获取定义此类的二进制字节流
- 将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构
- 在内存中生成一个代表这个类的 java.lang.Class 对象,作为方法区这个类的各种数据访问入口
动态代理分为:JDK动态代理和cglib动态代理,两者分别基于接口实现和类继承实现
jdb动态代理:
1.创建Proxy对象,通过newInstance方法获取代理对象实例;
2.newInstance中的三个参数:目标类的类加载器,接口全限定类,InvocationHandler对象
public class UserDynamicProxy {
private UserService userService;
public UserDynamicProxy(UserService userService) {
this.userService = userService;
}
// 通过动态代理获取代理对象
public Object getObject() {
// jdk动态代理固定参数:目标类加载器,目标接口,InvocationHandler对象
Object proxy = Proxy.newProxyInstance(userService.getClass().getClassLoader(),
new Class[]{UserService.class},
(object, method, args) -> {
// 增强方法
Object res = method.invoke(userService, args);
System.out.println("提交事务");
return res; // 这是个代理对象
}
);
return proxy;
}
}
测试方法:
@Test
public void testDynamicProxy() {
UserService userService = new UserServiceImpl();
UserDynamicProxy userDynamicProxy = new UserDynamicProxy(userService);
UserService proxy = (UserService) userDynamicProxy.getObject();
User user = proxy.getUserByName("娜美", 18);
System.out.println("dynamic user:" + user);
System.out.println("-----------华丽分割线-------------");
int count = proxy.getUserCounts();
System.out.println("数量:" + count);
}
测试发现,在newInstance中设置一次增强方法,UserService的所有方法都会被添加
jdk动态代理和cglib区别JDK动态代理:基于Java反射机制实现,必须要实现了接口的业务类才能用这种办法生成代理对象。
cglib动态代理:基于ASM机制实现,通过生成业务类的子类作为代理类。
JDK Proxy 的优势:
基于类似 cglib 框架的优势:
cglib感觉看不下去,之后来补上吧。。。。
spring中的aop机制就是依靠动态代理进行实现的,统一了cglib和jdk动态代理实现上的差异,给出了统一的规范,简化了学习的困难。
spring: spring复习_右眸Remnant的博客-CSDN博客



