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

关于Spring的学习总结(三)

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

关于Spring的学习总结(三)

文章目录
  • 一、理解AOP
    • (一)什么是AOP
    • (二)AOP中的相关概念
  • 二、使用Spring实现AOP
    • (一)基于XML的声明式
    • (二)基于注解的声明式


一、理解AOP

AOP(Aspect Oriented Programming),面向切面思想,是Spring的三大核心思想之一(两外两个:IOC-控制反转、DI-依赖注入)。

(一)什么是AOP

用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。

下面有一些图片辅助理解:



(二)AOP中的相关概念
  • Aspect(切面): Aspect 声明类似于 Java 中的类声明,在 Aspect 中会包含着一些 Pointcut 以及相应的 Advice。
  • Joint point(连接点):表示在程序中明确定义的点,典型的包括方法调用,对类成员的访问以及异常处理程序块的执行等等,它自身还可以嵌套其它 joint point。
  • Pointcut(切点):表示一组 joint point,这些 joint point 或是通过逻辑关系组合起来,或是通过通配、正则表达式等方式集中起来,它定义了相应的 Advice 将要发生的地方。
  • Advice(增强):Advice 定义了在 Pointcut 里面定义的程序点具体要做的操作,它通过 before、after 和 around 来区别是在每个 joint point 之前、之后还是代替执行的代码。
  • Target(目标对象):织入 Advice 的目标对象。
  • Weaving(织入):将 Aspect 和其他对象连接起来, 并创建 Adviced object 的过程。
二、使用Spring实现AOP

导入依赖


		org.aspectj
  	aspectjweaver
  	1.9.4

使用Aspectj实现AOP有俩种方式:基于XML的声明式和基于注解的声明式

(一)基于XML的声明式

基于XML的声明式是指通过XML文件来定义切面、切入点以及通知,所有切面、切入点和通知都必须定义在元素中。

Spring配置文件中的元素下可以包含多个元素,一个元素中有可以包含属性和子元素,子元素包括、、,配置的时候也必须按照此顺序来。

常用配置代码如下:




       
       
       
              
              
                     
                     
              
                     
                     
                     
                     
                     
                     
                     
                     
                     
                     
              
       

  1. UserDao.java
public interface UserDao {
    public void addUser();
    public void deleteUser();
}
  1. UserDaoImpl.java
public class UserDaoImpl implements UserDao{

    @Override
    public void addUser() {
        System.out.println("添加新用户");
    }

    @Override
    public void deleteUser() {
        System.out.println("删除用户");
    }
}
  1. MyAspectj.java
public class MyAspectj {
    //前置通知
    public void myBefore(JoinPoint joinPoint){
        System.out.println("前置通知:模拟执行权限检查");
        System.out.println("目标类"+joinPoint.getTarget());
        System.out.println("被植入的强处理的目标方法为"+joinPoint.getSignature().getName());
    }
    //后置通知
    public void myAfterReturning(JoinPoint joinPoint){
        System.out.println("后置通知:模拟记录日志");
        System.out.println("被植入强处理的目标方法为"+joinPoint.getSignature().getName());
    }
    
    public Object myAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable{
        //开始
        System.out.println("环绕开始:执行目标方法之前,模拟开启事务");
        //执行当前目标方法
        Object obj = proceedingJoinPoint.proceed();
        //结束
        System.out.println("环绕结束:执行目标方法之后,模拟关闭事务");
        return obj;
    }
    //异常通知
    public void myAfterThrowing(JoinPoint joinPoint,Throwable e){
        System.out.println("异常通知:出现错误"+e.getMessage());
    }
    //最终通知
    public void myAfter(){
        System.out.println("最终通知:模拟方法结束后释放资源");
    }
}
  1. applicationContext.xml



    
    
    
    
    
        
        
            
            
            
            
            
            
            
            
            
            
            
            
            
        
    

  1. TestXMLAspectj.java
public class TestXMLAspectj {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        UserDao userDao = (UserDao) context.getBean("userDao");
        userDao.deleteUser();
    }
}
(二)基于注解的声明式
  1. 在UserDaoImpl类上添加@Repository("userDao")
  2. MyAspect.java
@Aspect
@Component
public class MyAspectj {
    //定义切入点表达式
    @Pointcut("execution(* com.weirdo.dao.MyAspectj.*.*(..))")
    //使用一个返回值为void 方法体为空的方法来命名切入点
    public void myPointCut(){}
    //前置通知
    @Before("myPointCut()")
    public void myBefore(JoinPoint joinPoint){
        System.out.println("前置通知:模拟执行权限检查");
        System.out.println("目标类"+joinPoint.getTarget());
        System.out.println("被植入的强处理的目标方法为"+joinPoint.getSignature().getName());
    }
    //后置通知
    @AfterReturning(value = "myPointCut()")
    public void myAfterReturning(JoinPoint joinPoint){
        System.out.println("后置通知:模拟记录日志");
        System.out.println("被植入强处理的目标方法为"+joinPoint.getSignature().getName());
    }
    
    @Around("myPointCut()")
    public Object myAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable{
        //开始
        System.out.println("环绕开始:执行目标方法之前,模拟开启事务");
        //执行当前目标方法
        Object obj = proceedingJoinPoint.proceed();
        //结束
        System.out.println("环绕结束:执行目标方法之后,模拟关闭事务");
        return obj;
    }
    //异常通知
    @AfterThrowing(value = "myPointCut()",throwing = "e")
    public void myAfterThrowing(JoinPoint joinPoint,Throwable e){
        System.out.println("异常通知:出现错误"+e.getMessage());
    }
    //最终通知
    @After("myPointCut()")
    public void myAfter(){
        System.out.println("最终通知:模拟方法结束后释放资源");
    }
}

  1. applicationContext.xml



       
       
       
       

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

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

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