静态代理:
通过set或者构造的方式将需要代理的类注入到代理类中,所以可以知道的是:
代理类也是在编译阶段生成,然后他就会变成.class文件中,可以理解为编译增强
package com.huang.demo02; public class UserServiceImpl implements UserService{ @Override public void add() { System.out.println("增加用户"); } @Override public void delete() { System.out.println("删除用户"); } @Override public void update() { System.out.println("修改用户"); } @Override public void query() { System.out.println("查询用户"); } }代理类:
package com.huang.demo02; public class Proxy implements UserService { private UserServiceImpl userService; public void setUserService(UserServiceImpl userService) { this.userService = userService; } @Override public void add() { log("add"); userService.add(); } @Override public void delete() { log("delete"); userService.delete(); } @Override public void update() { log("update"); userService.update(); } @Override public void query() { log("query"); userService.query(); } private void log(String str) { System.out.println("使用了" + str + "方法"); } }缺点:
从上面代码可以看出,代理类代理的方法是通过:注入来的被代理对象调用的,如果接口增加了方法或者修改了方法,那么被代理对象与代理类都需要修改维护;这样就比较不方便;
动态代理:
代理类在运行时创建,AOP框架不会去修改字节码,所以说硬盘中是没有代理对象的,那么它的对象是在何时产生的?都说了在运行时创建,那么它是不是在内存中产生的代理对象的;这样的话维护成本就比较小;(牛逼之处:通过反射得到目标对象以及目标对象方法,以至于不需要再维护代理类了)
package com.huang.demo04; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; //用这个类自动生成代理 public class ProxyInvocationHandler implements InvocationHandler { //被代理的接口 private Object target; public void setTarget(Object target) { this.target = target; } //生成得到代理对象 public Object getProxy() { System.out.println("看看是不是得到类加载器,啥样子"+this.getClass().getClassLoader()); return Proxy.newProxyInstance(this.getClass().getClassLoader(), target.getClass().getInterfaces(), this); } //处理代理实例并返回结果 @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable{ log(method.getName()); Object result = method.invoke(target, args); return result; } public void log(String str){ System.out.println("打印了"+str+"方法"); } }代理三部曲:1.被代理的接口 ,利用set或构造将其注入;2.得到代理对象: 利用Proxy.newProxyInstance(this.getClass().getClassLoader(), target.getClass().getInterfaces, this); //这里的this指的是实现InvocationHandler的类
看到这里,联想一下上面的话,是不是就知道Proxy对象如何产生的了:得到它的加载器将其加载到内存,根据target,也就是对象接口,和InvocationHandler得到对应的代理对象;
用户类:
package com.huang.demo04; import com.huang.demo02.UserService; import com.huang.demo02.UserServiceImpl; public class Client { public static void main(String[] args) { //真实角色 UserServiceImpl userService = new UserServiceImpl(); //代理角色(不存在) ProxyInvocationHandler pih = new ProxyInvocationHandler(); pih.setTarget(userService);//设置要处理的对象 //动态生成代理类 UserService us = (UserService) pih.getProxy(); us.add(); us.delete(); } }1.先得到真实角色 2.然后得到代理角色 3.然后将真实角色注入到代理角色当中 4.生成代理类对象 5.利用代理对象,调用方法,完事;



