实现方式:基于配置XML和基于注解实现。
场景:一个手机进货系统,一旦要进货(或出货),要提前记录进货时间,进货完毕后,还要提醒其它人进行验货。
分析:3步走,1,操作进货(或出货)的方法的时候,先记录当前的时间,完毕后,提醒其他人验货。为了不使代码变得冗余,采用aop的策略实现。
基于配置实现
进货出货的接口:
IPhoneService.java
public interface IPhoneService {
public void salePhone();
public void buyPhone();
}
进货出货的接口实现:
PhoneServiceImpl.java
public class PhoneServiceImpl implements IPhoneService{
@Override
public void salePhone() {
System.out.println("销售iPhone系列手机");
}
@Override
public void buyPhone() {
System.out.println("进货iPhone系列手机");
//throw new RuntimeException();//模拟出现异常使用
}
}
切入的事件处理:
LogAdvice.java
import org.aspectj.lang.JoinPoint;
public class LogAdvice {
public void before(JoinPoint jp){
System.out.println("1.在" + jp.getSignature().getName() + "执行之前切入的内容"+",记录进出货时间");
}
public void afterMethod(JoinPoint jp){
System.out.println("2.在" + jp.getSignature().getName() + "执行之后切入的内容"+",提醒其他人验货");
}
public void afterThrow(JoinPoint jp,RuntimeException re){
System.out.println("3.方法" + jp.getSignature().getName() + "执行过程中,抛出了异常");
}
}
spring配置(切面,切点,切入事件)
applicationContext.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:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">
<bean id="phoneService" class="com.ysdit.spring2.service.PhoneServiceImpl"></bean>
<!-- 增强处理,切入的内容 -->
<bean id="logAdvice" class="com.ysdit.spring2.service.aop.LogAdvice"></bean>
<aop:config>
<!-- 地点,切入的位置,该包下的任何方法的任何返回值,任何参数。都切入 -->
<aop:pointcut expression="execution(* com.ysdit.spring2.service.*.*(..))" id="phonePoint"/>
<aop:aspect ref="logAdvice" id="ap1">
<!-- 时间,非功能需求代码切入的时间 -->
<aop:after-returning method="afterMethod" pointcut-ref="phonePoint"/>
</aop:aspect>
<aop:aspect ref="logAdvice" id="ap2">
<aop:before method="before" pointcut-ref="phonePoint"/>
</aop:aspect>
<aop:aspect ref="logAdvice" id="ap3">
<aop:after-throwing method="afterThrow" pointcut-ref="phonePoint" throwing="re"/>
</aop:aspect>
</aop:config>
</beans>
测试类:
AopTest.java
import com.ysdit.spring2.service.IPhoneService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class AopTest {
/**
* @param args
*/
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
IPhoneService phoneService = (IPhoneService) ctx.getBean("phoneService");
phoneService.buyPhone();
}
}
执行购手机的方法,控制台打印如下:
执行卖手机的方法,控制台打印如下:
模拟执行卖手机的方法,出现异常,控制台打印如下:
发生异常,程序依旧能通知我们出现了异常,能通知及时处理.
百度云云盘分享(配置实现):http://pan.baidu.com/s/1dFG46w5
基于注解实现
修改:
applicationContext.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:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">
<!--告诉spring要使用aop注解 -->
<aop:aspectj-autoproxy/>
<bean id="phoneService" class="com.ysdit.spring2.service.PhoneServiceImpl"></bean>
<!-- 增强处理,切入的内容 -->
<bean id="logAdvice" class="com.ysdit.spring2.service.aop.LogAdvice"></bean>
</beans>
修改:
LogAdvice.java
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
@Aspect
public class LogAdvice {
@Pointcut("execution(* com.ysdit.spring2.service.*.*(..))")//这样是为了,实现切入点的重用
public void pointcut(){}
@Before("pointcut()")
public void before(JoinPoint jp){
System.out.println("1.在" + jp.getSignature().getName() + "执行之前切入的内容"+",记录进出货时间");
}
@After("pointcut()")
public void afterMethod(JoinPoint jp){
System.out.println("2.在" + jp.getSignature().getName() + "执行之后切入的内容"+",提醒其他人验货");
}
@AfterThrowing("pointcut()")
public void afterThrow(JoinPoint jp){
System.out.println("3.方法" + jp.getSignature().getName() + "执行过程中,抛出了异常");
}
}
执行购手机的方法,控制台打印如下:
执行卖手机的方法,控制台打印如下:
模拟执行卖手机的方法,出现异常,控制台打印如下:
发生异常,程序依旧能通知我们出现了异常,能通知及时处理.
百度云盘链接(注解实现):http://pan.baidu.com/s/1nu5OC8h
对于spring-boot 启用aop注解
1.添加依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
2.开启注解
spring.aop.auto=true
完成