Spring框架学习(二):试试AOP多厉害

在第一篇中,我介绍了Spring的一些基础概念,其中有的概念来来自于《Spring实战第四版》,而有的概念是我自己的理解。IOC和AOP被称为是Spring框架的核心。这一篇,我们就初步探索一下AOP的厉害之处。继续引用第一篇的例子,关于配置文件的解释,我会循序渐进地讲。

我们一般在做作业之前会看一眼时间,为了更好贴合AOP,我广泛地说,每次做作业我们都需要看一眼时间再开始。我新建了一个类叫做:CheckNowTime.java

public class CheckNowTime {

    public void beforDoHomework(){
        System.out.println(new Date(System.currentTimeMillis()));
    }
}

这个类有一个方法,作用是打印一下当前时间。Student.java和Homework.java与上一篇一样:

 

public class Student {

    private String name;
    private Homework homework;
    public Student(){}
    public Student(String name, Homework homework) {
        this.name = name;
        this.homework = homework;
    }

    public void doHomeWork(){
        System.out.println(homework.getContent());
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Homework getHomework() {
        return homework;
    }

    public void setHomework(Homework homework) {
        this.homework = homework;
    }
}
View Code

 

public class Homework {

    private String content;

    public Homework(){}
    public Homework(String content) {
        this.content = content;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }
}
View Code

对App.java的代码稍微调整一下:

public class App {

    public static void main(String[] args) {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("appContext.xml");
        Student student = context.getBean(Student.class);

        System.out.println(student.getName()+"准备做作业了");
        student.doHomeWork();

        context.close();

    }
}

在appContext.xml中加入aop的声明

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
    <!-- 让Spring管理 Student bean   -->
    <bean id="student" class="demo1.Student">
        <property name="name" value="小明"></property>
        <property name="homework" ref="homework"></property>
    </bean>

    <!-- 让Spring管理Homework bean-->
    <bean id="homework" class="demo1.Homework">
        <property name="content" value="how to calc 3+2 ?"></property>
    </bean>
    
    <!-- 切面定义-->
    <bean id="checktime" class="demo1.CheckNowTime"></bean>
    <aop:config>
        <aop:aspect ref="checktime">
            <aop:pointcut id="dohomework" expression="execution(* *.doHomeWork(..))"/>
            <aop:before pointcut-ref="dohomework" method="beforDoHomework"></aop:before>
        </aop:aspect>
    </aop:config>
</beans>

我们先看看运行结果

 

 在main方法中,我并没有调用CheckNowTime的方法,我甚至没有创建过CheckNowTime的对象,但是从控制台打印的消息显示,我在调用doHomework()方法之前调用了beforDoHomework()方法,没错了,这就是AOP干的。实际上,我调用几次doHomework()方法就会自动调用几次beforDoHomework()方法。是不是很强大?

我们简单的分析一下appContext.xml的那几句AOP相关代码(标有<!-- 切面定义-->下面的几行):首先,我把CheckNowTime用<bean>标签声明了一下,这样,在Spring的容器中就能得到CheckNowTime的对象了。我还把这个类抽象为“切面”,为什么这么说呢?根据我的需求,学生在做作业时会看一下时间,泛化了讲,任何一个学生对象,在调用doHomework()方法之前都需要调用beforDoHomework()方法,所以beforDoHomework()是一个公共服务。公共服务就可以理解为切面,当然了,这个类还可以有多个方法,所以“切面”这个描述放在类上面更为合适。那么,什么是切点呢?我认为,切点就是激发公共服务的点,什么时候激发公共服务?在本例中,调用doHomework()函数时激发。expression = "execution(* *.doHomeWork(..))"规定了调用这个方法时执行,那么,是在调用前执行还是调用后执行呢,由我们决定,例子中我使用了<aop:before ....>规定了调用前执行,执行的内容就是调用method="beforDoHomework"。

分析到这里,你是不是对AOP有了初步了解?记住,暂时不要太过于关心为什么这么写。如果你想尝试我的这个例子,IDE选择IntelliJ IDEA,建议创建基于Maven的Spring项目。具体参考这个链接。如果这篇文章对你有帮助,关注、收藏、点赞素质三连哦。

posted @ 2019-07-19 21:52  陈玉林  阅读(320)  评论(0)    收藏  举报