动态代理是一种常用的Java代理模式,它能够在运行时动态地生成代理类,实现对目标对象的代理访问和控制。相比静态代理,动态代理具有更高的灵活性和可扩展性,能够适应更多的场景和需求。
在Java中,动态代理主要通过Java反射机制来实现,通常需要实现一个代理类的接口,并提供一个InvocationHandler接口的实现类来处理代理对象的方法调用。在代理对象方法调用时,InvocationHandler实现类会自动调用invoke()方法,通过反射机制调用目标对象的方法,并在必要时添加额外的逻辑处理。
动态代理的优点包括:
1.灵活性强:动态代理可以在运行时动态生成代理类,不需要事先编写好代理类的代码,因此更加灵活。
2.可扩展性好:动态代理可以通过InvocationHandler接口来实现代理对象的自定义逻辑处理,可以根据具体业务需求进行自由扩展和定制。
3.结构清晰:动态代理的代理类和目标类分离,结构更加清晰,易于维护和管理。
使用动态代理的场景包括:
4.实现AOP编程:动态代理可以在方法调用前后添加额外的逻辑处理,常用于实现AOP编程,如事务管理、性能监控等。
5.实现远程方法调用:动态代理可以通过网络传输将方法调用请求发送到远程服务器,并接收返回结果,常用于实现分布式系统和微服务架构。
6.实现IOC容器:动态代理可以在运行时动态生成对象,并将其注入到IOC容器中,常用于实现Spring等框架的IOC功能。
总之,动态代理是一个非常重要和常用的Java编程技术,掌握动态代理可以提高Java程序员的编程水平和代码质量。
Java中常见的动态代理包括基于JDK实现的接口代理和基于CGLIB实现的类代理。
一、基于JDK实现的接口代理:JDK提供了java.lang.reflect.Proxy类和java.lang.reflect.InvocationHandler接口,可以通过这两个类来实现接口的动态代理。示例代码:
public interface IUserDao {
void save();
}
public class UserDaoImpl implements IUserDao {
@Override
public void save() {
System.out.println("保存用户信息");
}
}
public class UserDaoProxy implements InvocationHandler {
private Object target;
public UserDaoProxy(Object target) {
this.target = target;
}
@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) {
IUserDao userDao = new UserDaoImpl();
InvocationHandler handler = new UserDaoProxy(userDao);
IUserDao proxy = (IUserDao) Proxy.newProxyInstance(userDao.getClass().getClassLoader(),
userDao.getClass().getInterfaces(), handler);
proxy.save();
}
}
基于CGLIB实现的类代理:CGLIB是一个高性能、强大的代码生成库,可以在运行时动态生成目标类的代理子类来实现代理功能。示例代码:
public class UserDao {
public void save() {
System.out.println("保存用户信息");
}
}
public class UserDaoInterceptor implements MethodInterceptor {
@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) {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(UserDao.class);
enhancer.setCallback(new UserDaoInterceptor());
UserDao userDao = (UserDao) enhancer.create();
userDao.save();
}
}