1.代理模式介绍
2.用代码演示代理模式
3.总结
1.代理模式介绍
定义:
1)代理模式,为代理对象提供一个替身,以管制这个对象的拜访,就是通过代理对象来拜访对象。这样做的益处是:能够在指标对象的根底上,再减少额定的加强操作。
2)被代理的对象能够是近程对象,创立开销大的字段和须要安全控制的字段
3)代理模式有三种不同的模式,动态代理,动静代理,和cglib代理。
形容:
代理最驰名的应用场景就是人尽皆知的AOP,就拿咱们很相熟的事务注解@Transactional来说,咱们晓得加上了这个注解后,函数办法就会成为事务操作。
咱们都晓得,用sql写事务的时候, 如果咱们要进行事务操作,须要写两个这样的sql语句:
start transaction;//两头执行业务逻辑commit;
这时咱们写好了两头的业务逻辑,加上注解之后,相当于把这个对象交给了一个代理对象,让代理对象执行开启事务和完结时的逻辑,咱们只有编写业务逻辑就好了。同时这个办法也失去了加强,有了前置和后置办法,有了事务的成果,加强额定的性能操作。
2.用代码演示依代理模式
1)动态代理
动态代理模式的根本介绍:
动态代理在应用的时候,须要定义接口或者父类,被代理对象(指标对象)与代理对象一起实现独特的接口或者是继承雷同的父类。
具体要求
1)定义一个接口ITeacherDao
2)指标对象TeacherDAO实现接口ITeacherDAO
3)定义一个代理对象TeacherProxy,也实现ITeacherDao
4)调用的时候通过调用代理对象的办法来调用指标对象
5)代理对象与指标要实现雷同的接口,而后通过调用雷同的办法来调用指标对象的办法。
代码展现
ITeacherDao:
public interface ITeacherDao { void teach();//授课的办法}
TeacherDao:
public class TeacherDao implements ITeacherDao { @Override public void teach() { System.out.println("老师开始上课了!"); }}
TeacherProxy:
public class TeacherProxy implements ITeacherDao { //先把要代理的对象传进来 private ITeacherDao target = new TeacherDao(); public TeacherProxy(ITeacherDao target) { this.target = target; } //执行代理办法,在办法前后进行加强 @Override public void teach() { System.out.println("代理开始"); target.teach(); System.out.println("代理完结"); }}
public static void main(String[] args) { //被代理对象 ITeacherDao iTeacherDao = new TeacherDao(); //代理对象 TeacherProxy teacherProxy = new TeacherProxy(iTeacherDao); //执行代理对象的办法 teacherProxy.teach(); }
长处:合乎开闭准则,能对指标对象进行扩大。
毛病:为每一个须要加强的服务都须要创立类,容易造成类爆炸。
2)动静代理
动静代理根本介绍:
1)代理对象不须要实现接口,然而指标对象要实现接口,否则不能应用
2)代理对象的生成,是利用jdk的api,动静的在内存中构建代理对象
3)动静代理也叫作:jdk代理,接口代理
代码实现:
ITeacherDao:
public interface ITeacherDao { void teach();//授课的办法}
TeacherDao:
public class TeacherDao implements ITeacherDao { @Override public void teach() { System.out.println("老师开始上课了!"); }}
ProxyFactory:
public class ProxyFactory { //保护一个指标对象 private Object target; //创立结构器对一个指标对象进行初始化 public ProxyFactory(Object target) { this.target = target; } public Object getProxyInstance() { //以后对象应用的指标类加载器 ClassLoader classLoader = target.getClass().getClassLoader(); //指标对象实现的接口类型,应用泛型的形式确认类型 Class<?>[] classes = target.getClass().getInterfaces(); //执行指标对象的办法时,会登程事件解决办法,会把以后执行的对象当做参数传入 InvocationHandler invocationHandler = null; return Proxy.newProxyInstance(classLoader, classes, new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { //加强逻辑 System.out.println("JDK代理开始"); //原办法执行逻辑,执行完之后返回值 Object invoke = method.invoke(target, args); System.out.println("JDK代理完结"); return invoke; } }); }}
要留神一下Proxy.newProxyInstance() 办法有三个参数,
Proxy.newProxyInstance()办法承受三个参数:
ClassLoader loader:指定以后指标对象应用的类加载器,获取加载器的办法是固定的
Class<?>[] interfaces:指定指标对象实现的接口的类型,应用泛型形式确认类型
InvocationHandler:指定动静处理器,执行指标对象的办法时,会触发事件处理器的办法
只须要依照上述的正文传入就能够了,用法也是非常简略。
长处:动静代理大大减少了咱们的开发工作,同时缩小了业务接口依赖。
毛病:始终无奈解脱interface代理的枷锁,无奈实现对class的动静代理。
3)cglib代理
1)须要引入cglib的依赖
2)通过字节码技术为一个类创立子类,并在子类中采纳办法拦挡的技术拦挡所有父类办法的调用,趁势织入横切逻辑。
代码展现:
TeacherDao:
public class TeacherDao { public void teach() { System.out.println("老师开始上课了!"); }}
CglibProxyFactory:
public class CglibProxyFactory implements MethodInterceptor { //要加强的指标类 private Object target; public CglibProxyFactory(Object target) { this.target = target; } public Object getProxyInstance() { // 创立工具类 Enhancer enhancer = new Enhancer(); //设置父类 enhancer.setSuperclass(target.getClass()); //设置回调函数 enhancer.setCallback(this); //创立子类对象,即代理对象 return enhancer.create(); } //重写intercept,会调用指标对象的办法 @Override public Object intercept(Object obj, Method method, Object[] args, MethodProxy methodProxy) throws Throwable { //加强的逻辑 System.out.println("cglib开始"); //执行结束后返回的参数 Object invoke = methodProxy.invokeSuper(obj, args); //加强的逻辑 System.out.println("cglib完结"); //返回参数 return invoke; }}
public static void main(String[] args) { //指标代理对象 TeacherDao target = new TeacherDao(); //代理工厂 CglibProxyFactory cglibProxyFactory = new CglibProxyFactory(target); //从代理工厂返回代理对象 TeacherDao proxyInstance = (TeacherDao) cglibProxyFactory.getProxyInstance(); //执行代理对象的办法 proxyInstance.teach(); }
长处:能对class进行加强,CGLIB创立的动静代理对象比JDK创立的动静代理对象的性能更高。
毛病:CGLIB创立代理对象时所破费的工夫比JDK多得多,而且编码不是十分不便,同时因为CGLib因为是采纳动态创建子类的办法,对于final润饰的办法无奈进行代理。
3.总结
代理模式就是spring底层AOP的实现办法,目标就是为了把一些加强切入到业务逻辑代码里,并将这个切面对立治理。