public class user {
private int id;
private String name;
public user() {
}
public user(int id, String name) {
this.id = id;
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public interface Service {
public boolean login(String name,int id);
public boolean add(String name,int id);
public List<user> find();
}
public class ServiceImp implements Service{
@Override
public boolean login(String name, int id) {
boolean result=false;
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
return result;
}
@Override
public boolean add(String name, int id) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println("添加成功");
return true;
}
@Override
public List<user> find() {
List<user>list=new ArrayList<>();
Collections.addAll(list,new user(1,"hhh"),new user(2,"aa"),new user(3,"fff"));
for (user user : list) {
System.out.println(user.getId()+" "+user.getName());
System.out.println("-----");
}
return list;
}
}
这是一个简单的业务流程,现在我们想要计算出ServiceImp类每个成员方法所消耗的时间,在每个方法李添加会破坏原代码,这时侯我们就要使用动态代理方法了
动态代理
动态代理就是提供一个代理的对象,有了代理对象后,当访问某个方法时,会被代理对象拦截(拦截后可以对方法进行前增强,后增强)
动态代理的特点:
1.动态的创建.Class文件(创建一个和被代理类实现相同父接口的子类【代理类】)
2.动态的加载.Class文件到内存中(创建Class对象)
Proxy类需要一个“类加载器”
代理对象的代码实现
代理对象=Proxy.newProxyInstance(类加载器,父接口,处理器)
public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h)
动态代理实现的关键步骤
1.被代理类必须有实现接口
2.创建被代理对象,交给代理对象使用
动态代理的代码实现:
public class testProxy {
@Test
public void test()
{
//1.创建被代理对象
ServiceImp serviceImp=new ServiceImp();
/**
* 参数一:类加载器,先获取类,再获取类加载器
* 参数二,父接口类数组,先获取类,在获取父类接口,serviceImp.getClass().getInterfaces()
*/
//Class []interfaces={ Service.class};//如果父接口类很多,那么就很麻烦,我们使用另一个方法
//Class[] interfaces = serviceImp.getClass().getInterfaces();
/* 代理对象实际上是一个实现Service接口的动态代理类的实例,并不是ServiceImp类的实例。*/
//所以是Service接口类型
Service proxyInstance = (Service) Proxy.newProxyInstance(
serviceImp.getClass().getClassLoader(),//类加载器
serviceImp.getClass().getInterfaces(),//实现的父类接口
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//参数一:不使用
//参数二:方法对象,(被代理类的每一个成员方法)
//参数三:成员方法的参数
//return :方法执行后的结果
//开始计时
long start = System.currentTimeMillis();
Object result=method.invoke(serviceImp,args);
long end=System.currentTimeMillis();
System.out.println(method.getName()+"花费的时间为 "+(end-start)+"毫秒");
return result;
}
}
);
proxyInstance.find();//会被加载器拦截
//proxyInstance.add("aaa",5);
}
}
结果:
案例:List中的remove()方法只能删除相同元素的第一个,我们想删除所有相同元素,使用动态代理:
public class testList {
@Test
public void test()
{
List<String> list=new ArrayList<>();
Collections.addAll(list,"hhh","hhh","hhh","aa","cc","cc","dd");
//增强remove()方法,删除多个相同元素
List proxyInstance = (List) Proxy.newProxyInstance(
list.getClass().getClassLoader(), //类加载器
list.getClass().getInterfaces(),//该类的父接口数组
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object result = method.invoke(list, args);//已经执行了一次,即删除了第一个相同元素
//if(method.getName().equals("remove")&&args[0].equals("hhh"))
//{
while(list.contains("hhh"))
{
list.remove("hhh");
}
//}
return result;
}
}
);
proxyInstance.remove("hhh");
System.out.println(list);//[aa, cc, cc, dd]
}
}
Xml
作用:总体上来说,就是用来维护数据的
编写一个人员信息,id是人员的属性代表人员编号。人员信息有年龄,名字,性别
在java语言中
public class Person {
private int id;
private String name;
private int age;
private String sex;
}
Person p=new Person(1,"hh",18,"男");
在xml中,文件后缀为.xml
<?xml version="1.0" encoding="UTF-8" ?><!-- 第一行为固定模式-->
<person id="1">
<name>hhhh</name>
<age>18</age>
<sex>男</sex>
</person>
xml文件的组成:
1.注释
2.声明:第一行
3.元素
4.属性
5.转义字符
6.字符区
元素:
1.格式一:<person>标签体</person>有标签体的标签-->双标签
2.格式二:<person/>没有标签体的标签(空标签)-->单标签
元素的命名:
- 区别大小写
- 不能使用空格,不能使用冒号
- 不建议以xml,Xml,XML,开头
- 标签不能以数字开头,可以有数字
- 可以使用下划线
只写一个根标签
<persons>
<person id="1">
<name>hhhh</name>
<age>18</age>
<sex>男</sex>
</person>
<person id="2">
<name>aaa</name>
<age>20</age>
<sex>男</sex>
</person>
</persons>
属性
1.属性是元素的一部分,它必须出现在开始标签中
2.属性的定义格式,属性名="属性值",其中属性值必须用单引号或者双引号
3.一个元素可以有多个属性,但一个元素不可以有同名属性名
4.属性名不能存在空格
转义字符
字符 转义后 说明 < <; 小于 > >; 大于 " "; 双引号 ' &apos; 单引号 & &; 和号
字符区
当大量的使用转义字符时,我们可以使用字符区,大写CD快捷键
<?xml version="1.0" encoding="UTF-8" ?><!-- 第一行为固定模式-->
<persons>
<person id="1">
<name>hhhh</name>
<age>18</age>
<sex>男</sex>
</person>
<person id="2">
<name>aaa</name>
<age>
20<30
<![CDATA[
20<30&&10>9
]]>
</age>
<sex>男</sex>
</person>
</persons>
xml文件的约束
限制xml文件中可以书写的内容
1.DTD
2.Schema,后缀名是 .xsd
xml文件的解析
使用Dom4j
使用步骤
1.使用Dom4j提供的核心类:SaxReader,加载xml文件并创建Document对象(dom树模型被创建)
创建SaxReader对象,调用read方法关联xml文件,生成Document对象
2.利用document对象:获取dom树的根元素
doucument的方法:
Element getRootElement();
3.从根元素可以获取根下的子元素
List<Element>所有子元素对象=rootElement.elements("子元素的名字");
Element 第一个子元素对象=rootElement.element("子元素的名字");
通过子元素,可以获取其下的子元素
通过子元素,可以获取其下的文本内容
String text=element对象.getText();
String text=父元素对象.elementText("子元素名字");通过父元素来取子元素的文本
获取元素的名字
String name=element对象.getName();
获取元素的属性值
String value=element对象.attributeValue("属性名");
public class testDom4j {
@Test
public void test() throws DocumentException {
//获取Document对象
Document document = new SAXReader().read("person.xml");
//System.out.println(document);
//获取根元素
Element rootElement = document.getRootElement();
System.out.println(rootElement.getName());//persons
//获取根元素的所有子元素
List<Element> elements = rootElement.elements("person");
for (Element personElement : elements) {
//获取name元素
Element name = personElement.element("name");
//获取name元素的文本
String nameText=name.getText();
System.out.println(nameText);
//获取person元素的id属性值
String id = personElement.attributeValue("id");
System.out.println(id);
//获取age元素的文本
String ageText = personElement.elementText("age");
System.out.println(ageText);
System.out.println("----");
}
}
}
接下来我们想要把取到的数据存储到集合中
所以我们创建一个Person类
public class Person {
private String id;
private String name;
private String age;
private String sex;
public Person() {
}
public Person(String id, String name, String age, String sex) {
this.id = id;
this.name = name;
this.age = age;
this.sex = sex;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
@Override
public String toString() {
return "Person{" +
"id='" + id + '\'' +
", name='" + name + '\'' +
", age='" + age + '\'' +
", sex='" + sex + '\'' +
'}';
}
public class testDom4j {
@Test
public void test() throws DocumentException {
List<Person>list=new ArrayList<>();
//获取Document对象
Document document = new SAXReader().read("person.xml");
//System.out.println(document);
//获取根元素
Element rootElement = document.getRootElement();
System.out.println(rootElement.getName());//persons
//获取根元素的所有子元素
List<Element> elements = rootElement.elements("person");
for (Element personElement : elements) {
//获取id属性值
String id = personElement.attributeValue("id");
//获取名字元素的文本
String nameText = personElement.elementText("name");
//获取年龄元素文本
String ageText = personElement.elementText("age");
//获取性别元素文本
String sexText = personElement.elementText("sex");
list.add(new Person(id,nameText,ageText,sexText));
}
System.out.println(list);
}
}