Java 动态代理实现方式详解及案例
Java 动态代理实现方式详解及案例
动态代理是一种强大的设计模式,它允许我们在不修改目标对象的情况下,为其添加额外的功能。在 Java 中,实现动态代理主要有三种方式:JDK 动态代理、CGLIB 动态代理和 ByteBuddy 动态代理。
1. JDK 动态代理
JDK 动态代理是基于接口实现的,需要目标对象实现一个或多个接口。
// 创建接口
public interface UserDao {
void save();
}
// 创建目标对象
public class UserDaoImpl implements UserDao {
@Override
public void save() {
System.out.println('保存用户信息');
}
}
// 创建代理对象的实现类
public class UserDaoProxy implements InvocationHandler {
private Object target;
public Object bind(Object target) {
this.target = target;
return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println('开启事务');
Object result = method.invoke(target, args);
System.out.println('提交事务');
return result;
}
}
// 测试
public class Test {
public static void main(String[] args) {
UserDao userDao = new UserDaoImpl();
UserDao proxy = (UserDao) new UserDaoProxy().bind(userDao);
proxy.save();
}
}
2. CGLIB 动态代理
CGLIB 动态代理是基于子类实现的,不需要目标对象实现接口。它通过继承目标类并重写方法来实现代理。
// 创建目标对象
public class UserDao {
public void save() {
System.out.println('保存用户信息');
}
}
// 创建代理对象的实现类
public class UserDaoProxy implements MethodInterceptor {
private Object target;
public Object bind(Object target) {
this.target = target;
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(target.getClass());
enhancer.setCallback(this);
return enhancer.create();
}
@Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
System.out.println('开启事务');
Object result = proxy.invokeSuper(obj, args);
System.out.println('提交事务');
return result;
}
}
// 测试
public class Test {
public static void main(String[] args) {
UserDao userDao = new UserDao();
UserDao proxy = (UserDao) new UserDaoProxy().bind(userDao);
proxy.save();
}
}
3. ByteBuddy 动态代理
ByteBuddy 动态代理是一种基于字节码操作的代理方式,它能够在运行时动态生成代理类的字节码。
// 创建目标对象
public class UserDao {
public void save() {
System.out.println('保存用户信息');
}
}
// 创建代理对象的实现类
public class UserDaoProxy {
public static void main(String[] args) throws IllegalAccessException, InstantiationException {
Class<? extends UserDao> dynamicType = new ByteBuddy()
.subclass(UserDao.class)
.method(named('save'))
.intercept(MethodDelegation.to(UserDaoInterceptor.class))
.make()
.load(UserDao.class.getClassLoader())
.getLoaded();
UserDao userDao = dynamicType.newInstance();
userDao.save();
}
}
// 创建拦截器
public class UserDaoInterceptor {
public static void save() {
System.out.println('开启事务');
System.out.println('保存用户信息');
System.out.println('提交事务');
}
}
注意: 以上代码为示例代码,并非完整可运行代码。实际使用时,需要根据具体情况进行相应的调整和完善。
总结
本文介绍了 Java 动态代理的三种常用实现方式,并提供每个方式的代码案例。您可以根据自己的需求选择合适的方式来实现动态代理。
动态代理在 AOP(面向切面编程)、事务管理、权限控制等方面都有着广泛的应用。掌握动态代理技术,能够帮助您更好地理解和使用 Java 语言。
原文地址: https://www.cveoy.top/t/topic/yvt 著作权归作者所有。请勿转载和采集!