谷歌增强Car问题
1 2 3 4 5 public interface ICar { public void start(); //启动 public void run(); //运行 public void stop(); //停止 }
希望在将谷歌Car 接入到生态圈平台时,增强汽车启动功能
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 public final class GoogleCar implements ICar { //我已经final了 不让任何类继承我去重写方法 @Override public void start() { System.out.println("GoogleCar判断天气是否良好"); System.out.println("GoogleCar判断情况是否良好"); System.out.println("GoogleCar控制谷歌汽车启动"); //调用谷歌汽车提供的c语言函数 } @Override public void run() { System.out.println("控制谷歌汽车运动"); } @Override public void stop() { System.out.println("控制谷歌汽车停止"); } }
**1.手动在谷歌Car上自己添加(除非开发的时候把源码给你)
**2.new一个类继承谷歌Car,重写方法(除非谷歌Car不是final 可以被继承)
**3.new一个类实现Icar,增强方法(装饰者模式)**
装饰者模式(实现接口)
使用环境: 适用于二次开发 的时候,无法(×)获取到源码(不能在源码更改),无法(×)使用继承(不能重写)前提下,要对已存在对象上的功能增强 .
前提: 可以获取到被装饰的对象GoogleCar实现的所有接口 ICar
实现思路: new一个类实现ICar接口,然后test测试的时候new的对象是GoogleCar对象
弊端: 如果被实现的接口中的方法过多,装饰类中的方法过多冗余(原来的方法不能太多)
MyCar(新创建的类 实现原来的接口)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 public class MyCar implements ICar{ ICar car; //构造方法 public MyCar(ICar car) { this.car=car; //通过TestCar里面new的对象传过来 } @Override public void start() { System.out.println("MyCar判断天气是否良好"); //增强的部分 System.out.println("MyCar判断路况是否拥堵"); //增强的部分 car.start(); } @Override public void run() { car.run(); } @Override public void stop() { car.stop(); } }
测试类TestCar
1 2 3 4 5 6 7 8 public class TestCar { public static void main(String[] args) { ICar car=new MyCar(new GoogleCar()); //面向接口编程 右边new的是GoogleCar对象 car.start(); car.run(); car.stop(); } }
分析: 其实就是test里面new的对象 –> 新写的增强MyCar的构造方法接收 –> 然后调用方法(里面既有新写的方法内容 + 谷歌原来的方法内容)
动态代理(字节码)
解决装饰者模式中实现方法太多接口的冗余问题
在class类里面本来就有.class的文件用于虚拟机识别的字节码:
只是在前面ICar和GoogleCar的基础上直接写test测试用字节码方式:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 public class TestCar { public static void main(String[] args) { //使用字节码 //1param: 固定值: 告诉虚拟机用哪个字节码加载器加载内存中创建出的字节码文件 //2param: 告诉虚拟机内存中正在被创建的字节码文件中应该有哪些方法 //3param: 告诉虚拟机正在被创建的字节码上的各个方法如何处理 ICar car=(ICar)Proxy.newProxyInstance(TestCar.class.getClassLoader(), GoogleCar.class.getInterfaces(),new InvocationHandler() { //第三个参数使用匿名内部类 //method:代表正在执行的方法 //args:代表正在执行的方法中的参数 //Object:代表方法执行完毕之后的返回值 @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { if(method.getName().equalsIgnoreCase("start")){ //让你本来有的方法和要改变的方法对比 System.out.println("检查天气是否良好"); method.invoke(new GoogleCar(), args); //这是固定的调用GoogleCar的方法 System.out.println("检查路况是否拥堵"); //增强的方法(位置可以变化) } else { method.invoke(new GoogleCar(), args); //这是固定的调用GoogleCar的方法 } return null; } }); car.start(); //调用方法输出结果 car.run(); car.stop(); } }
字节码加载器(3种 – 系统引导加载器): jdk有一些程序 – 专门将各种字节码文件 – > 到内存 (IO流技术 )
动态代理解决全站乱码 1.项目中新建一个页面Index.html
1 2 3 4 5 6 7 8 9 10 11 <h1>post方式提交中文</h1> <form action="/day18_v3/ServletDemo" method="post"> User:<input type="" name="username"/><br/> <input type="submit"/> </form> <h1>get方式提交中文</h1> <form action="/day18_v3/ServletDemo" method="get"> User:<input type="" name="username"/><br/> <input type="submit"/> </form>
2.servlet代码
1 2 3 无论是在post/get方法,执行以下语句不存在中文乱码问题(可以在前面加一句防止乱码的) String um=request.getParameter("username"); //获取username System.out.println(um);
3.过滤器Filter中,为request上的getParameter()功能进行增强
判断当前的请求是get/post
request.getMethod();
如果是post,
设置一句话: request.setCharacterEncoding(“utf-8”);
放行
如果是get,
调用原先的String v=request.getParameter(name);
将v进行转码,
放行
<
redis
设计模式
>