Spring实现AOP主要有两种方式:
1.基于AspectJ注解
2.基于XML配置
接下来我们分别介绍如何使用这两种方式来实现AOP
一.使用注解方式实现AOP功能
利用Spring注解方式可以实现前置通知,后置通知,例外通知以及环绕通知等。
实现AOP功能步骤如下:
- 引入Jar文件
- 配置AOP命名空间
- 创建目标对象类
- 创建切面
- 在配置文件中配置切面
- 创建入口类进行测试
接下来我们在示例中演示一下
具体要求如下:
- 创建一个Java Bean,例如PersonBean
- PersonBean包含一些简单的业务逻辑,例如运动相关,包括走路,跑步,爬山,打球等。
- 在每个运动的方法前,方法中,以及方法后输出相关的日志信息。
Step1:在classpath下的AspectJ类库:
Step2:创建一个接口Person
Step3:定义Tager Object
Step4:定义Aspect和Advice
Step5:进行Aop设置
spring-aspects.jar aspectj.weaver.jar aopalliance.jar
Step2:创建一个接口Person
public interface Person { public void work(); public void run(); public void playBasketball(); public void swim(); }
Step3:定义Tager Object
import org.springframework.stereotype.Component; /** * Created by icarus on 2016/6/13. * Person接口实现类 */ @Component("personimpl1") public class PersonImpl1 implements Person{ public void work() { System.out.println("散步!"); } public void run() { System.out.println("跑步!"); } public void playBasketball() { System.out.println("打篮球!"); } public void swim() { System.out.println("游泳!"); } }
Step4:定义Aspect和Advice
import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.*; import org.springframework.stereotype.Component; @Aspect @Component("loggingaspect") public class LoggingAspect { @Pointcut("execution(* cn.lovepi.chapter06.aop.test.PersonImpl1.*(..))") public void sport(){ } /** * 方法执行前记录日志 * @param jp 连接点 */ @Before("sport()") public void loggerBeforeAction(JoinPoint jp) { System.out.println(jp.getSignature().getName()+"执行开始"); } /** * 方法执行过程中记录日志 * @param pjp 只能在Around 的advice中使用 * @throws Throwable */ @Around("sport()") public void loggerAroundAction(ProceedingJoinPoint pjp) throws Throwable { pjp.proceed();//执行原方法 System.out.println(pjp.getSignature().getName()+"执行过程中... ..."); } /** * 方法执行完记录日志 * @param jp 连接点 * @throws Throwable */ @After("sport()") public void loggerAfterAction(JoinPoint jp){ System.out.println(jp.getSignature().getName()+"执行结束"); } }
Step5:进行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" xmlns:context="http://www.springframework.org/schema/context" 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 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <!--开启注解扫描--> <context:component-scan base-package="cn.lovepi.chapter06.aop.test"/> <!--开启Spring动态代理--> <aop:aspectj-autoproxy proxy-target-class="true"/> </beans>
说明:必须在Spring IoC容器中启用AspectJ动态代理支持
Step6:测试
public class Main { public static void main(String[] args){ ApplicationContext context= new FileSystemXmlApplicationContext("src/conf/conf-test.xml"); cn.lovepi.chapter06.aop.test.PersonImpl1 person=context.getBean("personimpl1",cn.lovepi.chapter06.aop.test.PersonImpl1.class); person.run(); person.work(); person.playBasketball(); person.swim(); } }
程序执行结果:
run执行开始
跑步!
run执行过程中... ...
run执行结束
work执行开始
散步!
work执行过程中... ...
work执行结束
playBasketball执行开始
打篮球!
playBasketball执行过程中... ...
playBasketball执行结束
swim执行开始
游泳!
swim执行过程中... ...
swim执行结束
二.使用Spring XML配置方式实现AOP功能
实现AOP的主要步骤如下:
- 引入Jar文件
- 配置AOP命名空间
- 创建目标对象类
- 创建切面
- 在配置文件中配置
- 创建入口类进行测试
接下来我们在示例中演示一下
具体要求如下:
- 创建一个Java Bean,例如PersonBean
- PersonBean包含一些简单的业务逻辑,例如运动相关,包括走路,跑步,爬山,打球等。
- 在每个运动的方法前,方法中,以及方法后输出相关的日志信息。
Step1:在classpath下的AspectJ类库:
Step2:创建一个接口Person
Step3:定义Tager Object
Step4: 定义Aspect和Advice
Step5:进行Aop设置
spring-aspects.jar aspectj.weaver.jar aopalliance.jar
Step2:创建一个接口Person
public interface Person { public void work(); public void run(); public void playBasketball(); public void swim(); }
Step3:定义Tager Object
public class PersonImplXml implements Person{ public void work() { System.out.println("散步!"); } public void run() { System.out.println("跑步!"); } public void playBasketball() { System.out.println("打篮球!"); } public void swim() { System.out.println("游泳!"); } }
Step4: 定义Aspect和Advice
import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoinPoint; /** * Created by icarus on 2016/6/13. */ public class LoggingAspectXml { /** * 开始执行方法 * @param jp */ public void loggerBeforeAction(JoinPoint jp) { System.out.println(jp.getSignature().getName()+"执行开始"); } /** * 方法执行中 * @param pjp * @throws Throwable */ public void loggerAroundAction(ProceedingJoinPoint pjp) throws Throwable { pjp.proceed();//执行原方法 System.out.println(pjp.getSignature().getName()+"执行过程中... ..."); } /** * 方法执行结束 * @param jp */ public void loggerAfterAction(JoinPoint jp){ System.out.println(jp.getSignature().getName()+"执行结束"); } }
Step5:进行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动态代理--> <aop:aspectj-autoproxy proxy-target-class="true"/> <!--bean 配置--> <bean id="personImplXml" class="cn.lovepi.chapter06.aop.test.PersonImplXml"/> <bean id="loggingAspectXml" class="cn.lovepi.chapter06.aop.test.LoggingAspectXml"/> <!--aop 配置--> <aop:config> <!--设置切点--> <aop:pointcut id="loggingAspect" expression="execution(* cn.lovepi.chapter06.aop.test.PersonImplXml.*(..))"/> <!--切面设置--> <aop:aspect id="loggingaspect" ref="loggingAspectXml"> <aop:before method="loggerBeforeAction" pointcut-ref="loggingAspect"/> <aop:around method="loggerAroundAction" pointcut-ref="loggingAspect"/> <aop:after method="loggerAfterAction" pointcut-ref="loggingAspect"/> </aop:aspect> </aop:config> </beans>
说明:必须在Spring IoC容器中启用AspectJ动态代理支持
Step6:测试
public class MainXml { public static void main(String[] args){ ApplicationContext context=new FileSystemXmlApplicationContext("src/conf/conf-test-xml.xml"); PersonImplXml person=context.getBean("personImplXml",PersonImplXml.class); person.work(); person.run(); person.playBasketball(); person.swim(); } }
程序执行结果:
run执行开始
跑步!
run执行过程中... ...
run执行结束
work执行开始
散步!
work执行过程中... ...
work执行结束
playBasketball执行开始
打篮球!
playBasketball执行过程中... ...
playBasketball执行结束
swim执行开始
游泳!
swim执行过程中... ...
swim执行结束
总结:
通过最后结果相比较而言,AspectJ更值得推荐