定义aop的方法,有两种,可以通过xml来定义,也可以通过注解。首先,来看看通过xml如何定义aop。
AOP中,最重要的为理解切面(aspect)、切点(pointcut)、通知(advice)三个概念。
简单理解:切面,也是一个类对象,这个类的功能一般为:安全管理、账号登录等。也就是说,这些类的功能很关键,在整个程序的各个地方可能都用的到,但是,他们的功能独立,与程序的耦合度应该降低到最小。总而言之,切面是这么个玩意:
1);它是一个类,普通的java类。
2):功能独立
3):用处广泛,用的地方比较零散。
举个例子吧。一个账户登录的类,通常可以作为一个切面。在你登录账户时、转账时、下载东西时等,都会涉及账户登录这个类。
那切点是什么呢?我的理解为:切点,是一个具体类中的一个方法。
这么说态抽象了。举个例子吧!
package com.bean.AOP2;
public interface IEat {
public void eat();
}
package com.bean.AOP2;
public class Eat implements IEat {
@Override
public void eat(){
for(int i=0;i<1e4;i++);
System.out.println("today,i eat food!");
for(int i=0;i<1e4;i++);
}
}
这里的Eat.eat方法,就可以理解为一个切点。也就是说,我要在这个方法执行之前、之后来做一些事情。
定义一个切面如下:
package com.bean.AOP2;
import org.aspectj.lang.ProceedingJoinPoint;
public class EatPrepare {
public void washHand(){
System.out.println("wash hand!");
}
public void takeFood(){
System.out.println("take food!");
}
public void cleanDish(){
System.out.println("clean dish!");
}
public void calculateEatime(ProceedingJoinPoint joinPoint){
try{
long begintime=System.currentTimeMillis();
System.out.println("begin eat!");
joinPoint.proceed();
long endtime=System.currentTimeMillis();
System.out.println("end eat!");
System.out.println("eat time is:"+(endtime-begintime));
}catch(Throwable t){
t.printStackTrace();
}
}
}
在吃饭之前,我们要洗手(washhand)
、端菜(takefood),在吃饭之后,我们还要洗碗(cleandish)。当然,我们还想知道,我们吃饭用了多长时间(calculateEatTime)。
<?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-4.2.xsd">
<!-- 先定义一个切面bean -->
<bean id="eatprepare" class="com.bean.AOP2.EatPrepare"></bean>
<!-- 定义aop,该aop用在所有调用该方法com.bean.AOP2.Eat.eat()的com.bean.AOP2.Eat对象上-->
<aop:config>
<aop:aspect ref="eatprepare">
<!-- 注意execution中,*与com之间必须有空格 -->
<aop:pointcut expression="execution(* com.bean.AOP2.Eat.eat(..))" id="eat_aspect"/>
<aop:before method="washHand" pointcut-ref="eat_aspect"/>
<aop:before method="takeFood" pointcut-ref="eat_aspect"/>
<aop:after method="cleanDish" pointcut-ref="eat_aspect"/>
</aop:aspect>
</aop:config>
<!-- 调用id为eat时的eat()方法时,aop为eatprepare的切面的方法washHand、takeFood、cleanDish、calculateEatime会被执行 -->
<bean id="eat" class="com.bean.AOP2.Eat"></bean>
<!-- 定义环绕aop -->
<aop:config>
<aop:aspect ref="eatprepare">
<aop:pointcut expression="execution(* com.bean.AOP2.Eat.eat(..))" id="eat_aspect2"/>
<aop:around method="calculateEatime" pointcut-ref="eat_aspect2"/>
</aop:aspect>
</aop:config>
</beans>
测试代码如下:
package com.bean.AOP2;
import org.springframework.context.support.FileSystemXmlApplicationContext;
public class Main {
public static void main(String[] args) {
FileSystemXmlApplicationContext context=new FileSystemXmlApplicationContext("BeanXml\\AOP2.xml");
//对于aop,必须向上转型为接口类型,所以,切点类必须实现了某个接口
IEat eat=(IEat)context.getBean("eat");
eat.eat();
context.close();
}
}