码迷,mamicode.com
首页 > 其他好文 > 详细

了解AOP以及实现方式

时间:2020-02-05 00:00:58      阅读:103      评论:0      收藏:0      [点我收藏+]

标签:--   http   static   org   conf   core   测试   parameter   exce   

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以及实现方式

标签:--   http   static   org   conf   core   测试   parameter   exce   

原文地址:https://www.cnblogs.com/yimengxianzhi/p/12261804.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!