您的位置:首页 > 编程语言 > ASP

SPRING IN ACTION 第4版笔记-第四章ASPECT-ORIENTED SPRING-005-定义切面使用@Aspect、@EnableAspectJAutoProxy、<aop:aspectj-autoproxy>

2016-03-03 17:43 681 查看
一、

假设有如下情况,有一个演凑者和一批观众,要实现在演凑者的演凑方法前织入观众的"坐下"、"关手机方法",在演凑结束后,如果成功,则织入观众"鼓掌",演凑出错则观众要求"回水"

基本的类如下:

1.

package com.springinaction.springidol;

public interface Instrument {
public void play();
}


2.

package com.springinaction.springidol;

public class Guitar implements Instrument {
public void play() {
System.out.println("Strum strum strum");
}
}


3.

package com.springinaction.springidol;

public interface Performer {
void perform() throws PerformanceException;
}


4.

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;
}
}


二、

可以定义的advice



Spring的切面是一个pojo

1.使用@Aspect定义切面类

(1)不同的方法可以用不同的pointcut

package concert;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
@Aspect
public class Audience {
@Before("execution(** concert.Performance.perform(..))")
public void silenceCellPhones() {
System.out.println("Silencing cell phones");
}
@Before("execution(** concert.Performance.perform(..))")
public void takeSeats() {
System.out.println("Taking seats");
}
@AfterReturning("execution(** concert.Performance.perform(..))")
public void applause() {
System.out.println("CLAP CLAP CLAP!!!");
}
@AfterThrowing("execution(** concert.Performance.perform(..))")
public void demandRefund() {
System.out.println("Demanding a refund");
}
}


(2)定义一个公共的pointcut,其对应的方法名就是id

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() { //<co id="co_definePointcut"/>
}

@Before("performance()")
public void takeSeats() { //<co id="co_takeSeatsBefore"/>
System.out.println("The audience is taking their seats.");
}

@Before("performance()")
public void turnOffCellPhones() { //<co id="co_turnOffCellPhonesBefore"/>
System.out.println("The audience is turning off their cellphones");
}

@AfterReturning("performance()")
public void applaud() { //<co id="co_applaudAfter"/>
System.out.println("CLAP CLAP CLAP CLAP CLAP");
}

@AfterThrowing("performance()")
public void demandRefund() { //<co id="co_demandRefundAfterException"/>
System.out.println("Boo! We want our money back!");
}
}


2.把切面交给Spring容器

(1)在java配置文件中,使用@EnableAspectJAutoProxy

package concert;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
@Configuration
@EnableAspectJAutoProxy
@ComponentScan
public class ConcertConfig {
@Bean
public Audience audience() {
return new Audience();
}
}


(2)在xml使用<aop:aspectj-autoproxy>

<?xml version="1.0" encoding="UTF-8"?>
<!--<start id="preamble" />-->
<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"> <!--<end id="preamble" />-->

<bean id="eddie"
class="com.springinaction.springidol.Instrumentalist">
<property name="instrument">
<bean class="com.springinaction.springidol.Guitar" />
</property>
</bean>

<!--<start id="audience_bean" />-->
<bean id="audience"
class="com.springinaction.springidol.Audience" />
<!--<end id="audience_bean" />-->

<!--<start id="contestant_introducer" />-->
<bean class="com.springinaction.springidol.ContestantIntroducer" />
<!--<end id="contestant_introducer" />-->

<!--<start id="aspectj_autoproxy" />-->
<aop:aspectj-autoproxy />
<!--<end id="aspectj_autoproxy" />-->

</beans>


3.测试

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();
}
}


audienceShouldApplaud的测试结果:

The audience is taking their seats.
The audience is turning off their cellphones
Strum strum strum
CLAP CLAP CLAP CLAP CLAP
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: