1. 表演接口Performance 和舞台剧LivingTheatre

package concert;

/**
 * ①普通Java类
 * Created by guoli on 2017/7/23 0023.
 * YXV0aG9yOiB6aGFuZ2d1b2xpLmNu
 */

/**
 * Performance只是一个普通的Java接口
 * 使用如下切点表达式可以设置当perform()方法执行时触发通知的调用
 * execution(*  concert.LivingTheatre.perform(..))
 * 切点表达式解释如下:
 * execution 在方法执行时触发
 * *任意返回值类型
 * concert.LivingTheatre.perform 包-类/接口-方法
 * .. 任意参数
 */
public interface Performance {
    public void perform();
}
package concert;

import org.springframework.stereotype.Component;

/**
 * ②实现Performance接口的普通类
 * Created by guoli on 2017/7/23 0023.
 * YXV0aG9yOiB6aGFuZ2d1b2xpLmNu
 */

/**
 * @Component泛指组件,和@Controller、@Service、@Repository在大多数情况下是通用的
 */
@Component
public class LivingTheatre implements Performance {

    @Override
    public void perform() {
        System.out.println("kaixinmahua........");
    }
}

2. 切点表达式

切点表达式基础知识

package concert;

import org.aspectj.lang.annotation.*;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;

/**
 * ③频繁使用的切点表达式用@Pointcut定义以重用
 * Created by guoli on 2017/7/23 0023.
 * YXV0aG9yOiB6aGFuZ2d1b2xpLmNu
 */

/**
 * AspectJ会自动为使用@Aspect注解的bean创建代理,这个代理会围绕该切面的切点所匹配的bean
 * 在这里Audience类中的通知方法将会在perform()调用前后执行
 * Spring的AspectJ代理只用于方法上
 */

@Aspect
@Component
public class AudienceJ {

    @Pointcut("execution(* concert.LivingTheatre.perform(..))")
    public void performance() {
    }

    @Before("performance()")
    public void silenceCellPhones() {
        System.out.println("phone is silencing...");
    }

    @Before("performance()")
    public void takeSeats() {
        System.out.println("taking seats");
    }

    @AfterReturning("performance()")
    public void applause() {
        System.out.println("CALP CALP CALP");
    }

    @AfterThrowing("performance()")
    public void demandRefund() {
        System.out.println("Demanding a refund");
    }

}

3. 使用Java配置方式启动AspectJ注解的自动代理

package concert;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;

/**
 * ④JavaConfig中启用AspectJ注解的自动代理
 * Created by guoli on 2017/7/23 0023.
 * YXV0aG9yOiB6aGFuZ2d1b2xpLmNu
 */

/**
 * @Configuration 当前Class为配置类
 * @EnableAspectJAutoProxy 启用自动代理, XML方式配置:<aop:aspectj-autoproxy />
 * @ComponentScan 自动扫描同路径下的@Component、@Controller、@Service、@Repository等相关注解并为其注册为bean
 * 此处@ComponentScan、@ComponentScan(backPackages="concert")、@ComponentScan("concert")等效
 */

@Configuration
@EnableAspectJAutoProxy
@ComponentScan

public class ConcertConfig {

}

4. 测试

package concert;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

/**
 * Created by guoli on 2017/7/23 0023.
 * YXV0aG9yOiB6aGFuZ2d1b2xpLmNu
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = ConcertConfig.class)
public class PerTest {


    @Autowired
    private Performance per;

    @Test
    public void testPerform() {
        //这个方法被Spring代理包裹起来了,在执行这个的前后执行AudienceJ类的相关方法(行为)
        per.perform();
    }
}

输出如下:

phone is silencing...

taking seats
kaixinmahua........
CALP CALP CALP

标签: Spring, aspect

添加新评论