Spring(4): AOP

1. AOP定义和术语

AOP(Aspect Oriented Programming):面向切面编程。AOP可以把各类的公共行为封装到一个可重用模块,并将其命名为”Aspect”,即切面,便于减少系统的重复代码,降低模块之间的耦合度。常用的主要功能:日志记录,性能统计,安全控制,事务处理,异常处理。

术语介绍:
- 切面(Aspect):是对横切关注点的抽象。
- 切入点(Pointcut):对连接点进行拦截的定义。
- 连接点(Join point):指被拦截到的方法。
- 增强(Advice):指拦截到连接点之后要执行的代码,通知分为前置、后置、异常、最终、环绕通知五类。
- 引入(Introduction):引用允许你添加新方法或属性到现有的类中。
- 目标对象(Target object):被一个或者多个方面所通知的对象,这个对象永远是一个被代理对象。
- 织入(Weaving):将切面应用到目标对象并导致代理对象创建的过程。

2. Spring对AOP的支持

Spring AOP 事务管理的2种代理方式:
① 基于 JDK 接口的动态代理;
② 基于 CGLib 动态生成子类的代理。

2.1 使用注解创建切面

AspectJ的风格类似纯java注解的普通java类。AspectJ切面使用@Aspect注解配置,拥有@Aspect的任何bean将被Spring自动识别并应用。
用@Aspect注解的类可以有方法和字段,他们也可能包括切入点(pointcut),增强(Advice)和引入(introduction)声明。
@Aspect注解不能通过类路径自动检测发现,需要配合使用@Component注释或者在xml配置bean。

代码:

1.定义切面代码
@Aspect
public class Audience {

    @Pointcut("execution(* com.chen.aop.Concert.perform(..))")
    public void performance() {
    }

    @Before("performance()")
    public void slienceCellPhones() {
        System.out.println("Silencing cell phones.");
    }

    @After("performance()")
    public void takeSeats() {
        System.out.println("Leaving away.");
    }

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

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

}

说明:
@Aspect:表明类PreGreetingAspect不仅仅是一个POJO,还是一个切面。
@Pointcut:在切面内定义可重用的切点。

2.配置代码
@Configuration
@EnableAspectJAutoProxy(proxyTargetClass = true)
public class AopConfig {

    @Bean
    public Concert concert() {
        return new Concert();
    }

    @Bean
    public Audience audience(){
        return new Audience();
    }

}

说明:
@EnableAspectJAutoProxy:注解启动自动代理功能。proxyTargetClass默认为false,表示使用JDK动态代理技术织入增强;当配置为true时,表示使用CGLib动态代理技术织入增强。

3.测试代码
@RunWith(SpringRunner.class)
@SpringBootTest
@ContextConfiguration(classes = AopConfig.class)
public class ConcertTest {

    @Autowired
    private Concert concert;

    @Test
    public void testPerform() {
        assertNotNull(concert);
        concert.perform();
    }

    @Test
    public void testPerformByAutoProxy() {
        Concert target = new Concert();
        AspectJProxyFactory factory = new AspectJProxyFactory();

        // 1.设置目标对象
        factory.setTarget(target);
        // 2.添加切面类
        factory.addAspect(Audience.class);
        // 3.生成织入切面的代理对象
        Concert concert = factory.getProxy();

       concert.perform();
    }

}

AspectJ提供的5个注解:

  1. @Before:增强方法会在目标方法调用之前执行;
  2. @Around:增强方法将目标方法封装起来;
  3. @After:增强方法会在目标方法返回或抛出异常后调用;
  4. @AfterReturning:增强方法会在目标方法返回后调用;
  5. @AfterThrowing:增强方法会在目标方法抛出异常后调用。

2.2 使用XML配置AOP

Spring所有的切面和增强都必须放在一个<aop:config>内(可以配置包含多个<aop:config> 元素),每一个<aop:config>可以包含pointcut,advisor和aspect元素,它们必须按照这个顺序进行声明。
<aop:config>使用Spring的自动代理机制。
代码:

<?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">

    <!--基于@Aspect切面的驱动器-->
    <aop:aspectj-autoproxy proxy-target-class="true"/>

    <!--目标Bean-->
    <bean id="concert" class="com.chen.aop.Concert"/>
    <bean id="audience" class="com.chen.aop.Audience"/>

    <aop:config>
        <aop:aspect ref="audience">
            <aop:pointcut id="performance" expression="execution(* com.chen.aop.Concert.perform(..))"/>
            <aop:before pointcut-ref="performance" method="silenceCellPhones"/>
            <aop:after pointcut-ref="performance" method="leaveAway"/>
            <aop:after-returning pointcut-ref="performance" method="applause"/>
            <aop:after-throwing pointcut-ref="performance" method="demandRefund"/>
            <aop:around pointcut-ref="performance" method="watchPerformance"/>
        </aop:aspect>
    </aop:config>

</beans>

源代码:
https://github.com/leifchen/hello-spring
代码包:com.chen.aop

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值