最近又学习到了aop这一个概念,和之前学过的代理模式类似,通俗点说就是在一个事情发生之前或之后或之前和之后去做点事情。比如我要去吃饭,我就可以选择在吃饭之前付钱或者是吃完饭之后,这里就要引入几个概念:切入点和切面。在这个例子里面,吃饭就是切入点,切面就是要执行的动作,也就是付钱。
aop的配置有两种方式,一个是通过配置文件配置,另一个就是通过注释进行配置。
一、先来看通过配置文件配置:
首先写一个bean类Me:
package spring.com.service;
public class Me {
//动作:吃饭
public void eatSomeFood(){
System.out.println("这顿饭吃一个汉堡两个鸡腿");
}
}
切片类OneAspect:
package spring.com.aop;
public class OneAspect {
//洗手
public void washHand(){
System.out.println("你已经洗手");
}
//付钱
public void pay(){
System.out.println("这顿饭花费20元,支付成功");
}
}
配置文件:
<?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:context="http://www.springframework.org/schema/context"
xmlns:util="http://www.springframework.org/schema/util" xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.3.xsd">
<!-- 将Me对象装入容器 -->
<bean id="me" class="spring.com.service.Me"></bean>
<!-- 将切片对象装入容器 -->
<bean id="myAs" class="spring.com.aop.OneAspect"></bean>
<aop:config>
<!-- 切入点 -->
<aop:pointcut expression="execution(* spring.com.service.Me.eatSomeFood(..))" id="pointshut"/>
<!-- 切片 -->
<aop:aspect ref="myAs">
<!-- 在吃饭 之前 洗手 -->
<aop:before method="washHand" pointcut-ref="pointshut"/>
<!-- 在吃饭 之后 结账 -->
<aop:after method="pay" pointcut-ref="pointshut"/>
</aop:aspect>
</aop:config>
</beans>
测试类:
package spring.com.testeat;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import spring.com.service.Me;
public class ToEat {
static ConfigurableApplicationContext context;
public static void main(String args[]){
context = new ClassPathXmlApplicationContext("eat.xml");
Me me = (Me)context.getBean("me");
me.eatSomeFood();
}
}
测试输出:
aop的切片内有五个属性,after是方法执行结束后再执行切片方法(包含正常结束和非正常结束);after-returning是方法正常执行后再执行切片方法;after-throwing是方法发生错误结束后执行切片方法;around是方法执行前后选择性执行切片方法;before是方法执行前执行
二、通过配置文件配置
只需要修改切片OneAspect
package spring.com.aop;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
@Aspect
public class OneAspect {
//洗手 注释里面的value值是切入点
@Before("execution(* spring.com.service.Me.eatSomeFood(..))")
public void washHand(){
System.out.println("你已经洗手");
}
//付钱 注释里面的value值是切入点
@After("execution(* spring.com.service.Me.eatSomeFood(..))")
public void pay(){
System.out.println("这顿饭花费20元,支付成功");
}
}
xml文件变得超简单:
<?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:context="http://www.springframework.org/schema/context"
xmlns:util="http://www.springframework.org/schema/util" xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.3.xsd">
<!-- 将Me对象装入容器 -->
<bean id="me" class="spring.com.service.Me"></bean>
<!-- 将切片对象装入容器 -->
<bean id="myAs" class="spring.com.aop.OneAspect"></bean>
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
</beans>
输出结果相同: