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

Spring-AOP

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

Spring-AOP

AOP概述

AOP 即 Aspect Oriented Program 面向切面编程,首先,在面向切面编程的思想里面,把功能分为核心业务功能和辅助功能。

  • 核心业务:比如登陆,增加数据,删除数据都叫核心业务
  • 辅助功能:比如性能统计,日志,事务管理等等

面向切面的编程(AOP)是一种编程范式,旨在通过允许横切关注点的分离,提高模块化。AOP提供切面来将跨越对象关注点模块化。
AOP要实现的是在我们写的代码的基础上进行一定的包装,如在方法执行前、或执行后、或是在执行中出现异常后这些地方进行拦截处理或叫做增强处理。

Aop的概念

  • Pointcut:切点。一个基于正则表达式的表达式。通常一个pointcut,会选取程序中的某些我们感兴趣的执行点,或者说是程序执行点的集合。
  • JoinPoint:通过pointcut选取出来的集合中的具体的一个执行点,我们就叫JoinPoint。
  • Advice:通知。在选取出来的JoinPoint上要执行的操作逻辑。5种类型:@Around、@Before、@After、@AfterRunning、@AfterThrowing
  • Aspect:切面。这个关注点可能会横切多个对象和模块,事务管理是横切关注点的很好的例子。由pointcut 和advice组成
  • Weaving:织入。把切面应用到目标对象来创建新的 advised 对象的过程。

AOP现有两个主要的流行框架,即SpringAOP和AspectJ。

SpringAOP和AspectJ区别:

  • 织入的时期不同:SpringAop采用的动态织入,而Aspectj是静态织入。SpringAop基于动态代理来实现,默认如果使用接口的,用JDK提供的动态代理实现,如果是方法则使用CGLIB实现;而Aspectj静态织入,通过修改代码来实现,编译前、后都可以进行织入,而且类加载后也可以织入。
  • 使用对象不同:SpringAOP需要依赖IOC容器来管理,并且只能作用于Spring容器中的SpringBean对象;而AspectJ可以在任何Java对象上应用通知。
  • 功能上:Spring AOP的功能不如AspectJ全面。
  • 性能上:Spring AOP是基于动态代理来实现的,在容器启动时需要生成代理实例,在方法调用上也会增加栈的深度,使得Spring AOP的性能不如AspectJ好。
SpringAop概述

在Spring-AOP思想里,辅助功能被定义为切面,核心业务功能和切面功能分别独立进行开发,然后把切面功能和核心业务功能 “编织” 在一起,这种可选择性的,低耦合的把切面和核心业务功能结合在一起的编程思想,就叫做切面编程(AOP)。

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

底层原理

AOP底层使用动态代理:

  • 有接口情况,使用JDK动态代理。
    • 1、创建方法拦截器类(JDK动态代理实现接口InvocationHandler.invoke()),实现相应接口方法。
    • 2、使用方法拦截器类,创建动态代理类(JDK动态代理使用Proxy.newProxyInstance(ClassLoader var0, Class[] var1, InvocationHandler var2))。
    • 3、使用动态代理类调用方法即可。
  • 没有接口情况,使用CGLIB动态代理。
    • 1、创建方法拦截器类(CGLIB动态代理实现接口MethodInterceptor.intercept()),实现相应接口方法。
    • 2、使用方法拦截器类,创建动态代理类(CGLIB动态代理使用Enhancer.setCallback(Callback callback))。
    • 3、使用动态代理类调用方法即可。

代码详见《Java-动态代理》

AspectJ概述

AspectJ全称是Eclipse AspectJ,AspectJ不是Spring的组成部分。
AspectJ是一个易用的功能强大的AOP框架,可以单独使用,也可以整合到其它框架中。一般把AspectJ和Spirng框架一起使用,Spring框架一般都是基于AspectJ实现AOP操作。

基于AspectJ实现AOP操作:

  • 基于xml配置文件实现
  • 基于注解方式实现(常用)
基于xml配置文件方式

引用AspectJ包

业务类 ProductService:

package springAop.AOP.service;

public class ProductService {

    public void doSomeService(){

        System.out.println("doSomeService");

    }
}

切面类 LoggerAspect:

package springAop.AOP.aspect;
import org.aspectj.lang.ProceedingJoinPoint;

public class LoggerAspect {
    
    public Object log(ProceedingJoinPoint joinPoint) throws Throwable {
        System.out.println("start log:" + joinPoint.getSignature().getName());
        
        Object object = joinPoint.proceed();
        
        System.out.println("end log:" + joinPoint.getSignature().getName());
        return object;
    }
}

配置文件applicationContext.xml:




    
    

    
    
    
    
    
        
        

        
        
            
        
    


  • aop:pointcut:指定切点-核心业务功能,指定被代理的类方法。
  • aop:aspect:指定切面-辅助功能,指定增强类方法以及切点。
  • aop:config:把切点与切面编织在一起。

execution(* com.how2java.service.ProductService.*(…)) :
* :返回任意类型
com.how2java.service.ProductService.* :包名以 com.how2java.service.ProductService 开头的类的任意方法
(…) :参数是任意数量和类型

TestSpring:

package springAop.AOP;

import configTest.AOP.service.ProductService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class TestSpring {

    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext(new String[] {"springAop/AOP/applicationContext.xml"});
        ProductService s = (ProductService) context.getBean("s");
        s.doSomeService();
    }
}

运行结果:

基于注解方式

注解业务类 ProductService:

package springAop.AOP.service;
import org.springframework.stereotype.Component;

@Component("s")
public class ProductService {
    public void doSomeService(){
        System.out.println("doSomeService");
    }
}

注解切面类 LoggerAspect:

package springAop.AOP.aspect;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class LoggerAspect {

    @Around(value = "execution(* springAop.AOP.service.ProductService.*(..))")
    public Object log(ProceedingJoinPoint joinPoint) throws Throwable {
        System.out.println("start log:" + joinPoint.getSignature().getName());
        Object object = joinPoint.proceed();
        System.out.println("end log:" + joinPoint.getSignature().getName());
        return object;
    }
}

@Aspect 注解表示这是一个切面
@Component 表示这是一个bean,由Spring进行管理
@Around(value = “execution(* com.how2java.service.ProductService.*(…))”) 表示对com.how2java.service.ProductService 这个类中的所有方法进行切面操作

配置文件applicationContext.xml:




    
    
    

运行结果:

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

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

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