一、XML
- 作用:作为配置文件、存储数据、传输数据、描述数据
- 文档声明:
<?xml version="1.0" encoding="utf-8" ?>
要写在第一行第一列 - 特殊字符:
- CDATA区(解析器忽略其中的内容,直接当作文本)
格式:<![CDATA[任意内容,但不能写"]]>"]]>
二、XML约束
- 分为两种:
- dtd约束
- schema约束
三、XML解析
- DOM解析:
- 原理:将xml文件加载到内存,形成一棵dom树
- 优点:可以进行增删改查
- 缺点:如果xml文件太大,dom树占内存多,解析慢,可能会内存溢出
- 其中:Document(文档节点)、Element(标签节点)、Text(文本节点)、Attribute(属性节点)、Comment(注释节点)
- SAX解析
- 原理:逐行读取,内存中只有读取的那一行
- 优点:内存占用很小,速度快
- 缺点:只能读取,不能回写
- pull解析
- Android 内置解析器
- 常用xml解析(jar包)
- JAXP:JDK自带,支持dom和sax
- JDOM:
- DOM4J: 支持dom和sax
- JSOUP:爬虫,解析html
- DMO4J的使用(没有如约束)
- xml文件
<?xml version="1.0" encoding="UTF-8" ?>
<studnets>
<studnet id="01">
<name>张三</name>
<age>18</age>
</studnet>
<studnet id="02">
<name>李四</name>
<age>19</age>
</studnet>
</studnets>
```
//1.创建SaxReader对象
SAXReader saxReader=new SAXReader();
//2.读取xml文件,获得输入流,读取src目录下文件
InputStream is = demo01.class.getClassLoader().getResourceAsStream("Student.xml");
//3.获得文档对象
Document document = saxReader.read(is);
//4.获得根元素 studnets
Element rootElement = document.getRootElement();
//5.获得根标签的所有子标签
List<Element> elements = rootElement.elements();
//6.获得第一个子标签
Element element = elements.get(0);
//7.获得第一个子标签的属性值 id
String id = element.attributeValue("id");
```
- XPath的使用,基于dom4j(导入 jaxen-1.1-beta-6.jar和DOM4J包)
//8.1获得一个标签 Element nameElement = (Element) document.selectSingleNode("/students/student/name"); //8.2获得子标签student集合 List<Element> list = document.selectNodes("/students/student");
四、动态代理:
-
代理模式:
- 作用:对目标类进行增强,增强一个类中的某个方法.对程序进行扩展. Spring框架中AOP.
- 使用场景:在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。(租房–>中介–>房东)
- 与装饰者模式相比:装饰者模式可以对实现了同一个接口的类进行增强(多态),而代理是对指定类进行增强(指定对象)
- 静态代理和动态代理的区别:静态代理有有具体的代理类,动态代理是通过反射生成一个代理对象
-
静态代理:
//接口类 public interface FangZhi { public void fangZhi01(); public void fangZhi02(); }
//房东有房子 public class FangDong implements FangZhi{ @Override public void fangZhi01() { System.out.println("出租房,888元每月,不包水电"); } @Override public void fangZhi02() { System.out.println("出租房,666元每月,不包水电"); } }
//中介的房子是房东的 public class Zhongjie implements FangZhi{ private FangDong fangDong; public Zhongjie() { fangDong=new FangDong(); } //增强的方法 @Override public void fangZhi01() { System.out.println("出租房,1288元每月,不包水电"); } @Override public void fangZhi02() { fangDong.fangZhi02(); } }
public class ZhuKe { public static void main(String[] args) { //租客通过中介租房子 Zhongjie zhongjie=new Zhongjie(); zhongjie.fangZhi01();//增强的方法 zhongjie.fangZhi02();//实际调用的是房东的方法 //租客直接找房东找房子 FangDong fangDong=new FangDong(); fangDong.fangZhi01(); fangDong.fangZhi02(); } }
-
动态代理:
public class ZhuKe { public static void main(String[] args) { FangZhi target=new FangDong(); InvocationHandler invocationHandler=new InvocationHandler() { @Override //参数1: proxy,代理对象,没有用 //参数2:method,代理类当前执行的方法 //参数3:argus,代理类当前执行方法的实际参数 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { //获取方法名 String methodName = method.getName(); //房子1租金上涨 if ("fangZhi01".equals(methodName)){ System.out.println("出租房,1288元每月,不包水电"); return null; } //执行不增强目标的方法 return method.invoke(target,args); } }; Class[] interfaces=new Class[]{FangZhi.class}; //1.代理类 //参数1:类加载器,程序运行时,创建的新类,需要类加载器将其加载到内存中 固定写法:当前类名.class.getClassLoader() //参数2: 实现的接口的class类,是一个数组参数,new Class[]{接口.class,...} //参数3:处理类 InvocationHandler,代理类调用每一个方法都会执行invoke方法 FangZhi proxyObj=(FangZhi) Proxy.newProxyInstance(ZhuKe.class.getClassLoader(),interfaces,invocationHandler); proxyObj.fangZhi01(); proxyObj.fangZhi02(); } }