java中代理的实现并在spring的应用
2023-12-26 15:43:29
Java代理机制介绍
Java代理机制是一种在运行时创建一个代理对象来代替原始对象的方法。代理对象通常用于在调用原始对象的方法之前或之后执行一些额外的操作,例如日志记录、性能监控等。
静态代理
静态代理是在编译时就已经确定代理的对象,代理类和原始类是一对一的关系。下面是一个简单的静态代理的例子:
// 定义接口
public interface Hello {
void sayHello();
}
// 原始类
public class HelloImpl implements Hello {
@Override
public void sayHello() {
System.out.println("Hello, world!");
}
}
// 代理类
public class HelloProxy implements Hello {
private Hello hello;
public HelloProxy(Hello hello) {
this.hello = hello;
}
@Override
public void sayHello() {
System.out.println("Before saying hello");
hello.sayHello();
System.out.println("After saying hello");
}
}
动态代理
jdk
动态代理是在运行时创建代理对象,代理类是在运行时生成的。Java提供了java.lang.reflect.Proxy
和java.lang.reflect.InvocationHandler
来实现动态代理。下面是一个简单的动态代理的例子:
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
// 定义接口
public interface Hello {
void sayHello();
}
// 原始类
public class HelloImpl implements Hello {
@Override
public void sayHello() {
System.out.println("Hello, world!");
}
}
// 动态代理类
public class DynamicProxy implements InvocationHandler {
private Object target;
public DynamicProxy(Object target) {
this.target = target;
}
public Object getProxy() {
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("Before saying hello");
Object result = method.invoke(target, args);
System.out.println("After saying hello");
return result;
}
}
cglib
下面是一个使用CGLIB实现动态代理的示例。
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
// 原始类
public class Hello {
public void sayHello() {
System.out.println("Hello, world!");
}
}
// CGLIB动态代理类
public class CglibProxy implements MethodInterceptor {
private Object target;
public CglibProxy(Object target) {
this.target = target;
}
public Object getProxy() {
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("Before saying hello");
Object result = proxy.invokeSuper(obj, args);
System.out.println("After saying hello");
return result;
}
}
jdk和cglib的区别
区别 | JDK代理 | CGLIB代理 |
---|---|---|
实现方式 | 基于接口实现 | 基于继承实现 |
目标对象 | 必须实现接口 | 可以是普通类或接口实现类 |
代理性能 | 通常比CGLIB代理慢 | 通常比JDK代理快 |
适用场景 | 目标对象实现接口的情况 | 目标对象不实现接口或需要继承实现的情况 |
生成代理对象的方式 | Proxy.newProxyInstance() | CGLIB动态生成子类 |
Spring中的代理
在Spring中,代理通常用于AOP(面向切面编程)和事务管理。Spring使用代理来实现切面的横切逻辑,并且可以通过配置来选择使用静态代理还是动态代理。
Spring提供了两种代理方式:JDK动态代理和CGLIB动态代理。默认情况下,如果目标对象实现了接口,Spring会使用JDK动态代理;如果目标对象没有实现接口,Spring会使用CGLIB动态代理。
不使用代理的场景
在一些情况下,可能不适合使用代理,例如:
- 对性能要求非常高的场景,代理会增加额外的开销。
- 原始类本身已经提供了足够的扩展点,不需要额外的代理来实现。
spring中使用代理需要注意的点
在Spring中,代理通常用于AOP
和事务管理
,而在一些特定场景下可能不适合使用代理。这里提出一点,当方法名被private修饰
或者使用this调用方法
不会生成代理类,这可能会导致事务失效
,异步任务错误的执行
等。
文章来源:https://blog.csdn.net/weixin_44808225/article/details/135221112
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!