1.类和对象(实例)的关系
类就是对象的抽象(模板),对象就是类的实例
2.java设置模式--代理模式
定义:代理就是中介,例如租房子经常有中介,还有出票软件 飞猪,携程。
3.代理大纲分为两种:静态代理与动态代理,主要区别在于代理对象是自定义还是系统生成。自定义的为静态代理,自动生成的为动态代理
4.静态代理--举一个我们生活中买房子的事情中介事情
package jav.com.study.proxy.staticProxy; //这是我们生活中买房子的事情中介事情 public interface SellHome { public void sell(); }
package jav.com.study.proxy.staticProxy; //这是目标类--房子开发商 public class Developer implements SellHome { @Override public void sell() { System.out.println("这是开发商建造后需要销售的房子"); } }
package jav.com.study.proxy.staticProxy; //这是代理,即为中介 public class Medium implements SellHome{ SellHome sellHome; Medium(SellHome sellHome){ this.sellHome=sellHome; } @Override public void sell() { System.out.println("买房子前咨询一下"); System.out.println("买房子前参观"); System.out.println("买房子签合同"); sellHome.sell(); System.out.println("买房子付款"); } }
以上有我们生活中的行为类(接口),还有目标类(开发商的房子售卖的事情),中介,现在做一下用户测试
package jav.com.study.proxy.staticProxy; public class Client { public static void main(String[] args) { //创建中介,传入target SellHome sellHome=new Medium(new Developer()); sellHome.sell(); } }
Connected to the target VM, address: '127.0.0.1:54952', transport: 'socket' Disconnected from the target VM, address: '127.0.0.1:54952', transport: 'socket' 买房子前咨询一下 买房子前参观 买房子签合同 这是开发商建造后需要销售的房子 买房子付款 Process finished with exit code 0
静态代理比较容易理解,简单理解就是,中介拿到了目标类的对象,然后在目标对象的前后做手脚
5.动态代理 --有JDK动态代理,CGLib动态代理等,我们就讲JDK动态代理---还是买房子这件事情
首先不变的有两个类--- 开发商目标类Developer,还有我们买房子这件事 SellHome
然后先跟大家隆重介绍两个新角色 ,不然都不敢说自己是动态代理了,不然怎么和静态代理区别呢
(1)InvocationHandler 这是一个处理器,主要就是每次要执行目标方法的时候,都会跑到InvocationHandler里面的invoke方法(到现在我都不知道底层是怎么实现的,不过我猜测可能是对目标类的各种方法做了listener监听)
(2)Proxy类,刚刚我们说动态代理的代理对象是系统生成的,其实就是Proxy这个大佬生成的
有这两个角色,我们接着讲,我们还得创建一个实现InvocationHandler接口的实现类,创建的时候,把目标对象传给SellHandler,他就像会对目标对象盯得紧紧的
package jav.com.study.proxy.dynamicProxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; public class SellHandler implements InvocationHandler { Object target; SellHandler(Object o){ this.target=o; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("买房子前咨询一下"); System.out.println("买房子前参观"); System.out.println("买房子签合同"); method.invoke(this.target,args); System.out.println("买房子付款"); return null; } }
其次创建Client,我们来看一下
package jav.com.study.proxy.dynamicProxy; import java.lang.reflect.Proxy; public class Client { public static void main(String[] args) { //第一步创建目标类 SellHome sellHome=new Developer(); //第二步创建控制类 SellHandler sellHandler=new SellHandler(sellHome); //第三步创建代理对象 SellHome proxy= (SellHome) Proxy.newProxyInstance(sellHome.getClass().getClassLoader(), sellHome.getClass().getInterfaces(),sellHandler); //第四步骤代理类调用目标类方法 proxy.sell(); } }
Connected to the target VM, address: '127.0.0.1:56137', transport: 'socket' Disconnected from the target VM, address: '127.0.0.1:56137', transport: 'socket' 买房子前咨询一下 买房子前参观 买房子签合同 这是开发商建造后需要销售的房子 买房子付款 Process finished with exit code 0
效果是一样的
动态代理肯定是比静态代理好,少写很多代码,统一处理
---今天20200504
研究了一下cglib动态代理
这个比jdk动态代理更强大--不分是否有接口
就是给我们的目标类创建一个代理类,那么我们得有目标类,即如下
// 目标类 public class CglibClass { public final void testHideFinal(){ System.out.println("这是不能展示的"); } public void testShowFinal(){ System.out.println("这是可以展示的"); } }
还有生成代理类的类,我们就叫代理工厂吧
//代理工厂 public class CGLibProxy implements MethodInterceptor { Object o; public Object createProxyObject(Object obj){ this.o=obj; Enhancer enhancer=new Enhancer(); enhancer.setSuperclass(obj.getClass()); enhancer.setCallback(this); Object newProxy=enhancer.create(); return newProxy; } @Override public Object intercept(Object p, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { System.out.println("开始进行权限检测"); Object ret=method.invoke(o,objects); System.out.println("检测完毕"); return ret; } }
-- 接下来测试
public class ProxyTest { public static void main(String[] args) { CGLibProxy cgLibProxy=new CGLibProxy(); CglibClass cglibClass= (CglibClass) cgLibProxy.createProxyObject(new CglibClass()); cglibClass.testHideFinal(); cglibClass.testShowFinal(); } }
-- 输出
这是不能展示的
开始进行权限检测
这是可以展示的
检测完毕
Process finished with exit code 0
注意:这里为什么testHideFinal()前后没有进行权限检测呢?这是因为使用了final的方法,使得新创建的代理类不能够继承,所以就没有前后输出检测的信息
---今天是2019.10.15 我温故一下
二.工厂方法模式
工厂方法主要是吧对象的生产和使用分离开,主要涉及的类有四个,抽象工厂,具体工厂,抽象产品,具体产品(参考出自http://c.biancheng.net/view/1348.html)
具体代码:
创建一个接口 Product
class Interface Product{ public void show(); }
然后创建实现类
class Product1 implement Product{ public void show{ System.out.print("这是产品1"); } } class Product2 implement Product{ public void show{ System.out.print("这是产品2"); } }
创建抽象工厂
Class Interface ProductFactory{ public Product getProduct(); }
创建抽象工厂实现类
Class ProductFactory1 implement ProductFactory{ public Product getProduct(){ System.out.print("工厂1->创建产品1"); } } Class ProductFactory2 implement ProductFactory{ public Product getProduct(){ System.out.print("工厂2->创建产品2"); } }
最后写测试
Class ClientTest{ public static void main(String[] args){ //获取配置信息,具体可以自己写一个 ProductFactory pf=(ProductFactory) ReadXML1.getObject(); Product p=pf.getProduct(); p.show(); } }
三.抽象工厂模式
比较工厂模式,竖向多了一个产品等级