jdk和cglib动态代理
程序员文章站
2022-06-17 20:22:06
...
静态代理和动态代理
- 静态代理:代理类在编译期已经存在在.class文件中。
- 动态代理:程序运行时,通过反射机制动态创建而成。
- 如果需要为不同的主题类提供代理,需要一一增加代理类,导致类个数急剧增加,所以需要在运行时创建动态代理。
动态代理
原理
- jdk动态代理需要主题类实现接口,使用实现相同接口的代理类代理主题类。如果主题类没有实现接口,则需要使用cglib动态代理。
- cglib使用继承实现代理,针对指定的类创建一个子类,覆盖其中的方法实现增强。无法对final代理。
jdk
- jdk动态代理通过Proxy和InvocationHandler接口实现。
- Proxy:提供创建动态代理类和对象的方法。
public static Class<?> getProxyClass(ClassLoader loader, Class<?>... interfaces) throws IllegalArgumentException
public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) throws IllegalArgumentException
- InvocationHandler:实现增强的业务逻辑。
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable;
- 实例。
public class DaoHandler implements InvocationHandler {
private Object subject;
public DaoHandler(Object subject) {
this.subject = subject;
}
public DaoHandler() {
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
beforeInvoke();
Object result = method.invoke(subject, args);
afterInvoke();
return result;
}
private void beforeInvoke() {
System.out.println("beforeInvoke");
}
private void afterInvoke() {
System.out.println("afterInvoke");
}
}
public class Client {
public static void main(String[] args) {
AbstractUserDao userDao = new UserDao();
InvocationHandler handler = new DaoHandler(userDao);
AbstractUserDao proxy = (AbstractUserDao) Proxy
.newProxyInstance(AbstractUserDao.class.getClassLoader(), new Class[]{AbstractUserDao.class}, handler);
System.out.println(proxy.findUser(""));
}
}
cglib
- cglib动态代理通过Enhancer和MethodInterceptor接口实现。
- Enhancer:创建代理对象。
public Object create()
- MethodInterceptor:实现增强的业务逻辑。
Object intercept(Object var1, Method var2, Object[] var3, MethodProxy var4) throws Throwable;
- 实例。
public class UserDaoProxyHandler implements MethodInterceptor {
private Object subject;
public UserDaoProxyHandler(Object subject) {
this.subject = subject;
}
public UserDaoProxyHandler() {
}
public Object getInstance() {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(this.subject.getClass());
//设置回调方法
enhancer.setCallback(this);
//创建代理对象
return enhancer.create();
}
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
beforeInvoke();
Object result = methodProxy.invokeSuper(o, objects);
afterInvoke();
return result;
}
private void beforeInvoke() {
System.out.println("beforeInvoke");
}
private void afterInvoke() {
System.out.println("afterInvoke");
}
}
public class Client {
public static void main(String[] args) {
UserDao userDao = new UserDao();
UserDao proxy = (UserDao) new UserDaoProxyHandler(userDao).getInstance();
System.out.println(proxy.findUser(""));
}
}
推荐阅读
-
关于.NET动态代理的介绍和应用简介
-
详解Spring的两种代理方式:JDK动态代理和CGLIB动态代理
-
Spring学习之动态代理(JDK动态代理和CGLIB动态代理)
-
Mybaits 源码解析 (十一)----- 设计模式精妙使用:静态代理和动态代理结合使用:@MapperScan将Mapper接口生成代理注入到Spring
-
java代理 jdk动态代理应用案列
-
关于.NET动态代理的介绍和应用简介
-
Java JDK动态代理(AOP)的实现原理与使用详析
-
Java JDK 动态代理的使用方法示例
-
你必须会的 JDK 动态代理和 CGLIB 动态代理
-
Java使用JDK与Cglib动态代理技术统一管理日志记录