栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

spring快速入门-Aop

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

spring快速入门-Aop

Aop

​ AOP(Aspect Oriented Programming):意为面向切片编程;
​ AOP 是一种编程思想,是面向对象编程(OOP)的一种补充。面向对象编程将程序抽象成各个层次的对象,而面向切面编程是将程序抽象成各个切面。


        
            org.aspectj
            aspectjweaver
            1.9.4
        
    
AOP核心概念

    1、横切关注点:对哪些方法进行拦截,拦截后怎么处理,这些关注点称之为横切关注点

    2、切面(aspect):类是对物体特征的抽象,切面就是对横切关注点的抽象

    3、连接点(joinpoint):被拦截到的点,因为Spring只支持方法类型的连接点,所以在Spring中连接点指的就是被拦截到的方法,实际上连接点还可以是字段或者构造器

    4、切入点(pointcut):对连接点进行拦截的定义

    5、通知(advice):所谓通知指的就是指拦截到连接点之后要执行的代码,通知分为前置、后置、异常、最终、环绕通知五类

    6、目标对象:代理的目标对象

    7、织入(weave):将切面应用到目标对象并导致代理对象创建的过程

    8、引入(introduction):在不修改代码的前提下,引入可以在运行期为类动态地添加一些方法或字段

Spring对AOP的支持

Spring中AOP代理由Spring的IOC容器负责生成、管理,其依赖关系也由IOC容器负责管理。
因此,AOP代理可以直接使用容器中的其它bean实例作为目标,这种关系可由IOC容器的依赖注入提供。Spring创建代理的规则为:

1、默认使用Java动态代理来创建AOP代理,这样就可以为任何接口实例创建代理了

2、当需要代理的类不是代理接口的时候,Spring会切换为使用CGLIB代理,也可强制使用CGLIB

AOP编程其实是很简单的事情,

纵观AOP编程,程序员只需要参与三个部分:

1、定义普通业务组件

2、定义切入点,一个切入点可能横切多个业务组件

3、定义增强处理,增强处理就是在AOP框架为普通业务组件织入的处理动作
所以进行AOP编程的关键就是定义切入点和定义增强处理,一旦定义了合适的切入点和增强处理,AOP框架将自动生成AOP代理,即:代理对象的方法=增强处理+被代理对象的方法。
Advice通知类型
(1)Before:在目标方法被调用之前做增强处理,@Before只需要指定切入点表达式即可

(2)AfterReturning:在目标方法正常完成后做增强,@AfterReturning除了指定切入点表达式后,还可以指定一个返回值形参名returning,代表目标方法的返回值

(3)AfterThrowing:主要用来处理程序中未处理的异常,@AfterThrowing除了指定切入点表达式后,还可以指定一个throwing的返回值形参名,可以通过该形参名

来访问目标方法中所抛出的异常对象

(4)After:在目标方法完成之后做增强,无论目标方法时候成功完成。@After可以指定一个切入点表达式

(5)Around:环绕通知,在目标方法完成前后做增强处理,环绕通知是最重要的通知类型,像事务,日志等都是环绕通知,注意编程中核心是一个ProceedingJoinPoint
流程 编写实体类
package method;

public interface UserDAO {
    void add();

    void update();

    void delete();
}
package method;

import org.springframework.stereotype.Component;

@Component
public class UserDAOImpl implements UserDAO{
    @Override
    public void add() {
        System.out.println("add~~~~~");
    }

    @Override
    public void update() {
        System.out.println("update~~~~~");
    }

    @Override
    public void delete() {
        System.out.println("delete~~~~~");
    }
}
方式一

编写增强类

package method;

import org.aspectj.lang.annotation.AfterThrowing;
import org.springframework.aop.AfterAdvice;
import org.springframework.aop.AfterReturningAdvice;

import java.lang.reflect.Method;

public class AfterTest implements AfterReturningAdvice {
    @Override
    public void afterReturning(Object o, Method method, Object[] objects, Object o1) throws Throwable {
        System.out.println("[AfterReturningLog]:执行了"+"---"+method.getName());
    }
}
package method;

import org.aopalliance.aop.Advice;
import org.springframework.aop.BeforeAdvice;
import org.springframework.aop.MethodBeforeAdvice;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

@Component
public class BeforeTest implements MethodBeforeAdvice {

    @Override
    public void before(Method method, Object[] objects, Object o) throws Throwable {
        System.out.println("[beforeLog]:执行了"+"---"+method.getName());
    }
}

配置bean.xml




    
    
    
    
        
        
        
    

测试

@Test
public void test6(){
    ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("bean2.xml");
    UserDAO userDao = context.getBean("userDao", UserDAO.class);
    userDao.add();
}

方式二

编写增强类

package method;


import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;

public class Log {

    //前置通知
    public void before(){
        System.out.println("前置通知)~~~");
    }

    //最终通知
    public void after(){
        System.out.println("最终通知~~~");
    }

    //异常通知
    public void afterThrowing(){
        System.out.println("异常通知~~~");
    }

    //返回通知
    public void afterReturning(){
        System.out.println("返回通知~~~");
    }

    //环绕通知
    public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        System.out.println("环绕之前~~~");
        proceedingJoinPoint.proceed();
        System.out.println("环绕之后~~~");
    }
}

织入





    
    

    
        
            
            
            
            
            
            
        
    

测试

@Test
public void test6(){
    ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("bean2.xml");
    UserDAO userDao = context.getBean("userDao", UserDAO.class);
    userDao.add();
}

当有异常发生时的输出结果:

package method;

import org.springframework.stereotype.Component;

@Component
public class UserDAOImpl implements UserDAO{
    @Override
    public void add() {
        int x=10/0;
        System.out.println("add~~~~~");
    }

    @Override
    public void update() {
        System.out.println("update~~~~~");
    }

    @Override
    public void delete() {
        System.out.println("delete~~~~~");
    }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IOmHyxla-1635772458273)(C:Users74374AppDataRoamingTyporatypora-user-imagesimage-20211101162552604.png)]

可以发现当异常发生时,最终通知还是调用了,而AfterReturning没有调用,说明After(最终通知)必定会被调用

方式三

注解开放

package method;


import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;

@Aspect
public class Log {

    @Before("execution(* method.UserDAOImpl.*(..))")
    //前置通知
    public void before(){
        System.out.println("前置通知)~~~");
    }

    @After("execution(* method.UserDAOImpl.*(..))")
    //最终通知
    public void after(){
        System.out.println("最终通知~~~");
    }

    @AfterThrowing("execution(* method.UserDAOImpl.*(..))")
    //异常通知
    public void afterThrowing(){
        System.out.println("异常通知~~~");
    }

    @AfterReturning("execution(* method.UserDAOImpl.*(..))")
    //返回通知
    public void afterReturning(){
        System.out.println("返回通知~~~");
    }

    @Around("execution(* method.UserDAOImpl.*(..))")
    //环绕通知
    public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        System.out.println("环绕之前~~~");
        proceedingJoinPoint.proceed();
        System.out.println("环绕之后~~~");
    }
}

开启自动扫描





    
    
    

测试

@Test
public void test6(){
    ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("bean2.xml");
    UserDAO userDao = context.getBean("userDao", UserDAO.class);
    userDao.add();
}

schema/context/spring-context.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd">




```

测试

@Test
public void test6(){
    ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("bean2.xml");
    UserDAO userDao = context.getBean("userDao", UserDAO.class);
    userDao.add();
}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/389851.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号