定義切面使用@Aspect、@EnableAspectJAutoProxy、


一、

假設有如下情況,有一個演湊者和一批觀眾,要實現在演湊者的演湊方法前織入觀眾的"坐下"、"關手機方法",在演湊結束后,如果成功,則織入觀眾"鼓掌",演湊出錯則觀眾要求"回水"

基本的類如下:

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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM