了解AOP以及实现方式

Posted yimengxianzhi

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了了解AOP以及实现方式相关的知识,希望对你有一定的参考价值。

AOP是什么?

面向切面编程,把那些与业务无关,却为业务模块所共同调用的逻辑封装成一个可重的模块,即切面
使用"横切"技术,AOP把软件系统分为两个部分:核心关注点和横切关注点。业务处理的主要流程是核心关注点,与之关系不大的部分是横切关注点

为什么使用AOP?

如果说面向对象编程是关注将需求功能划分为不同的并且相对独立,封装良好的类,并让它们有着属于自己的行为,依靠继承和多态等来定义彼此的关系的话;那么面向切面编程则是希望能够将通用需求功能从不相关的类当中分离出来,能够使得很多类共享一个行为,一旦发生变化,不必修改很多类,而只需要修改这个行为即可。

如下,有两个方法分别为mul和div,这两个方法的内容代码大多数是重复的,则我们可以抽离一个新的方法

package com.zzj.calculatar.service;
import org.springframework.stereotype.Service;

@Service
public class CalculatorService implements ICalculatorService{

    @Override
    public int mul(int a, int b) {
        System.out.println("The mul method begins.");
        System.out.println("The mul method args:["+a+","+b+"]");
        return a*b;
    }

    @Override
    public int div(int a, int b) {
        System.out.println("The div method begins.");
        System.out.println("The div method args:["+a+","+b+"]");
        return a/b;
    }
    
}

新的方法如下:

@Service
public class CalculatorService implements ICalculatorService{

    @Override
    public int mul(int a, int b) {
        t("mul", a, b);
        return a*b;
    }

    @Override
    public int div(int a, int b) {
        t("div", a, b);
        return a/b;
    }
    
    private void t(String methodName,int a,int b){
        System.out.println("The"+methodName+"method begins.");
        System.out.println("The"+methodName+"method args:["+a+","+b+"]");
    }
    
}

AOP的切面化就体现在此,具体的AOP实现方式有:注解和XML配置

package com.zzj.calculatar.service;
import org.springframework.stereotype.Service;

@Service
public class CalculatorService implements ICalculatorService{

    @Override
    public int mul(int a, int b) {
        return a*b;
    }

    @Override
    public int div(int a, int b) {
        return a/b;
    }
    
}

注解方式实现AOP:

package com.zzj.aspect;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;


@Order(1)//切片执行顺序,默认为字典顺序
@Aspect
@Component
public class CalculatorAspect {

        //提取表达式
    @Pointcut("execution(public int com.zzj.calculatar.service.CalculatorService.*(..))")
    public void pointCut(){
        
    }
    
    @Around(value="pointCut()")
    public Object around(ProceedingJoinPoint joinPoint){
        Object result = null;
        Object target = joinPoint.getTarget();//目标对象
        String methodName = joinPoint.getSignature().getName();
        Object[] params = joinPoint.getArgs();
        
        try{
            try{
                //前置增强
                System.out.println(target.getClass().getName()+": The "+methodName+" method begins.");
                System.out.println(target.getClass().getName()+": Parameters of the "+methodName+"method: ["+params[0]+","+params[1]+"]");
                //执行目标对象内的方法
                result = joinPoint.proceed();
            }finally{
                //后置增强
                System.out.println(target.getClass().getName()+":The "+methodName+" method ends.");
            }
            //返回增强
            System.out.println(target.getClass().getName()+":Result of the "+methodName+" method:"+result);
        }catch (Throwable e) {
            System.out.println(target.getClass().getName()+":Exception of the method "+methodName+": "+e);
        }
        return result;
    }
    
}    
<!--XML代码-->
<context:component-scan base-package="com.zzj"></context:component-scan>
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>

XML配置方式实现AOP(不需要注解,将注解放在XML中):

package com.zzj.aspect;
import org.aspectj.lang.ProceedingJoinPoint;
public class CalculatorAspect {
    public Object around(ProceedingJoinPoint joinPoint){
        Object result = null;
        Object target = joinPoint.getTarget();//目标对象
        String methodName = joinPoint.getSignature().getName();
        Object[] params = joinPoint.getArgs();
        
        try{
            try{
                //前置增强
                System.out.println(target.getClass().getName()+": The "+methodName+" method begins.");
                System.out.println(target.getClass().getName()+": Parameters of the "+methodName+"method: ["+params[0]+","+params[1]+"]");
                //执行目标对象内的方法
                result = joinPoint.proceed();
            }finally{
                //后置增强
                System.out.println(target.getClass().getName()+":The "+methodName+" method ends.");
            }
            //返回增强
            System.out.println(target.getClass().getName()+":Result of the "+methodName+" method:"+result);
        }catch (Throwable e) {
            System.out.println(target.getClass().getName()+":Exception of the method "+methodName+": "+e);
        }
        return result;
    }
}
<!--扫描-->
<context:component-scan base-package="com.zzj"></context:component-scan>
<!--获取aspect类-->
<bean id="calculatorAspect" class="com.zzj.aspect.CalculatorAspect"></bean>

<aop:config>
        <!--提取表达式-->
    <aop:pointcut expression="execution(public int com.zzj.calculatar.service.CalculatorService.*(..))" id="pointCut"/>
        <!--环绕增强-->
    <aop:aspect ref="calculatorAspect" order="1">
        <aop:around method="around" pointcut-ref="pointCut"/>
    </aop:aspect>
</aop:config>

测试类:

package com.zzj.test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.zzj.calculatar.service.ICalculatorService;

public class Test {

    public static void main(String[] args){
        
        ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("application.xml");
        ICalculatorService calculatorService = applicationContext.getBean(ICalculatorService.class);
        System.out.println(calculatorService.getClass());//当有代理类时,获取的代理对象
        System.out.println(calculatorService.div(1,1));
        applicationContext.close();
        
    }
    
}

测试结果:

技术图片

 

以上是关于了解AOP以及实现方式的主要内容,如果未能解决你的问题,请参考以下文章

通过注解方式实现IOC和AOP

Spring框架学习笔记 --- [在spring中初步上手实现AOP,以及对事务的初步配置使用]

一起学Spring之注解和Schema方式实现AOP

Spring实现AOP的4种方式

Spring详解------AspectJ 实现AOP

Spring实现AOP的4种方式