spring_AOP

AOP (Aspect Orient Programming)面向切面编程

Aspect:表示切面,给业务方法增加的功能。切面一般都是非业务功能,而且切面功能一般都是可以复用的。例如日志功能、事务功能、权限检查、参数检查、统计信息等。
Joinpoint:连接点
Pointcut:切入点(一组连接点),表切面执行的位置
target:目标对象,给哪个对象增加切面的功能,这个对象就是目标对象
Advice:切面的执行时间,在目标方法之前执行切面,还是在目标方法之后执行切面
**

使用Aspectj框架实现AOP

1.Advice注解;
Aspectj表示切面执行时间,用的是通知(Advice)注解:
@Before:前置通知
@AfterReturning::后置通知
@Around:环绕通知
@AfterThrowing:异常通知
@After:最终通知
2.PointCut;
语法表示:execution(访问权限 方法返回值 方法声明(参数) 异常类型 );
通配符:
“*” 0-多个任意字符;
“…” 用在方法参数中,表示任意多个参数
###用在包名后,表示当前包及其子包路径;
“+” 用在类名后,表示当前类及其子类
###用在接口后,表示当前接口及其实现类;

实现步骤:

1.新建maven项目;
2.修改pom.xml,添加依赖:spring-aspects(使用aspectj框架的功能)
3.创建业务接口和实现类;
4.创建一个切面类

  1. 在类的上面加入@Aspect
  2. 在类中定义方法,方法表示切面的功能。在方法的上面加入Aspect框架中的通知注解,如@Before(value = "切入点表达式“)
@Aspect
public class MyAspect {
    @Before(value = "execution(void org.example.service.SomeServiceImpl.doSome(String,int))")
    public void MyBefore(){
        System.out.println("前置通知");
    }
}
前置通知方法的定义:
1)方法是public void,名称自定义
2)方法可以有参数,如果有是JoinPoint,也可以没有
JoinPont参数的作用:
表示正在执行的业务方法,使用要求必须是参数列表的第一个,作用是获取方法执行时的信息,如方法名称,方法的参数集合
@Aspect
public class MyAspect {
    @Before(value = "execution(void org.example.service.SomeServiceImpl.doSome(String,int))")
    public void MyBefore(JoinPoint jp){
        System.out.println("获取目标方法的定义"+jp.getSignature());
        System.out.println("获取目标方法的名称"+jp.getSignature().getClass());
        System.out.println("前置通知");
    }
}

5.创建spring配置文件

  • 1)声明目标对象
  • 2)声明切面类对象
  • 3)声明自动代理生成器
    <!-- 创建目标对象-->
    <bean id="someService" class="org.example.service.SomeServiceImpl"/>
    <!-- 创建切面类对象-->
    <bean id="myAspect" class="org.example.handle.MyAspect"/>
    <!-- 创建自动代理生成器-->
    <aop:aspectj-autoproxy/>

6.创建测试类,测试目标方法执行时,增加切面的功能

public class AppTest {
    @Test
    public void test01() {
        String config = "bean.xml";
        ApplicationContext cat = new ClassPathXmlApplicationContext(config);
        SomeService service = (SomeService)cat.getBean("someService");
        service.doSome("lisi",22);
    }
}

@AfterReturning:后置通知

@Aspect
public class MyAspect {
//    @AfterReturning:属性value,returning(
//    自定义的变量,表示目标方法的返回值,自定义变量名必须和通知方法的形参名一样)
//    特点:能获取到目标方法的执行结果
    @AfterReturning(value = "execution(* org.example.service.SomeServiceImpl.doOther(String,int))",returning = "res")
    public void MyAfter(Object res){

        System.out.println("后置通知");
    }
}

@Around :环绕通知

@Aspect
public class MyAspect {
//    @Around:属性value,
//    返回值:object,表示调用目标方法希望得到执行结果(不一定是目标方法自己的返回值)
//    参数:ProceedingJoinPoint(作用是执行目标方法)
//    public interface ProceedingJoinPoint extends JoinPoint{}

//    特点:1)在目标方法的前和后都能增强功能
//         2)控制目标方法是否执行
//         3)修改目标方法的执行结果
    @Around(value = "execution(* org.example.service.SomeServiceImpl.doFirst(String))")
    public Object MyAround(ProceedingJoinPoint pj) throws Throwable {

        System.out.println("环绕通知");
        Object o = pj.proceed();//执行目标方法
        return o;//返回目标方法的返回值
    }
}
执行结果:
1)环绕通知
2)执行doFirst(目标方法)
3)ab(目标方法的返回值)

@AfterThrowing:异常通知

@Aspect
public class MyAspect {
//AfterThrowing
//    方法没有返回值,方法的参数是Exception
//    属性:value,throwing表示目标方法抛出的异常。变量名必须和通知方法的形参名一样。
//    特点:1)在目标方法抛出异常后执行。没有异常不执行
//    2)能获取目标方法的异常信息
//    3)不是异常处理程序,可以得到发生异常的通知,可以发送邮件,短信通知开发人员,可以看作是目标方法的监控程序。
    @AfterThrowing(value = "execution(* org.example.service.SomeServiceImpl.doSecond(String))",throwing = "ex")
    public void MyThrowing(Exception ex) {

        System.out.println("异常通知");
    }
}

@After:最终通知

@After
//    属性:value
//    特点:1)在目标方法执行之后执行的
//    2)总会被执行
//    3)可以用来做程序最后的收尾工作,如:清除临时数据,变量,清理内存
    @After(value = "execution(* org.example.service.SomeServiceImpl.doThird(String))")
    public void myAfter(){
        System.out.println("执行after");
    }

@Pointcut

//    Pointcut:定义和管理切入点,不是通知注解
//    属性:value
//    位置:在一个自定义方法的上面。这个方法可以看作切入表达式的别名
    @After(value = "execution(* org.example.service.SomeServiceImpl.doThird(..))")
    public void myAfter(){
        System.out.println("执行after");
    }
    @Before(value = "execution(* org.example.service.SomeServiceImpl.doThird(..))")
    public void myBefore(){
        System.out.println("前置通知");
    }
    @Pointcut(value= "execution(* org.example.service.SomeServiceImpl.doThird(..))")
    public void mapt(){
//        无需代码
    }

AOP总结:

AOP是一种动态的技术思想,目的是实现业务功能的解耦合。业务功能是独立的模块,其他功能也是独立的模块。例如事务功能,日志等。让这些事务,日志功能是可以被复用的。
当目标方法需要一些功能时,可以在不修改,不能修改代码的情况下使用AOP技术在程序执行期间生成代理对象,通过代理对象执行业务方法,同时增加功能。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值