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; } }
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; } }
对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项目。具体参考这个链接。如果这篇文章对你有帮助,关注、收藏、点赞素质三连哦。

浙公网安备 33010602011771号