spring - aop (三种实现方式)

Aop切面思想

在不影响原有功能业务的情况下,横向切入某些功能(事务,日志…) ,称之为切面;

切面的 组成

横切关注点:跨应用多个模块的方法 或者功能 ;及与业务逻辑无关 ,且需要我们关注的功能点;称之为 横切关注点
比如:日志 事务 安全

切面(ASPCET):横切关注点被模块化为一个特殊的对象  : 类

通知(Advice):必须要完成的一个工作  : 必须执行的方法  

通知目标(Target):被通知的对象

代理(Proxy):向目标对象应用通知后创建的对象

切入点(PointCut):切面通知执行 "地点" 的定义

接入点(JOinPoint):与切入点匹配的执行点;

实现aop的3种方式

导入 依赖都是必须的

<dependency>
   <groupId>org.aspectj</groupId>
   <artifactId>aspectjweaver</artifactId>
   <version>1.9.5</version>
</dependency>

方式一

使用 spring API 接口

//执行前
public class Log implements MethodBeforeAdvice {
    //method  : 要执行的目标对象方法
    //object 参数类型
    //target 目标对象
    public void before(Method method, Object[] args, Object target) throws Throwable {
        System.out.println(target.getClass().getSimpleName()+"的"+method.getName()+"方法");
    }
}
//执行后
public class AfterLog implements AfterReturningAdvice {
    public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
        System.out.println(target.getClass().getSimpleName()+"的"+method.getName()+"方法"
        +"的返回结果为"+returnValue);
    }
}
//接口

public interface UserService {
     void add();
     void select();
     void update();
     void delete();
}
//接口实现
public class UserServiceImple implements UserService {
    public void add() {
        System.out.println("增加了一个用户");
    }

    public void select() {
        System.out.println("查询用户");
    }

    public void update() {
        System.out.println("修改了一个用户");
    }

    public void delete() {
        System.out.println("删除了一个用户");
    }
}
//测试
public class MyTest {
    public  static  void main(String [] args){
        //获取spring的上下文对象
        ApplicationContext context = new ClassPathXmlApplicationContext("applictionContext.xml");
         Hello h = (Hello) context.getBean("h");
        System.out.println(h.toString());
    }
}

配置文件

    <!--配置aop ;需要导入aop约束-->
    xmlns:aop="http://www.springframework.org/schema/aop"
    http://www.springframework.org/schema/aop
    https://www.springframework.org/schema/aop/spring-aop.xsd">

<!--  方式一 使用原生态Spring API核心-->

    <aop:config>
        <!--切入点 : expression:表达式   execution(需要执行的位置)-->
        <!--
   execution(* sl.service.UserServiceImple.*(..))
    第一个 * 表示返回值    
    sl.service.UserServiceImple 表示切入的类
    第二个 * 代表 类下的所有方法
   (..) 方法参数  表示 方法内参数可有可无
    -->
        <aop:pointcut id="pointcut" expression="execution(* sl.service.UserServiceImple.*(..))"/>
        <!--执行环绕增强-->
        <aop:advisor advice-ref="log" pointcut-ref="pointcut"/>
        <aop:advisor advice-ref="afterLog" pointcut-ref="pointcut"/>
    </aop:config>

方式二

自定义类 实现AOP

//定义  diy 类
public class AopDiy {
    public  void before(){
        System.out.println("执行前");
    }
    public  void after(){
        System.out.println("执行后");
    }
}
//测试
public class MyTest {
    public  static  void main(String [] args){
        //获取spring的上下文对象
        ApplicationContext context = new ClassPathXmlApplicationContext("applictionContext.xml");
         Hello h = (Hello) context.getBean("h");
        System.out.println(h.toString());
    }
}

配置文件

<!--方式二  自定义diy类 实现aop-->
     <!--注册 beans-->
    <bean id="aopDiy" class="sl.diy.AopDiy"/>
    <aop:config>
        <!--自定义切面-->
        <aop:aspect ref="aopDiy">
            <!-- 定义切入点-->
            <aop:pointcut id="point" expression="execution(* sl.service.UserServiceImple.*(..))"/>
            <aop:before method="before" pointcut-ref="point"/>
            <aop:after method="after" pointcut-ref="point"/>
        </aop:aspect>
    </aop:config>

方式三

注解 实现 AOP

//使用注解实现 aop
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;

@Aspect//标注这是一个切面
public class AnnotationPointCut {
    //后置增强
    @Before("execution(* sl.service.UserServiceImple.*(..))")
    public void before(){
        System.out.println("执行前");
    }
    //前置增强
    @After("execution(* sl.service.UserServiceImple.*(..))")
     public void after(){
         System.out.println("执行后");
     }
     //环绕增强 我们可以定义一个参数  ,代表我们要切入的点;
    @Around("execution(* sl.service.UserServiceImple.*(..))")
     public void around(ProceedingJoinPoint joinPoint) throws Throwable {
         System.out.println("环绕前");
            //获取签名
            Signature signature = joinPoint.getSignature();
            //执行方法
            Object o = joinPoint.proceed();

        System.out.println("环绕后");
        System.out.println(signature);
    }
}

配置文件

 <!--方式三-->
    <bean id="annotationPointCut" class="sl.zhujie.AnnotationPointCut"/>
    <!--开启注解支持
    两种
    1. 默认 JDK(proxy-target-class="false")
    2. ture cglib(proxy-target-class="true")-->
    <aop:aspectj-autoproxy />
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值