zoukankan      html  css  js  c++  java
  • Spring-11-AOP面向切面编程

    11.AOP

    11.1 什么是AOP?

    AOP,意为面向切面编程,通过预编译和运行时动态代理实现程序功能的统一维护的一种技术。

    在这里插入图片描述

    11.2 AOP在Spring中的作用

    提供声明式事务:允许用户自定义切面

    • 横切关注点:跨越应用程序多个模块的方法或功能;

    • 切面:横切关注点 被模块化 的特殊对象,即一个类;

    • 通知:切面必须要完成的工作:即类中的一个方法;

    • 目标:被通知的对象;

    • 代理:向目标对象应用通知后创建的对象;

    • 切入点:切面通知执行的地点的定义;

    • 连接点:与切入点匹配的执行点;

    在这里插入图片描述

    SpringAOP中,通过Advice定义横切逻辑,Spring支持5种类型的Advice:

    • 前置通知
    • 后置通知
    • 环绕通知
    • 异常抛出通知
    • 引介通知

    11.3 使用Spring实现AOP

    【重点】使用AOP织入,需要导入一个依赖包

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

    方式一:使用Spring的API接口【主要是Spring接口实现】

    业务接口:

    public interface UserService {
        public void add();
        public void delete();
        public void update();
        public void select();
    }
    

    实现类:(类似于host)

    public class UserServiceImpl implements UserService{
        public void add() {
            System.out.println("增加一个用户");
        }
    
        public void delete() {
            System.out.println("删除一个用户");
        }
    
        public void update() {
            System.out.println("更新一个用户");
        }
    
        public void select() {
            System.out.println("查询一个用户");
        }
    
    
    }
    

    增强方法:

    public class Log implements MethodBeforeAdvice {
    
        //method:要执行的目标对象的方法
        //args:参数
        //target:目标对象
        public void before(Method method, Object[] args, Object target) throws Throwable {
            System.out.println(target.getClass().getName()+"的"+method.getName()+"被执行了");
        }
    }
    
    public class AfterLog implements AfterReturningAdvice {
        //o=returnValue:返回值
        public void afterReturning(Object o, Method method, Object[] objects, Object o1) throws Throwable {
            System.out.println("执行了"+method.getName()+"方法,返回结果为"+o);
        }
    }
    
    

    applicationContext.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:aop="http://www.springframework.org/schema/aop"
           xsi:schemaLocation="http://www.springframework.org/schema/beans
            https://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/aop
            https://www.springframework.org/schema/aop/spring-aop.xsd">
    
        <!--注册bean-->
        <bean id="userService" class="com.kuang.service.UserServiceImpl"/>
        <bean id="log" class="com.kuang.log.Log"/>
        <bean id="afterLog" class="com.kuang.log.AfterLog"/>
    
        <!--方式一:使用原生Spring API接口-->
        <!--配置aop:需要导入aop约束-->
        <aop:config>
            <!--切入点:pointcut 表达式:expression,execution()-->
            <aop:pointcut id="pointcut" expression="execution(* com.kuang.service.UserServiceImpl.*(..))"/>
    
            <!--执行环绕增强-->
            <aop:advisor advice-ref="log" pointcut-ref="pointcut"/>
            <aop:advisor advice-ref="afterLog" pointcut-ref="pointcut"/>
    
        </aop:config>
    </beans>
    

    方式二:自定义来实现AOP【主要是切面定义】

    自定义类(切面):

    public class DiyPointCut {
        public void before(){
            System.out.println("=====方法执行前=====");
        }
        public void after(){
            System.out.println("=====方法执行后=====");
        }
    }
    

    applicationContext.xml配置:

    <!--方式二:自定义类-->
    <bean id="diy" class="com.kuang.diy.DiyPointCut"/>
    
    <aop:config>
        <!--自定义切面,ref表示要引用的类-->
        <aop:aspect ref="diy">
            <!--切入点-->
            <aop:pointcut id="point" expression="execution(* com.kuang.service.UserServiceImpl.*(..))"/>
            <!--通知-->
            <aop:before method="before" pointcut-ref="point"/>
            <aop:after method="after" pointcut-ref="point"/>
        </aop:aspect>
    </aop:config>
    

    方式三:使用注解实现!

    切面:

    //使用注解实现AOP
    @Aspect //标注这个类是一个切面
    public class AnnotationPointCut {
        @Before("execution(* com.kuang.service.UserServiceImpl.*(..))")
        public void before(){
            System.out.println("=====方法执行前=====");
        }
        @After("execution(* com.kuang.service.UserServiceImpl.*(..))")
        public void after(){
            System.out.println("=====方法执行后=====");
        }
        //环绕增强中,我们可以给定一个参数,代表我们要获取处理切入的点
        @Around("execution(* com.kuang.service.UserServiceImpl.*(..))")
        public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
            System.out.println("环绕前");
    
            System.out.println(proceedingJoinPoint.getSignature());//获得签名
            //执行方法
            Object proceed = proceedingJoinPoint.proceed();
    
            System.out.println("环绕后");
        }
    }
    

    applicationContext.xml的配置:

    <!--方式三:使用注解实现aop jdk(默认) cglib-->
    <bean id="annotationPointCut" class="com.kuang.diy.AnnotationPointCut"/>
    <!--开启注解支持-->
    <aop:aspectj-autoproxy />
    

  • 相关阅读:
    easy ui 表单ajax和from两种提交数据方法
    easy ui 下拉级联效果 ,下拉框绑定数据select控件
    easy ui 下拉框绑定数据select控件
    easy ui 异步上传文件,跨域
    easy ui 菜单和按钮(Menu and Button)
    HTTP 错误 404.3
    EXTJS4.2 后台管理菜单栏
    HTML 背景图片自适应
    easy ui 表单元素input控件后面加说明(红色)
    EXTJS 4.2 添加滚动条
  • 原文地址:https://www.cnblogs.com/CodeHuba/p/13570633.html
Copyright © 2011-2022 走看看