Java动态代理、XML、正则
15.1 动态代理
在之后学习Spring框架时,Spring框架有一大核心思想,就是AOP,(Aspact-Oriented-Programming 面向切面编程) 而AOP的原理就是Java的动态代理机制,在Java的动态代理机制中,有两个重要的类或接口,一个是 InvocationHandler(Interface)、另一个则是 Proxy(Class),这一个类和接口是实现我们动态代理所必须用到的
15.1.1 动态代理的基础
动态代理的基础 : 必须有接口
Java中使用接口来定义统一的行为规范 : 接口.
接口必须有实现类:
interface SuperStar 超级明星
行为规范 :
void sing(int money);
void liveShow(int moeny);
void sleep();
// 接口必须有实现类 :
1. L implements SuperStar
2. B implements SuperStar
Proxy 代理类 :
Class Proxy 代理类 是在运行时创建的实现指定的接口列表(称为代理接口)的类 。 代理实例是代理类的一个实例。 每个代理实例都有一个关联的调用处理程序对象,它实现接口InvocationHandler 。 通过其代理接口之一的代理实例上的方法调用将被分派到实例调用处理程序的invoke方法
static Object newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h) 返回指定接口的代理实例,该代理实例将方法调用分派给指定的调用处理程序。
15.1.2 动态代理作用:
拦截和控制 被代理对象 的所有行为
15.1.3 InvocationHandler 调用处理器
Interface InvocationHandler 每个代理实例都有一个关联的调用处理程序。 当在代理实例上调用方法时,方法调用将被编码并分派到其调用处理程序的invoke方法。
15.1.4 案例
15.2 XML
简介 : XML全称为Extensible Markup Language,意思是可扩展的标记语言。
标记 -> 用标记来修饰文本信息.
可扩展 -> 标记可随意定义.
XML技术 : 与数据相关技术, 在企业中xml技术常用来存储数据和传输数据, xml之所以流行的原因在于xml语言与任何编程语言无关, xml可用于 php, java, .net任何编程语言.
15.2.1 书写一个xml配置文件
xml编写时也要符合一定的规则 :
1)xml文件的后缀名是.xml
2)xml有且只有一个根标签
3)xml的标签是尖括号包裹关键字成对出现的,有开始标签有结束标签,关键字是自定义的, xml也可以有空标签/自关闭标签
4)xml允许有属性,属性也是根据需要自定义的,属性格式:属性= "属性值",多个属性之间使用空格隔开
5)xml是区分大小写的
xml 的组成
1)文档声明:<?xml version="1.0" encoding="UTF-8" ?>
2)根标签,例如: <store>
3)其他标签,例如:<name>
4)属性,例如:category="手机数码"
5)文本,例如:华为手机
6)注释,例如:<!-- 这是xml文档的根标签 -->
15.2.2 约束介绍 DTD ,Schema
15.2.3 xml 解析:
XML的实际应用场景 :
实际开发中,我们一般会使用各种各样的框架进行企业开发,而这些框架一般都会将某些公共的功能都已经写好,我们需要做的只需要按照框架提供的约束进行框架的配置就可以了,当我们使用XML配置好框架后,再运行时,框架底层会解析我们配置XML文档获取有用的信息,从而根据我们的需求实现某些功能。
所以,实际开发中我们很少会自己编写XML约束和解析XML.
@Test
public void test1() throws DocumentException {
// 1. 创建一个 saxReader 解析器
SAXReader saxReader = new SAXReader();
// 2. 调用 read 方法读取 xml 配置文件, 并获取一个 document 对象
Document document = saxReader.read("books.xml");
// 3. 调用 getRootElement 方法, 获取根标签对象
Element root = document.getRootElement();
// 4. 调用 elements 方法, 获取子标签数组
List<Element> bookElements = root.elements();
// 5. 遍历 bookElements 数组
for (Element book : bookElements) {
// 6. 调用 attributeValue 方法, 传入属性名称, 获取对应的属性值
String author = book.attributeValue("author");
System.out.println("author = " + author);
// 7. 获取子标签
List<Element> elements = book.elements();
// 8. 遍历子标签
for (Element e : elements) {
// 9. 获取标签名称, 和标签体数据
String name = e.getName();
String text = e.getText();
System.out.println(name + " = " + text);
}
}
}
输出结果 :
author = 张三丰
name = Java从入门到精通
price = 98
author = 灭绝师太
name = Java编程思想
price = 998
@Test
public void test2() throws DocumentException {
// 1. 创建一个 saxReader 解析器
SAXReader saxReader = new SAXReader();
// 2. 调用 read 方法读取 xml 配置文件, 并获取一个 document 对象
Document document = saxReader.read("beans.xml");
// 3. 调用 getRootElement 方法, 获取根标签对象
Element root = document.getRootElement();
// 4. 调用 elements 方法, 获取子标签数组
List<Element> beanElements = root.elements();
// 5. 调用 elements 方法, 获取子标签数组
for (Element bean : beanElements) {
// 6. 调用 attributeValue 方法, 传入属性名称, 获取对应的属性值
String id = bean.attributeValue("id");
String className = bean.attributeValue("className");
System.out.println(id + " = " + className);
// 7. 调用 elements 方法, 获取子标签数组
List<Element> propElements = bean.elements();
// 8. 调用 propElements 方法, 获取子标签数组
for (Element prop : propElements) {
// 9. 调用 attributeValue 方法, 传入属性名称, 获取对应的属性值
String name = prop.attributeValue("name");
String value = prop.attributeValue("value");
System.out.println(name + " = " + value);
}
}
}
输出结果 :
001 = cn.itcast.bean.User
username = ZhangSan
password = 123456
002 = cn.itcast.bean.User
username = LiSi
password = 654321
15.3 正则表达式
15.3.1 正则概念
egular Expression 正则表达式 : 在Java中, 正则主要使用在 String 类的方法参数为 regex 的名称上
String 类的三个带 regex 参数的方法 :
split(String regex) 切割.
matches(String regex) 匹配.
replaceAll(String regex, String replacement) 替换.
15.3.2 符号介绍
1. [] 取值的范围. 0-9 数值0到9都成立.
说明 : [0-9] 可以使用 \\d 表示
2. {} 表示前一个条件中 `值 / 字符` 可以出现的次数.
说明 : {4,11} 至少4次, 最多11次.
{0,1} 至少0次,最多一次. 可以使用 ? 表示.
{1,} 至少1次,最多无限次 可以使用 + 表示.
{0,} 至少0次,最多无限次. 可以使用 * 表示.
3. () 表示分组. 在replaceAll方法的第二个参数上可以使用 $ 符号来引用之前的分组,分组编号自动从1开始.
15.3.3 案例
public class ReplaceAllTest4 {
public static void main(String[] args) {
// 13311111946 -> 133****1946
String phone = "13311111946";
/*
源数据 : 13311111946
第一部分 : 133 规则一 : 1[34578]\\d
第二部分 : 1111 规则二 : \\d{4}
第三部分 : 1946 规则三 : \\d{4}
*/
String result = phone.replaceAll("(1[34578]\\d)(\\d{4})(\\d{4})", "$1****$3");
System.out.println("result = " + result);
}
}
输出结果 :
result = 133****1946