java动态代理用在很多地方。spring框架,RPC框架中都使用了动态代理,动态代理很重要。
首先看看静态代理:
相对静态代理而已,静态代理需要对每一个方法做一次处理。如下:
定义一个实体列,交个代理类,然后由代理帮忙做事
public static void main(String[] args) {People people = new Students();ProxyManager proxyManager = new ProxyManager(people);proxyManager.findJob();}
接口
public interface People {public void findJob();}
实体类:
public class Students implements People{@Overridepublic void findJob() {System.out.println("I am student ,I am looking for a job");}}
代理类:
public class ProxyManager implements People {People people ;public ProxyManager(People people){this.people = people;}@Overridepublic void findJob() {System.out.println("I am Manager, I am help other find job");people.findJob();System.out.println("");}}
,如果实体类有多个方法,那么静态的代理类就需要复写多个方法,哪怕是做同样的事情,所以就出现动态代理。
添加一个动态代理类:
public class ProxyD {Class target;Object object;public ProxyD(Class target,Object object){this.target=target;this.object=object;}public Object getPeopele() throws Throwable{return Proxy.newProxyInstance(target.getClassLoader(),new Class[]{target}, new ObjectHandle(this.object));}class ObjectHandle implements InvocationHandler{Object target;public ObjectHandle(Object object) {this.target = object;}public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("I am Manager, I am help other find job");Object o = method.invoke(target, args);System.out.println("");return o;}}}
然后在看测试类:
People people = new Students();ProxyD proxyD=new ProxyD(People.class,people);People proxyManager =(People) proxyD.getPeopele();proxyManager.findJob();
从这里看动态类和静态的没有什么区别,但是如果接口添加一个方法,那么静态代理类将必须重写这个方法,但是动态代理就不需要,可以直接调用,
People people = new Students();ProxyD proxyD=new ProxyD(People.class,people);People proxyManager =(People) proxyD.getPeopele();proxyManager.findJob();proxyManager.findGirl();
这就是动态代理的好处,比如在做web的拦截器时,只需要在
System.out.println("I
am Manager, I am help other find job"); 改为对method的判断或者
对参数的判断,就可以达到拦截的处理。比如
if(method.getName.endwith(".jpg")){
return null;
}
接下来看看proxy底层代码是怎么实现的。
public static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h)throws IllegalArgumentException{Objects.requireNonNull(h);//接口复制- final Class<?>[] intfs = interfaces.clone();
- //安全判断,一般不会设置安全问题
final SecurityManager sm = System.getSecurityManager();if (sm != null) {checkProxyAccess(Reflection.getCallerClass(), loader, intfs);}/** Look up or generate the designated proxy class.*///去缓存查看是否已经生成过,如果生存过直接获取。没有就生存并保存到缓存中Class<?> cl = getProxyClass0(loader, intfs);/** Invoke its constructor with the designated invocation handler.*/try {if (sm != null) {checkNewProxyPermission(Reflection.getCallerClass(), cl);}//获取类的构造函数final Constructor<?> cons = cl.getConstructor(constructorParams);final InvocationHandler ih = h;if (!Modifier.isPublic(cl.getModifiers())) {AccessController.doPrivileged(new PrivilegedAction<Void>() {public Void run() {//如果私有,需要设置setAccessible为true才能读取cons.setAccessible(true);return null;}});}//反射生存对象return cons.newInstance(new Object[]{h});......}
底层就是通过反射完成的。
本文深入探讨了Java中的动态代理机制,对比静态代理,详细解析了动态代理的实现原理及其应用场景,尤其是在Spring框架和RPC框架中的应用。
java 动态代理和反射&spm=1001.2101.3001.5002&articleId=77018255&d=1&t=3&u=d3b37cd2e3fd4dc1937e7fa80b975e12)
1034

被折叠的 条评论
为什么被折叠?



