如果在Spring
的程序中同时定义了环绕通知(Around)
和前置通知(Before)
。.那么,有以下问题:
1.怎么让两个切面通知都起作用
2.或者让两者切面按自己指定的顺序进行执行?
3.环绕通知和前置后置通知的区别
如果在同一接入点(join point) 有多个通知(advice),Spring AOP 采用和 AspectJ 类似的优先级来指定通知的执行顺序,目标执行前(进入时),优先级高的通知先执行,目标执行后(出来时),优先级高的通知后执行。
如果两个通知分别定义在各自的 Aspect 内,可以通过如下两种方式控制 Aspect 的施加顺序:
Aspect 类添加注解:org.springframework.core.annotation.Order
顺序值:使用注解属性指定
Aspect 类实现接口:org.springframework.core.Ordered
顺序值:实现 Ordered 接口的 getOrder() 方法即可
如果两个 advice 位于同一 aspect 内,且执行顺序有先后,通过 advice 的声明顺序是无法确定其执行顺序的,因为 advice 方法的声明顺序无法通过反射获取,只能采取如下变通方式,二选一:
将两个 advice 合并为一个 advice,那么执行顺序就可以通过代码控制了
将两个 advice 分别抽离到各自的 aspect 内,然后为 aspect 指定执行顺序
作者:Night Silent
链接:http://www.zhihu.com/question/32326290/answer/55572235
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
将需要被执行的通知的实现类,在Sping中进行注册或者全部采用注解的方式和配置扫描包
如果编写的环绕通知和前置后置通知没有问题,那么,通知就可以在切点出被调用。
"aroundAudience"
class="com.springinaction.springidol.AroundAudience">
"audience"
class="com.springinaction.springidol.Audience" />
你在Spring的配置文件中声明环绕通知和前置后置通知的顺序就是他们执行的先后顺序。由配置顺序决定执行先后顺序,本身没有优先级。
参考文档文档
下面的地址是Spring官方给出的AOP切面的文档
http://docs.spring.io/spring/docs/2.5.x/reference/aop.html#aop-ataspectj-advice-ordering
使用Spring进行面向切面编程(AOP).
http://www.blogjava.net/supercrsky/articles/174368.html
跟我学SPring3.x之切面执行顺序
http://jinnianshilongnian.iteye.com/blog/1423489
下面用一个实例来说明如何执行多个通知,实例采用Maven进行依赖管理,通知采用注解形式的配置
<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">
<bean id="eddie"
class="com.springinaction.springidol.Instrumentalist">
<property name="instrument">
<bean class="com.springinaction.springidol.Guitar" />
property>
bean>
<bean id="aroundAudience"
class="com.springinaction.springidol.AroundAudience">
bean>
<bean id="audience"
class="com.springinaction.springidol.Audience" />
<bean class="com.springinaction.springidol.ContestantIntroducer" />
<aop:aspectj-autoproxy />
beans>
接口
package com.springinaction.springidol;
public interface Instrument {
public void play();
}
Instrument实现类
package com.springinaction.springidol;
public class Guitar implements Instrument {
public void play() {
System.out.println("Strum strum strum");
}
}
package com.springinaction.springidol;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
@Aspect
public class AroundAudience {
@Pointcut("execution(* com.springinaction.springidol.Performer.perform(..))")
public void performance() {
}
//"audience_around_bean" />
@Around("performance()")
public void watchPerformance(ProceedingJoinPoint joinpoint) {
try {
System.out.println("The audience is taking their seats.");
System.out.println("The audience is turning off their cellphones");
long start = System.currentTimeMillis();
joinpoint.proceed();
long end = System.currentTimeMillis();
System.out.println("CLAP CLAP CLAP CLAP CLAP");
System.out.println("The performance took " + (end - start)
+ " milliseconds.");
} catch (Throwable t) {
System.out.println("Boo! We want our money back!");
}
}
//"audience_around_bean" />
}
package com.springinaction.springidol;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
@Aspect
public class Audience {
@Pointcut(
"execution(* com.springinaction.springidol.Performer.perform(..))")
public void performance() { //
System.out.println("fuck fuck fuck me ");
}
@Before("performance()")
public void takeSeats() { //
System.out.println("2222The audience is taking their seats.");
}
@Before("performance()")
public void turnOffCellPhones() { //
System.out.println("The audience is turning off their cellphones");
}
@AfterReturning("performance()")
public void applaud() { //
System.out.println("CLAP CLAP CLAP CLAP CLAP");
}
@AfterThrowing("performance()")
public void demandRefund() { //
System.out.println("Boo! We want our money back!");
}
}
package com.springinaction.springidol;
public interface Performer {
void perform() throws PerformanceException;
}
package com.springinaction.springidol;
public class PerformanceException extends Exception {
private static final long serialVersionUID = 1L;
}
package com.springinaction.springidol;
public class Instrumentalist implements Performer {
public void perform() throws PerformanceException {
instrument.play();
}
private Instrument instrument;
public void setInstrument(Instrument instrument) {
this.instrument = instrument;
}
public Instrument getInstrument() {
return instrument;
}
}
package com.springinaction.springidol;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("spring-idol.xml")
public class AspectTest {
@Autowired
ApplicationContext context;
@Test
public void audienceShouldApplaud() throws Exception {
Performer eddie = (Performer) context.getBean("eddie");
eddie.perform();
}
@Test
public void eddieShouldBeAContestant() {
Contestant eddie = (Contestant) context.getBean("eddie");
eddie.receiveAward();
}
}
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0modelVersion>
<groupId>com.frankgroupId>
<artifactId>springinactionartifactId>
<packaging>warpackaging>
<version>1.0-SNAPSHOTversion>
<name>springinaction Maven Webappname>
<url>http://maven.apache.orgurl>
<properties>
<project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
<springversion>3.1.1.RELEASEspringversion>
<junitversion>3.8.1junitversion>
properties>
<dependencies>
<dependency>
<groupId>junitgroupId>
<artifactId>junitartifactId>
<version>3.8.1version>
<scope>testscope>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-aopartifactId>
<version>${springversion}version>
<type>jartype>
<scope>compilescope>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-asmartifactId>
<version>${springversion}version>
<type>jartype>
<scope>compilescope>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-aspectsartifactId>
<version>${springversion}version>
<type>jartype>
<scope>compilescope>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-beansartifactId>
<version>${springversion}version>
<type>jartype>
<scope>compilescope>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-contextartifactId>
<version>${springversion}version>
<type>jartype>
<scope>compilescope>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-context-supportartifactId>
<version>${springversion}version>
<type>jartype>
<scope>compilescope>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-coreartifactId>
<version>${springversion}version>
<type>jartype>
<scope>compilescope>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-expressionartifactId>
<version>${springversion}version>
<type>jartype>
<scope>compilescope>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-jdbcartifactId>
<version>${springversion}version>
<type>jartype>
<scope>compilescope>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-aopartifactId>
<version>${springversion}version>
dependency>
<dependency>
<groupId>org.aspectjgroupId>
<artifactId>aspectjrtartifactId>
<version>1.8.2version>
dependency>
<dependency>
<groupId>org.aspectjgroupId>
<artifactId>aspectjweaverartifactId>
<version>1.8.2version>
<scope>runtimescope>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-jmsartifactId>
<version>${springversion}version>
<type>jartype>
<scope>compilescope>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-ormartifactId>
<version>${springversion}version>
<type>jartype>
<scope>compilescope>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-oxmartifactId>
<version>${springversion}version>
<type>jartype>
<scope>compilescope>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-txartifactId>
<version>${springversion}version>
<type>jartype>
<scope>compilescope>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-webartifactId>
<version>${springversion}version>
<type>jartype>
<scope>compilescope>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-webmvcartifactId>
<version>${springversion}version>
<type>jartype>
<scope>compilescope>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-testartifactId>
<version>${springversion}version>
<type>jartype>
<scope>compilescope>
dependency>
<dependency>
<groupId>javax.servletgroupId>
<artifactId>jstlartifactId>
<version>1.2version>
<type>jartype>
<scope>compilescope>
dependency>
<dependency>
<groupId>commons-collectionsgroupId>
<artifactId>commons-collectionsartifactId>
<version>3.1version>
dependency>
<dependency>
<groupId>commons-logginggroupId>
<artifactId>commons-loggingartifactId>
<version>1.1version>
dependency>
<dependency>
<groupId>junitgroupId>
<artifactId>junitartifactId>
<version>RELEASEversion>
<scope>testscope>
dependency>
dependencies>
project>