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. C/C++ 语言 Hello world

    #include <stdio.h> void main() { int x,i; ; scanf("%d",&x); if(x>y) printf(&q ...

  2. TDDL与Spring Boot集成Version报错——跟踪与解决

    先说背景:公司采用diamond+tddl,这套技术来做web管理.本人处于好奇率先体验了下spring-boot,于是就有了spring-boot+tddl的组合.但是jar包上线后,屡屡发现一条e ...

  3. SLAP(Speaker-Listener Label Propagation Algorithm)社区发现算法

    其中部分转载的社区发现SLPA算法文章 一.概念 社区(community)定义:同一社区内的节点与节点之间关系紧密,而社区与社区之间的关系稀疏. 设图G=G(V,E),所谓社区发现是指在图G中确定n ...

  4. .Net Core 发布WindowsServices

    项目代码文件夹 执行命令 dotnet publish -c Release -r win-x64

  5. tcp ip三次握手链接和四次挥手断开

      先来个整体的流程图       一 三次握手目的是为了建立连接... 1 核心的就是client端和service端,进行数据"报文" 交换 2 报文,目的是互相通知,确认链接 ...

  6. .NET源码Stack<T>和Queue<T>的实现

    这阵子在重温数据结构的时候,顺便用ILSpy看了一些.NET类库的实现,发现一些基本的数据结构的实现方法也是挺有意思的,所以这里拿出来跟大家分享一下.这篇文章讨论的是Stack和Queue的泛型实现. ...

  7. 再学Java 之 形参个数可变函数

    自Java 5后,Java允许定义形参个数可变的方法,从而允许运行过程中,为方法指定不确定个数的形参. 其定义方法的格式如下: void function_name ( type ... variab ...

  8. Spring Security构建Rest服务-0300-Restful API异常处理

    SpringBoot默认的错误处理机制: 一.测试需要的部分代码 (完整代码放在了github https://github.com/lhy1234/spring-security): UserCon ...

  9. JVM调优一些相关内容

    JVM调优工具 Jconsole,jProfile,VisualVM Jconsole : jdk自带,功能简单,但是可以在系统有一定负荷的情况下使用.对垃圾回收算法有很详细的跟踪.详细说明参考这里 ...

  10. webbench的安装

    1.下载webbench包: 2.下载完毕后,在linux中安装   root@jack-desktop:~/software# tar xvzf webbench-1.5.tar.gz   root ...