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

Spring-AOP

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

Spring-AOP

1. 面向切面 1.1 什么是面向切面

面向切面(AOP,Aspect Orient Programming):通过预编译方式和运行期间动态代理实现程序功能的统一维护的一种技术。AOP 为 Spring IoC 提供一个非常强大的中间件解决方案,是函数式编程的一种衍生泛型。

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

AOP 在 Spring 框架中用于:

  • 提供声明式企业服务。最重要的此类服务是 声明式事务管理。
  • 让用户实现自定义切面,用 AOP 补充他们对 OOP 的使用。

OOP:面对对象编程

面向方面编程 (AOP) 通过提供另一种思考程序结构的方式来补充面向对象编程 (OOP)。

区别:OOP 中模块化的关键单位是类,而 AOP 中模块化的单位是方面。

1.2 AOP名词 1.2.1 名词术语
名词说明备注
横切关注点跨越应用程序中多个模块的方法或功能方法拦截处
切面(Aspect)是一个关注点的模块化,一个切面能包含多个增强方法如事务处理、日志处理
连接点(Joint point)程序执行过程中的一个点通知开始执行的地方
切入点(Point Cut)对连接点进行拦截的条件定义匹配连接点的谓词
引介(Introduction)代表类型声明额外的方法或字段添加新的方法
通知(Advice)连接点后要执行的代码完成功能的实现
目标(Target)被一个或多个切面所通知的对象被通知(代理)的对象
织入(Weave)将增强方法添加到目标的具体连接点上的过程AOP有三种织入方式
1.2.2 通知类型
通知类型说明实现
前置通知(Before Advice)在连接点之前执行的通知
后置通知(After Advice)在连接点结束的时候执行的通知
返回后通知(After Return Advice)在连接点正常完成后执行的通知>
环绕通知(Around Advice)包围一个连接点的通知
异常通知(After Throwing Advice)在方法异常退出时执行的通知
1.3 Spring-AOP

Spring AOP 是用纯 Java 实现的。不需要特殊的编译过程。Spring AOP 不需要控制类加载器层次结构,因此适用于 servlet 容器或应用程序服务器。

Spring 中的 AOP 是通过动态代理实现的。

Spring AOP 目前仅支持方法执行连接点。

1.4 AOP代理

Spring AOP 默认为 AOP 代理使用标准的 JDK 动态代理。Spring AOP 也可以使用 CGLIB 代理。

默认情况下,如果业务对象未实现接口,则使用 CGLIB。

2. AOP的Spring实现

需要导入aspectjweaver依赖:


   org.aspectj
   aspectjweaver
   1.9.4

2.1 基于 Spring API 实现

利用之前在代理模式中用到的增删查改的业务,同样完成添加日志的功能。

基本业务:

public interface UserService {
    public void add();
    public void delete();
    public void update();
    public void query();
}
public class UserServiceImpl implements UserService {
    @Override
    public void add() {
        System.out.println("添加一个用户");
    }

    @Override
    public void delete() {
        System.out.println("删除一个用户");
    }

    @Override
    public void update() {
        System.out.println("更改一个用户");
    }

    @Override
    public void query() {
        System.out.println("查询用户");
    }
}
2.1.1 需要实现的接口

需要实现的接口有:

  • MethodBeforeAdvice:在调用方法之前调用的通知。这样的通知不能阻止方法调用继续进行,除非它们抛出Throwable。
  • AfterReturningAdvice:返回通知仅在正常方法返回时调用,而不是在抛出异常时调用。这样的建议可以看到返回值,但不能更改它。
public interface MethodBeforeAdvice extends BeforeAdvice {

   
   void before(Method method, Object[] args, @Nullable Object target) throws Throwable;

}
public interface AfterReturningAdvice extends AfterAdvice {

   
   void afterReturning(@Nullable Object returnValue, Method method, Object[] args, @Nullable Object target) throws Throwable;

}
2.1.2 实现接口

我们需要两个增强类,一个前置增强、一个后置增强。

public class Before_log implements MethodBeforeAdvice {
    @Override
    public void before(Method method, Object[] args, Object target) throws Throwable {
        System.out.println("执行 " + target.getClass().getName() + " 的 " + method.getName() + " 方法");
    }
}
public class After_log implements AfterReturningAdvice {
    @Override
    public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
        System.out.println("该方法的返回值为:" + returnValue);
    }
}
2.1.3 applicationContext

在xml文件中注册bean,并配置aop。(需要aop约束)




    
    
    

    
    
         
        
        
        
        
        
    

2.1.4 测试
public class MyTest {
    @Test
    public void TestUserService(){
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("ApplicationContext.xml");
        UserService userService = applicationContext.getBean("UserService", UserService.class);
        userService.add();
    }
}


2.2 自定义 AOP 实现 2.2.1 定义代理类

代理中需要提供两个增强类,一个前置增强、一个后置增强。

public class DiyPoint {
    public void After(){
        System.out.println("===========开始前==============");
    }
    public void Before(){
        System.out.println("===========开始后==============");
    }
}
2.2.2 applicationContext




    
    
        
        
        
        
        
    

2.2.3 测试

测试类不变!

 
2.3 基于注解 AOP 实现 
2.3.1 注解类 
@Configuration   // Java配置类
@Aspect  // 标识一个切面
public class AnnotationPoint {

    @After("execution(* com.service.UserServiceImpl.*(..))")
    public void After(){
        System.out.println("===========开始前==============");
    }
    @Before("execution(* com.service.UserServiceImpl.*(..))")
    public void Before(){
        System.out.println("===========开始后==============");
    }
}
2.3.2 applicationContext





2.3.3 测试

测试类不变!

 
3. 写在最后 

通过上面三种实现AOP的例子,我们可以看到AOP是基于动态代理实现的。在实际应用中,我们应当选择前两种,而酌情(小项目)选择第三种。

 


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

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

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