第六讲 静态代理
1、静态代理的角色分析:
抽象角色------一般使用接口或者抽象类来实现。
真实角色------被代理的角色 (租房子的人)
代理角色------代理真实角色--代理真实角色后一般会做一些附属操作。 (中介租房,添加其他方法功能)
客户------------使用代理角色来进行一些操作
2、代码 略见/07spring4_staticproxy
3、使用静态代理好处:
使得真实角色处理的业务更加纯粹,不再去关注一些公共的事情。(公共的事情(切面)交由代理类去切入)
(1、dao接口的实现类需要有事务,但每一个实现类都加相同的不好,让一个代理类去实现dao接口,然后在里面添加事务代码 2、service接口的实现类需要有日志,每一个方法都需要去加很麻烦,那么就将它抽取出来)
公共的业务由代理来完成----实现了业务的分工
公共业务发生扩展时变得更加集中和方便
缺点: 类多了----多了代理类,工作量变大了,有一个service就必须要有一个代理类,开发效率降低了,所以静态代理太不爽
现在又想有静态代理的好处,又不想多写类,就有了----动态代理
第七讲 动态代理(动态代理指的是可以动态生成代理类,所以抽象角色和真实角色都应该存在)
1、动态代理和静态代理的角色是一样的。
2、动态代理的代理类是动态生成的,刚才静态代理的代理类是提前写好的。
3、分为两类----基于接口动态代理和基于类的动态代理
a) 基于接口动态代理---jdk动态代理(下面学的)
b) 基于类的动态代理---cglib
现在javasist来生成动态代理。
4、jdk动态代理---了解Proxy类和invocationHandler接口
实现代码:看代码理解;
抽象角色
真实角色
代理角色
package cn.sxt.dynamicproxy;
import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; 这个类是一个动态代理类,省去了静态代理要写很多类的麻烦,下面的private Object;对象已将其扩展的一般情况下 public class ProxyInvocationHandler implements InvocationHandler { private Rent rent; //由于它代理的可能是任何类型,不止Rent类型,所以增加一个Object target类型 private Object target; //目标对象----真实对象 public void setTarget(Object target) { this.target = target; } public void setRent(Rent rent) { this.rent = rent; } /** * 生成代理类方法,这个方法也可以不写在这个类中,写在这方便 */其实这个方法可以写在外面的 public Object getProxy() { return Proxy.newProxyInstance(this.getClass().getClassLoader(), target.getClass().getInterfaces(), this); // return Proxy.newProxyInstance(this.getClass().getClassLoader(), // target.getClass().getInterfaces(), this); } /** * proxy是生成的代理类 * * method是代理类的调用处理程序的方法对象 */ @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { log(method.getName()); seeHouse();//放在这个方法执行的前边 ////这里方法.invoke(),target表示真实对象,现在对象没有,所以在上面给它一个真实对象private Rent rent; Object result = method.invoke(target,args); 这个才是核心方法,修给invoke()第一个参数(比如这里给为cent)再修改上面方法的target.class
(改为cent.class)
就可以实现不同的对象调用 fare();//放在这个方法执行的后边 returnpublic void log(String methodName) { System.out.println("执行"+methodName+"方法"); } //看房 private void seeHouse() { System.out.println("带房客看房"); } //收中介费 private void fare() { System.out.println("收取中介费"); } }
客户端
上面代码理解了后,只要我有接口,我就可以代理
一个动态代理一般代理某一类业务,一个动态代理可以代理多个类。