Spring的AOP注解方式(十)

17 篇文章 0 订阅

AOP注解方式

使用Spring的AOP注解开发,所需要引入的JAR跟xml方式是一样的,4个基础jar包,2个日志jar包,4个aop jar包,和1个整合junit的jar包 如下:

引入jar包:
在这里插入图片描述

还需要引入配置文件,并且配置文件中需要添加AOP的约束,下面是完整的约束,其中有AOP,注解组件扫描,事务,bean等约束

applicationContext.xml:

<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:aop="http://www.springframework.org/schema/aop"
	xmlns:tx="http://www.springframework.org/schema/tx"
	xsi:schemaLocation="http://www.springframework.org/schema/beans 
	http://www.springframework.org/schema/beans/spring-beans.xsd
	http://www.springframework.org/schema/context
	http://www.springframework.org/schema/context/spring-context.xsd
	http://www.springframework.org/schema/aop
	http://www.springframework.org/schema/aop/spring-aop.xsd
	http://www.springframework.org/schema/tx 
	http://www.springframework.org/schema/tx/spring-tx.xsd">
</beans>

引入约束以后,还需要在配置文件中配置AOP命名空间的声明,让Spring为注解的切面类自动创建代理,织入切面,需要在配置文件中加入:

<!--在配置文件中开启AOP命名空间的声明-->
<!--自动创建代理-->
<aop:aspectj-autoproxy/>

<aop:aspectj-autoproxy />有一个proxy-target-class属性,默认为false,表示使用jdk动态代理织入增强。

当配为<aop:aspectj-autoproxy poxy-target-class=“true”/>时,表示使用CGLib动态代理技术织入增强。

不过即使proxy-target-class设置为false,如果目标类没有声明接口,则spring将自动使用CGLib动态代理。

然后创建一个目标类OrderDao,并且创建四个目标方法:

OrderDao:

public class OrderDao {
    public void save() { System.out.println("保存方法"); }

    public void update() {
        System.out.println("修改方法");
    }

    public void find() {
        System.out.println("查询方法");
    }

    public void del() {
        System.out.println("删除方法");
    }
}

然后就是创建一个切面类MyAspectAnno,在类上添加 @Aspect 注解,让Spring将这个类识别为切面类。

在增强方法上使用@Before 注解,标志该方法为前置增强(通知),并且通过 value 属性配置表达式指定相应的目标方法。

MyAspectAnno:

/*
* 注解方式的切面类
* */

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;

//@Aspect 注解会让spring自动将这个类识别为切面类
@Aspect
public class MyAspectAnno {
    //使用@Before注解,标识这是一个前置增强,以value属性通过表达式指定目标方法
    @Before(value = "execution(* SpringDemo.OrderDao.save(..))")
    public void before() {
        System.out.println("前置增强=========");
    }
}

然后将目标类和切面类交给Spring管理,在配置文件中声明两个bean标签:

<!--配置目标类-->
<bean name="orderDao" class="SpringDemo.OrderDao"/>

<!--配置切面类-->
<bean id="myAspect" class="SpringDemo.MyAspectAnno"/>

最后创建一个Spring整合Junit的测试类

test:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class test {

    @Resource(name ="orderDao")
    private OrderDao orderDao;

    @Test
    public void test() {
        orderDao.save();
    }
}

AOP的注解通知类型

在所有的通知类型中,都可以通过JoinPoint 类设定参数,然后获得切入点的信息。

  • @Before:前置通知
//使用@Before注解,标识这是一个前置增强,以value属性通过表达式指定目标方法
//增强方法可以通过joinPoint参数获得切入点的信心
@Before(value = "execution(* SpringDemo.OrderDao.save(..))")
public void before(JoinPoint joinPoint) {
    System.out.println("前置增强=========" + joinPoint.getclass());
}
  • @AfterReturning
//后置增强可以通过returning 获得方法中的返回值,returning定义的名称要和增强方法中的参数名称一样
@AfterReturning(value="execution(* SpringDemo.OrderDao.del(..))",returning = "result")
public void afterReturn(Object result){
    System.out.println("后置增强========" + result);
}
  • @Around:环绕通知
//环绕通知,通过ProceedingJoinPoint中的proceed方法来执行目标方法
// 同时创建一个object对象接收可能存在的返回值
//在proceed方法前后书写逻辑即可达到环绕的效果,甚至可以阻止目标方法运行
@Around(value="execution(* SpringDemo.OrderDao.update(..))")
public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
    System.out.println("环绕前置通知");
    //通过proceed执行目标方法,通过object类型接受方法可能存在的返回值
    Object obj = proceedingJoinPoint.proceed();
    System.out.println("环绕后置通知");
    return obj;
}
  • @AfterThrowing :异常抛出通知
 //异常抛出通知是当目标方法抛出异常的情况下才会增强,
 // 可以通过throwing 属性指定一个名称,要和增强方法中定义的Throwable参数名称一致
 //可以通过Throwable类输出异常信息
@AfterThrowing(value="execution(* SpringDemo.OrderDao.find(..))",throwing="ex")
public void throwing(Throwable ex){
    System.out.println("异常抛出通知" + ex.getMessage());
}
  • After:最终通知
//最终通知
//最终通知无论发生什么情况,总是会执行,类似于finally代码块中的内容
@After(value="execution(* SpringDemo.OrderDao.find(..))")
public void after(){
    System.out.println("执行最终通知");
}

切入点的注解

@Pointcut:切入点注解


//增强类名.切入点名称(方法名)的格式引用切入点方法
@After(value="MyAspectAnno.Pointcut4()")
public void after(){
    System.out.println("执行最终通知");
}


 //切入点的注解@Pointcut,类似于在XML中配置切入点信息一样
 //还需要定义一个空的方法,并无实际作用,只起到给切入点设定名称的作用,所以定义为私有类型
 //在增强方法中通过  增强类名.切入点名称(方法)的格式引用
 @Pointcut(value="execution(* SpringDemo.OrderDao.save(..))")
 private void Pointcut1(){}
 @Pointcut(value="execution(* SpringDemo.OrderDao.del(..))")
 private void Pointcut2(){}
 @Pointcut(value="execution(* SpringDemo.OrderDao.find(..))")
 private void Pointcut3(){}
 @Pointcut(value="execution(* SpringDemo.OrderDao.update(..))")
 private void Pointcut4(){}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值