Spring AOP

一、Spring AOP概述

    AOP(Aspect Oriented Programming),即面向切面编程,可以说是OOP(Object Oriented Programming,面向对象编程)的补充和完善。OOP引入封装、继承、多态等概念来建立一种对象层次结构,用于模拟公共行为的一个集合。不过 OOP允许开发者定义纵向的关系,但并不适合定义横向的关系,例如日志功能。日志代码往往横向地散布在所有对象层次中,而与它对应的对象的核心功能毫无关系对于其他类型的代码,如安全性、异常处理和透明的持续性也都是如此,这种散布在各处的无关的代码被称为横切(cross cutting),在OOP设计中,它导致了大量代码的重复,而不利于各个模块的重用。

    AOP技术,它利用一种称为"横切"的技术,剖解开封装的对象内部,并将那些影响了多个类的公共行为封装到一个可重用模块,并将其命名 为"Aspect",即切面。所谓"切面",简单说就是那些与业务无关,却为业务模块所共同调用的逻辑或责任封装起来,便于减少系统的重复代码,降低模块之间的耦合度,并有利于未来的可操作性和可维护性。

    使用"横切"技术,AOP把软件系统分为两个部分:核心关注点和横切关注点。业务处理的主要流程是核心关注点,与之关系不大的部分是横切关注点

二、代理模式

    1.静态代理

    2.动态代理:

package com.dailyblue.java.spring.代理模式.动态代理;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays;

public class DynamicProxy implements InvocationHandler {
    @Override//Class[]  Object[]
    //Object proxy为代理的对象,Method method对象的方法,Object[] args为实参列表
    public Object invoke(Object proxy, Method method, Object[] args)  
            throws Throwable {
        System.out.println("我是代理商,我负责代理EmpMapper的所有事宜");
        String methodName = method.getName();
        if("saveEmp".equals(methodName)){
            System.out.println("执行了对Emp表的插入操作,Id:"+ Arrays.toString(args));
        }else if("toString".equals(methodName)){
            System.out.println("toString方法被执行");
            return "我是toString";
        }
        return null;
    }

    public static <T> T getMapper(Class<T> c){
        ClassLoader loader = DynamicProxy.class.getClassLoader();
        Class[] cs = {c};
        DynamicProxy dp = new DynamicProxy();  //产生新的代理对象
        Object obj = Proxy.newProxyInstance(loader,cs,dp);  //cs要代理的对象
        return (T)obj;
    }
}

三、Spring AOP的名词解释

    a)切面:切面是通过创建一个使用@Aspect注解的类来定义的。

    b)连接点(Join point):指方法在Spring AOP中,一个连接点总是代表一个方法的执行。连接点可以看成是触发的时机。

    c)通知(Advice):在切面的某个特定的连接点(Join point)上执行的动作。通知有五种通知:前置通知(Before advice)、返回后通知(After returning advice)、抛出异常后通知(After throwing advice)、后置(最终)通知(After (finally) advice)、环绕通知(Around Advice)。

    d)切入点(Pointcut):切入点是指我们要对哪些连接点(Join point)进行拦截的定义。通过切入点表达式,指定拦截的方法,比如指定拦截add*、search*。

    e)引入(Introduction):声明额外的方法或者某个类型的字段。Spring允许引入新的接口(以及一个对应的实现)到任何被代理的对象。在不修改代码的前提下,引入可以在运行期为类动态地添加一些方法或字段。

    f)目标对象(Target Object):被一个或者多个切面(aspect)所通知(advise)的对象,也有人把它叫做被通知(adviced)对象.

    g) 织入(Weaving):指把增强应用到目标对象来创建新的代理对象的过程。Spring是在运行时完成织入。

五.Spring AOP的实现

    1.导jar包:spring-context、spring-aop、aspectjrt、aspectjweaver。

    2.xml方式

        a)书写目标对象的接口

        b)书写目标对象的实现

        c)书写通知

        d)在resource文件夹下xml文件中进行过配置:

<?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:context="http://www.springframework.org/schema/context"
       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/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">
    <context:annotation-config/>
    <context:component-scan base-package="com.dailyblue.java.spring.aop"/>

    <!--设置切入点,连接点的集合-->
    <bean id="pointcut" class="org.springframework.aop.support.JdkRegexpMethodPointcut">
        <property name="pattern" value=".*find.*" />  //find代表包含find字段的方法
    </bean>

    <bean id="pointcutAdvisor" class="org.springframework.aop.support.DefaultPointcutAdvisor">
        <property name="pointcut" ref="pointcut"/>
        <property name="advice" ref="firstAdvice" />
    </bean>

    <bean id="proxy" class="org.springframework.aop.framework.ProxyFactoryBean">
        <property name="target" ref="firstTargetImpl" />
        <property name="interceptorNames" value="pointcutAdvisor"/>
        <property name="proxyInterfaces" value="com.dailyblue.java.spring.aop.aop1.FirstTarget"/>
    </bean>
</beans>

         e)书写测试类

    3.注解方式

        前置注解:@Before("execution(* 包.类.方法(..))")  //*代表项目 ,括号里的..代表所有方法

        后置注解:@After("execution(项目 包.类.方法(..))")


    /**
     * 定义AOP签名 (切入所有使用鉴权注解的方法)
     */
    public static final String POINTCUT_SIGN = "@annotation(com.xyz.common.core.annotation.PermissionLimit)";

    /**
     * Construct
     */
    @Pointcut(POINTCUT_SIGN)
    public void checkPermissionCutPoint(){
    }

    @Around("checkPermissionCutPoint()")
    public Object check(ProceedingJoinPoint joinPoint) throws Throwable {
        log.info("Checking permission");
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值