java中的动态代理和xml文件解析(使用DOM4J)

文章介绍了Java中的动态代理技术,如何在ServiceImp类中添加时间测量功能,以及如何使用Dom4j库解析XML文件并将其内容转换为Person对象列表。
摘要由CSDN通过智能技术生成
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/>没有标签体的标签(空标签)-->单标签

元素的命名:

  1. 区别大小写
  2. 不能使用空格,不能使用冒号
  3. 不建议以xml,Xml,XML,开头
  4. 标签不能以数字开头,可以有数字
  5. 可以使用下划线

只写一个根标签 

<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.属性名不能存在空格

 转义字符

字符转义后说明
<&lt;小于
>&gt;大于
"&quot;双引号
'&apos;单引号
&&amp;和号

字符区

当大量的使用转义字符时,我们可以使用字符区,大写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&lt;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);
    }
}

  • 43
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

落落落sss

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值