AOP是什么?

面向切面编程,把那些与业务无关,却为业务模块所共同调用的逻辑封装成一个可重的模块,即切面
使用"横切"技术,AOP把软件系统分为两个部分:核心关注点和横切关注点。业务处理的主要流程是核心关注点,与之关系不大的部分是横切关注点

为什么使用AOP?

如果说面向对象编程是关注将需求功能划分为不同的并且相对独立,封装良好的类,并让它们有着属于自己的行为,依靠继承和多态等来定义彼此的关系的话;那么面向切面编程则是希望能够将通用需求功能从不相关的类当中分离出来,能够使得很多类共享一个行为,一旦发生变化,不必修改很多类,而只需要修改这个行为即可。

如下,有两个方法分别为mul和div,这两个方法的内容代码大多数是重复的,则我们可以抽离一个新的方法

package com.zzj.calculatar.service;
import org.springframework.stereotype.Service; @Service
public class CalculatorService implements ICalculatorService{ @Override
public int mul(int a, int b) {
System.out.println("The mul method begins.");
System.out.println("The mul method args:["+a+","+b+"]");
return a*b;
} @Override
public int div(int a, int b) {
System.out.println("The div method begins.");
System.out.println("The div method args:["+a+","+b+"]");
return a/b;
} }

新的方法如下:

@Service
public class CalculatorService implements ICalculatorService{ @Override
public int mul(int a, int b) {
t("mul", a, b);
return a*b;
} @Override
public int div(int a, int b) {
t("div", a, b);
return a/b;
} private void t(String methodName,int a,int b){
System.out.println("The"+methodName+"method begins.");
System.out.println("The"+methodName+"method args:["+a+","+b+"]");
} }

AOP的切面化就体现在此,具体的AOP实现方式有:注解和XML配置

package com.zzj.calculatar.service;
import org.springframework.stereotype.Service; @Service
public class CalculatorService implements ICalculatorService{ @Override
public int mul(int a, int b) {
return a*b;
} @Override
public int div(int a, int b) {
return a/b;
} }

注解方式实现AOP:

package com.zzj.aspect;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component; @Order(1)//切片执行顺序,默认为字典顺序
@Aspect
@Component
public class CalculatorAspect { //提取表达式
@Pointcut("execution(public int com.zzj.calculatar.service.CalculatorService.*(..))")
public void pointCut(){ } @Around(value="pointCut()")
public Object around(ProceedingJoinPoint joinPoint){
Object result = null;
Object target = joinPoint.getTarget();//目标对象
String methodName = joinPoint.getSignature().getName();
Object[] params = joinPoint.getArgs(); try{
try{
//前置增强
System.out.println(target.getClass().getName()+": The "+methodName+" method begins.");
System.out.println(target.getClass().getName()+": Parameters of the "+methodName+"method: ["+params[0]+","+params[1]+"]");
//执行目标对象内的方法
result = joinPoint.proceed();
}finally{
//后置增强
System.out.println(target.getClass().getName()+":The "+methodName+" method ends.");
}
//返回增强
System.out.println(target.getClass().getName()+":Result of the "+methodName+" method:"+result);
}catch (Throwable e) {
System.out.println(target.getClass().getName()+":Exception of the method "+methodName+": "+e);
}
return result;
} }
<!--XML代码-->
<context:component-scan base-package="com.zzj"></context:component-scan>
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>

XML配置方式实现AOP(不需要注解,将注解放在XML中):

package com.zzj.aspect;
import org.aspectj.lang.ProceedingJoinPoint;
public class CalculatorAspect {
public Object around(ProceedingJoinPoint joinPoint){
Object result = null;
Object target = joinPoint.getTarget();//目标对象
String methodName = joinPoint.getSignature().getName();
Object[] params = joinPoint.getArgs(); try{
try{
//前置增强
System.out.println(target.getClass().getName()+": The "+methodName+" method begins.");
System.out.println(target.getClass().getName()+": Parameters of the "+methodName+"method: ["+params[0]+","+params[1]+"]");
//执行目标对象内的方法
result = joinPoint.proceed();
}finally{
//后置增强
System.out.println(target.getClass().getName()+":The "+methodName+" method ends.");
}
//返回增强
System.out.println(target.getClass().getName()+":Result of the "+methodName+" method:"+result);
}catch (Throwable e) {
System.out.println(target.getClass().getName()+":Exception of the method "+methodName+": "+e);
}
return result;
}
}
<!--扫描-->
<context:component-scan base-package="com.zzj"></context:component-scan>
<!--获取aspect类-->
<bean id="calculatorAspect" class="com.zzj.aspect.CalculatorAspect"></bean> <aop:config>
<!--提取表达式-->
<aop:pointcut expression="execution(public int com.zzj.calculatar.service.CalculatorService.*(..))" id="pointCut"/>
<!--环绕增强-->
<aop:aspect ref="calculatorAspect" order="1">
<aop:around method="around" pointcut-ref="pointCut"/>
</aop:aspect>
</aop:config>

测试类:

package com.zzj.test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.zzj.calculatar.service.ICalculatorService; public class Test { public static void main(String[] args){ ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("application.xml");
ICalculatorService calculatorService = applicationContext.getBean(ICalculatorService.class);
System.out.println(calculatorService.getClass());//当有代理类时,获取的代理对象
System.out.println(calculatorService.div(1,1));
applicationContext.close(); } }

测试结果:

了解AOP以及实现方式的更多相关文章

  1. spring aop 使用注解方式总结

    spring aop的注解方式:和xml的配置方式略有区别,详细如下: 1.首先还是建立需要的切面类:切面类里面定义好切点配置,以及所有的需要实现的通知方法. /** * */ package com ...

  2. springboot aop 自定义注解方式实现完善日志记录(完整源码)

    版权声明:本文为博主原创文章,欢迎转载,转载请注明作者.原文超链接 一:功能简介 本文主要记录如何使用aop切面的方式来实现日志记录功能. 主要记录的信息有: 操作人,方法名,参数,运行时间,操作类型 ...

  3. springboot aop 自定义注解方式实现一套完善的日志记录(完整源码)

    https://www.cnblogs.com/wenjunwei/p/9639909.html https://blog.csdn.net/tyrant_800/article/details/78 ...

  4. Spring AOP 不同配置方式产生的冲突问题

    Spring AOP的原理是 JDK 动态代理和CGLIB字节码增强技术,前者需要被代理类实现相应接口,也只有接口中的方法可以被JDK动态代理技术所处理:后者实际上是生成一个子类,来覆盖被代理类,那么 ...

  5. 5.3 Spring5源码--Spring AOP使用接口方式实现

    Spring 提供了很多的实现AOP的方式:Spring 接口方式,schema配置方式和注解. 本文重点介绍Spring使用接口方式实现AOP. 使用接口方式实现AOP以了解为目的. 更好地理解动态 ...

  6. Spring学习总结(三)——Spring实现AOP的多种方式

    AOP(Aspect Oriented Programming)面向切面编程,通过预编译方式和运行期动态代理实现程序功能的横向多模块统一控制的一种技术.AOP是OOP的补充,是Spring框架中的一个 ...

  7. spring aop 使用xml方式的简单总结

    spring aop的 xml的配置方式的简单实现: 1.编写自己的切面类:配置各个通知类型 /** * */ package com.lilin.maven.service.aop; import ...

  8. ssm+redis整合(通过aop自定义注解方式)

    此方案借助aop自定义注解来创建redis缓存机制. 1.创建自定义注解类 package com.tp.soft.common.util; import java.lang.annotation.E ...

  9. 浅谈spring中AOP以及spring中AOP的注解方式

    AOP(Aspect Oriented Programming):AOP的专业术语是"面向切面编程" 什么是面向切面编程,我的理解就是:在不修改源代码的情况下增强功能.好了,下面在 ...

  10. spring AOP自定义注解方式实现日志管理

    今天继续实现AOP,到这里我个人认为是最灵活,可扩展的方式了,就拿日志管理来说,用Spring AOP 自定义注解形式实现日志管理.废话不多说,直接开始!!! 关于配置我还是的再说一遍. 在appli ...

随机推荐

  1. 【PAT甲级】1045 Favorite Color Stripe (30 分)(DP)

    题意: 输入一个正整数N(<=200),代表颜色总数,接下来输入一个正整数M(<=200),代表喜爱的颜色数量,接着输入M个正整数表示喜爱颜色的编号(同一颜色不会出现两次),接下来输入一个 ...

  2. 3、gitlab备份与恢复

    1.备份 #修改配置文件,启用备份 [root@localhost ~]# vim /etc/gitlab/gitlab.rb 377 gitlab_rails['backup_path'] = &q ...

  3. 利用DFS算出有多少个连通图

    以下面一个题目为例,[题目链接]: https://www.luogu.com.cn/problem/P4961 题目中涉及求出八联通图的个数,这里给出这步的代码: memset(vis, 0, si ...

  4. 「模板」可持久化 HFQ-Treap

    老师用的是静态数组的写法,开了很多数组- 其实个人更倾向于 struct 或者用 class 封装起来. 但是鉴于太难打 好吧,是我懒得打. 然后就借鉴了老师的模板,写出了属于自己的 压行 风格. 代 ...

  5. VUE学习笔记二

    package.json不可以写注释!!!!!!!!!!初始化:npm init -y 有时候使用 npm i node-sass -D 装不上,这时候,就必须使用  cnpm i node-sass ...

  6. spring demo

    参考: https://www.tutorialspoint.com/spring/spring_applicationcontext_container.htm

  7. Zenefits CodeSprint:Knight or Knave

    题意是一堆人,从1到n编号,每个人i说一句话,x.x是正数表示i说x君是个好人,x是负数表示i说x君是坏人.问这个群体中最多能有多少好人,把这种情况用字典序的方式输出(好人用A表示,坏人用B表示),希 ...

  8. jdk动态代理和cglib动态代理底层实现原理超详细解析(jdk动态代理篇)

    代理模式是一种很常见的模式,本文主要分析jdk动态代理的过程 1.举例 public class ProxyFactory implements InvocationHandler { private ...

  9. Codeforces1300C-Anu Has a Function

    定义一个函数f(x,y), f(x,y) = x|y - y,给你一个数列,a1,a2,,an问如何排列能使f(f(f(a1,a2),a3),````,an)答案最大,我们将f(x,y)变形,就是f( ...

  10. 嵊州普及Day6T3

    题意:n个点,对于q个询问,有t秒及一个矩形的范围.在此矩形内的数每秒加1,若等于c,则下一秒变为0. 思路:t可能很大,%c+1就可以了.然后一个一个加起来就可以了. 见代码: #include&l ...