AOP理解

  Aspect Oriented Program面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。

  但是,这种说法有些片面,因为在软件工程中,AOP的价值体现的并不是代码方面,更多的是为了项目的模块化,而不仅仅是为了减少重复代码。

  AOP是一种编程思想,为的是让模块本身变得更加内聚,让开发者更多的关注到业务逻辑的开发。

  在面向切面编程里,把功能分为核心业务功能和周边业务功能:

    核心业务,比如登陆,日常增,删数据

    周边功能,统计,日志,事务管理。在Spring的面向切面编程AOP思想里,即被定义为切面

在面向切面的思想里,核心业务功能和切面功能单独开发,然后把两个整合在一起,就是AOP。

AOP实现原理

  AOP底层将采用代理机制进行实现

  接口+实现类:spring采用jdk的动态代理Proxy

  实现类:spring采用cglib字节码增强

  Spring默认使用JDK动态代理,在需要代理类而不是接口的时候,Spring会自动切换为使用cglib代理,不过现在的项目都是面向接口开发,所以JDK动态代理相对来说用的还是多一些。

Spring AOP引入了几个概念

  切面(Aspect),它是跨不同Java类层面的横切性逻辑。可以通过XML文件中配置的普通类,也可以在类代码中使用“@Aspect” 注解去声明,在运行时,Spring会创建类似Advisor来代替它。其内部包括切入和通知。通俗的讲,是要告诉Spring什么时候,什么地方,做什么。

  连接点(JoinPoint),程序运行过程中明确的点,一般是方法的调用。

  通知(Advice),AOP在特定的切入点上知性的增强处理,告诉Spring什么时候,做什么。一般会讲Advice模拟成一个拦截起,并且在JoinPoint上维护多个Advice,进行层拦截。比如Http鉴权的实现。

  切入点(PointCut),就是带有通知的连接点。要切入的对象,可以是类,或方法。在Spring中,所有的方法都可以认为是JoinPoint,都可以添加Advice,但是这并不是所有都是我们真正想要的,而PointCut提供了一组规则,来匹配JointPoint,给满足规则的JointPoint添加Advice。其主要用来修饰JointPoint。

Advice的五种通知类型

  前置通知(@Before):在目标方法被调用之前调用通知功能

  后置通知(@After):在目标方法完成之后调用通知,此时不会关心方法的输出

  返回通知(@After-Returning):在目标方法成功执行之后调用通知

  异常通知(@AfterThrowing):在目标方法抛出异常后调用通知

  环绕通知(@Around):通知包裹了被通知的方法,在被通知的方法调用之前和之后执行自定义的行为

做个小demo

1. 在src下新建bean包,新建Operator类

package bean;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component; @Component
@Aspect
public class Operator { // @Pointcut("execution(* service.UserService.add()")
// public void service() {
// } @Pointcut("execution(* service.UserService.add())")
public void IService(){ } @Before("IService()")
public void doBefore(JoinPoint joinPoint) {
System.out.println(" before Advice");
} @After("IService()")
public void doAfter(JoinPoint joinPoint) {
System.out.println(" after Advice");
} @AfterReturning(pointcut = "IService()", returning = "returnVal")
public void afterReturn(JoinPoint joinPoint, Object returnVal) {
System.out.println(" after Advice return " + returnVal);
} @AfterThrowing(pointcut = "IService()", throwing = "errors")
public void afterThrowing(JoinPoint joinPoint, Throwable errors) {
System.out.println("afterThrowing Advice ..." + errors);
System.out.println(" afterThrowing..");
} @Around("IService()")
public void doAround(ProceedingJoinPoint proceedingJoinPoint) {
System.out.println(" around Advice before"); try {
proceedingJoinPoint.proceed();
} catch (Throwable throwable) {
throwable.printStackTrace();
}
System.out.println(" around Advice before");
}
}

2. src下新建service包,新建UserService类

package service;

import org.springframework.stereotype.Service;

@Service
public class UserService {
public void add() {
System.out.println("UserService add.");
} public boolean delete() {
System.out.println("UserService delete ..");
return true;
} public void edit() {
System.out.println("UserService edit ");
}
}

3.配置XML文件,在src下新建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:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <bean name="userService" class="service.UserService"></bean>
<bean name="operator" class="bean.Operator"></bean> <aop:config>
<aop:aspect id="operatorAspect" ref="operator">
<aop:pointcut id="servicePointCut" expression="execution(* service.UserService.add())"></aop:pointcut>
<aop:before pointcut-ref="servicePointCut" method="doBefore"></aop:before>
<aop:after pointcut-ref="servicePointCut" method="doAfter"></aop:after>
<aop:around pointcut-ref="servicePointCut" method="doAround"></aop:around>
<aop:after-returning pointcut-ref="servicePointCut" method="afterReturn"
returning="returnVal"></aop:after-returning>
<aop:after-throwing pointcut-ref="servicePointCut" method="afterThrowing"
throwing="errors"></aop:after-throwing>
</aop:aspect>
</aop:config>
</beans>

4.测试AOP,在src下新建test.java

import bean.User;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import service.UserService; public class test {
@Test
public void demo() {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
UserService userService = (UserService) context.getBean("userService", UserService.class);
userService.add();
} }

5.运行结果

Spring学习手札(二)面向切面编程AOP的更多相关文章

  1. Spring学习笔记:面向切面编程AOP(Aspect Oriented Programming)

    一.面向切面编程AOP 目标:让我们可以“专心做事”,避免繁杂重复的功能编码 原理:将复杂的需求分解出不同方面,将公共功能集中解决 *****所谓面向切面编程,是一种通过预编译方式和运行期动态代理实现 ...

  2. spring学习总结二-----面向切面编程(AOP)思想

    上一篇spring博客简总结了spring控制反转和依赖注入的相关思想知识点,这篇博文对spring的面向切的编程思想进行简单的梳理和总结. 一.面向切面的思想 与面向对象的纵向关系概念不同,面向切面 ...

  3. Spring学习总结之面向切面(AOP)

    AOP术语 通知(advice):定义切面是什么以及什么时候使用 连接点(join point):应用在执行过程中能够插入切面的点 切点(pointcut):切点的定义会匹配通知所要织入的一个或多个连 ...

  4. Spring框架学习笔记(2)——面向切面编程AOP

    介绍 概念 面向切面编程AOP与面向对象编程OOP有所不同,AOP不是对OOP的替换,而是对OOP的一种补充,AOP增强了OOP. 假设我们有几个业务代码,都调用了某个方法,按照OOP的思想,我们就会 ...

  5. Spring之控制反转——IoC、面向切面编程——AOP

      控制反转——IoC 提出IoC的目的 为了解决对象之间的耦合度过高的问题,提出了IoC理论,用来实现对象之间的解耦. 什么是IoC IoC是Inversion of Control的缩写,译为控制 ...

  6. Spring框架系列(4) - 深入浅出Spring核心之面向切面编程(AOP)

    在Spring基础 - Spring简单例子引入Spring的核心中向你展示了AOP的基础含义,同时以此发散了一些AOP相关知识点; 本节将在此基础上进一步解读AOP的含义以及AOP的使用方式.@pd ...

  7. 04 Spring:01.Spring框架简介&&02.程序间耦合&&03.Spring的 IOC 和 DI&&08.面向切面编程 AOP&&10.Spring中事务控制

    spring共四天 第一天:spring框架的概述以及spring中基于XML的IOC配置 第二天:spring中基于注解的IOC和ioc的案例 第三天:spring中的aop和基于XML以及注解的A ...

  8. 【串线篇】面向切面编程AOP

    面向切面编程AOP 描述:将某段代码“动态”的切入到“指定方法”的“指定位置”进行运行的一种编程方式 (其底层就是Java的动态代理)spring对其做了简化书写 场景: 1).AOP加日志保存到数据 ...

  9. [译]如何在ASP.NET Core中实现面向切面编程(AOP)

    原文地址:ASPECT ORIENTED PROGRAMMING USING PROXIES IN ASP.NET CORE 原文作者:ZANID HAYTAM 译文地址:如何在ASP.NET Cor ...

随机推荐

  1. window / Linux 下 Golang 开发环境的配置

    一直专注于使用python语言进行程序开发,但是却又一直被它的性能问题所困扰,直到遇到了天生支持高并发的Golang,这似乎也成了学习go语言最理所当然的理由.下面介绍下Go语言开发环境搭建的步骤: ...

  2. AVL树的实现——c++

    一.概念 AVL树是根据它的发明者G.M. Adelson-Velsky和E.M. Landis命名的.它是最先发明的自平衡二叉查找树,也被称为高度平衡树.相比于"二叉查找树",它 ...

  3. 错误处理Cannot load JDBC driver class 'oracle.jdbc.drive

    org.apache.tomcat.dbcp.dbcp.SQLNestedException: Cannot create PoolableConnec是由于<Resource name=&qu ...

  4. leetcode-162-寻找峰值

    题目描述: 峰值元素是指其值大于左右相邻值的元素. 给定一个输入数组 nums,其中 nums[i] ≠ nums[i+1],找到峰值元素并返回其索引. 数组可能包含多个峰值,在这种情况下,返回任何一 ...

  5. appt查看应用包报名和入口页面

    appt在哪里? aapt不需要另外安装喔,有安装了adt的,可以直接在adt../sdk/build-tools/android-xx/下,找到aapt,详细路径如图 怎么使用aapt.bat? 直 ...

  6. 解决Mysql Workbench的Error Code: 1175错误 无法删除数据

    使用workbench,如果你要批量更新或删除数据,一般会报“ Error Code: 1175 You are using safe update mode and you tried to upd ...

  7. java文件上传-原始的Servlet方式

    前言: 干了这几个项目,也做过几次文件上传下载,要么是copy项目以前的代码,要么是百度的,虽然做出来了,但学习一下原理弄透彻还是很有必要的.刚出去转了一圈看周围有没有租房的,在北京出去找房子是心里感 ...

  8. Failed to instantiate [java.util.List]: Specified class is an interface

    错误信息提示: Failed to instantiate [java.util.List]: Specified class is an interface; 错误信息意思:参数错误,参数封装出了问 ...

  9. Win7下无法提交MapReduce Job到集群环境(转)

    一. 对hadoop eclipse plugin认识不足 http://zy19982004.iteye.com/blog/2024467曾经说到我最hadoop eclipse plugin作用的 ...

  10. QMYSQL driver not loaded

    QT5 连接 QMYSQL 数据库时出现错误:QMYSQL driver not loaded. 解决方法如图:(图中使用指令:ldd libqsqlmysql.so) 从结果图显示中:libmysq ...