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更值得推荐