6.spring:AOP(注解)
spring Aop
AOP面向切面编程,与OOP面向对象编程相辅相成
AOP中最基本的单元是切面
问题:
代码混乱:越来越多的业务需求(日志&验证)加入后,原有的业务方法急剧膨胀,每个方法在处理核心代码的同时还必须兼顾其他的多个关注点
代码分散,以日志为例,知识为了满足这一单一的需求,就不得不在代码块中里多次调用重复的日志代码,如果日志发生变化,必须修改所有的模块
简介:
AOP:面向切面编程,是一种新的方法,式传统OOP面向对象编程的补充
AOP主要编程对象是切面,而切面模块化横切的关注点
在应用AOP编程时,仍需要定义公共的功能,但可以明确定义的功能在哪,以什么方式应用,并且不必修改影响的类,这样横切关注点就被模块化到特殊的
对象(切面)里
AOP的好处:
->每个事物逻辑位于一个位置,代码不分散,便于维护
->业务模块化更简洁,只包含核心的业务代码
AOP术语:
切面(Aspect):横切关注点被模块化的特殊对象
通知(Advice):切换必须完成的工作
目标(Target):被通知的对象
代理(Proxy):向目标对象应用的通知之后创建的对象
连接点(Joinpoint):程序执行的特定位置
切点(pointcut):每个类都有若干个连接点,
AOP即使通过定位到特定的连接点

每次做方法的时候,都在执行之前和之后都有相关的打印操作!
AtithmeticCalculator.java
public interface AtithmeticCalculator {
int add(int i,int j);
int sub(int i,int j);
int mul(int i,int j);
int div(int i,int j);
}
AtithmeticCalculatorImp.java
接口中方法的实现。
@Component
public class AtithmeticCalculatorImp implements AtithmeticCalculator{
public int add(int i, int j) {
int res = i + j;
return res;
}
public int sub(int i, int j) {
int res = i - j;
return res;
}
public int mul(int i, int j) {
int res = i * j;
return res;
}
public int div(int i, int j) {
int res = i / j;
return res;
}
}
LoggionAspect.java
切面类
//把这个类升级称为一个切面:返给到IOC容器中---->在声明为一个注解
@Order(2)
@Aspect
@Component
public class LoggionAspect { @Before("execution(public * com.MrChengsc.AOP.AtithmeticCalculator.*(..))")
public void beforeMethod(JoinPoint joinPoint){
String methodName = joinPoint.getSignature().getName();
Object [] args = joinPoint.getArgs(); System.out.println("The method " + methodName + " begins with " + Arrays.asList(args));
} /**
* 在方法执行之后执行的代码. 无论该方法是否出现异常
*/
@After("execution(public * com.MrChengsc.AOP.AtithmeticCalculator.*(..))")
public void afterMethod(JoinPoint joinPoint){
String methodName = joinPoint.getSignature().getName();
System.out.println("The method " + methodName + " ends");
} /**
* 在方法法正常结束受执行的代码
* 返回通知是可以访问到方法的返回值的!
*/
@AfterReturning(value="execution(public * com.MrChengsc.AOP.AtithmeticCalculator.*(..))",
returning="result")
public void afterReturning(JoinPoint joinPoint, Object result){
String methodName = joinPoint.getSignature().getName();
System.out.println("The method " + methodName + " ends with " + result);
} /**
* 在目标方法出现异常时会执行的代码.
* 可以访问到异常对象; 且可以指定在出现特定异常时在执行通知代码
*/
@AfterThrowing(value="execution(public * com.MrChengsc.AOP.AtithmeticCalculator.*(..))",throwing="e")
public void afterThrowing(JoinPoint joinPoint, Exception e){
String methodName = joinPoint.getSignature().getName();
System.out.println("The method " + methodName + " occurs excetion:" + e);
} //环绕通知
//需要携带ProceedingJoinPoint这个类型的参数
//环绕通知类似动态代理的全类名:ProceedingJoinPoint可以绝对是否执行目标方法
//必须要有返回值,返回值即为目标方法的返回值
// @Around("execution(public * com.MrChengsc.AOP.AtithmeticCalculator.*(..))")
// public Object aroundMethod(ProceedingJoinPoint proceedingJoinPoint){
// System.out.println("@Around");
// //返回值
// Object result = null;
// //前置通知
// String methodName = proceedingJoinPoint.getSignature().getName();
// try {
// //前置通知
// System.out.println("The methodName:" + methodName + " _The args :" + Arrays.asList(proceedingJoinPoint.getArgs()));
// //执行目标方法
// result = proceedingJoinPoint.proceed();
// //后置通知
// System.out.println("End result:" + result);
// } catch (Throwable e) {
// //e.printStackTrace();
// //异常通知
// System.out.println("Exception:" + e);
// }
// //后置通知
// System.out.println("End...");
// //返回值
// return result;
// }
}
LoggionAspect2.java
切面类2//把这个类升级称为一个切面:返给到IOC容器中---->在声明为一个注解
@Order(1)
@Aspect
@Component
public class LoggionAspect2 { //定义一个方法用于切点表达式
//一般的该方法不需要填入其他的代码
@Pointcut("execution(public * com.MrChengsc.AOP.AtithmeticCalculator.*(..))")
public void declareJointPointExpression(){ }
@Before("declareJointPointExpression()")
public void beforeMethod1(JoinPoint joinPoint){
System.out.println("--->beforeMethod1");
String methodName = joinPoint.getSignature().getName();
Object [] args = joinPoint.getArgs();
System.out.println("The method " + methodName + " begins with " + Arrays.asList(args));
System.out.println("--->beforeMethod1");
} /**
* 在方法执行之后执行的代码. 无论该方法是否出现异常
*/
@After("declareJointPointExpression()")
public void afterMethod1(JoinPoint joinPoint){
String methodName = joinPoint.getSignature().getName();
System.out.println("The method " + methodName + " ends");
} /**
* 在方法法正常结束受执行的代码
* 返回通知是可以访问到方法的返回值的!
*/
@AfterReturning(value="declareJointPointExpression())",
returning="result")
public void afterReturning1(JoinPoint joinPoint, Object result){
String methodName = joinPoint.getSignature().getName();
System.out.println("The method " + methodName + " ends with " + result);
} /**
* 在目标方法出现异常时会执行的代码.
* 可以访问到异常对象; 且可以指定在出现特定异常时在执行通知代码
*/
@AfterThrowing(value="declareJointPointExpression()",throwing="e")
public void afterThrowing1(JoinPoint joinPoint, Exception e){
String methodName = joinPoint.getSignature().getName();
System.out.println("The method " + methodName + " occurs excetion:" + e);
} //环绕通知
//需要携带ProceedingJoinPoint这个类型的参数
//环绕通知类似动态代理的全类名:ProceedingJoinPoint可以绝对是否执行目标方法
//必须要有返回值,返回值即为目标方法的返回值
// @Around("execution(public * com.MrChengsc.AOP.AtithmeticCalculator.*(..))")
// public Object aroundMethod(ProceedingJoinPoint proceedingJoinPoint){
// System.out.println("@Around");
// //返回值
// Object result = null;
// //前置通知
// String methodName = proceedingJoinPoint.getSignature().getName();
// try {
// //前置通知
// System.out.println("The methodName:" + methodName + " _The args :" + Arrays.asList(proceedingJoinPoint.getArgs()));
// //执行目标方法
// result = proceedingJoinPoint.proceed();
// //后置通知
// System.out.println("End result:" + result);
// } catch (Throwable e) {
// //e.printStackTrace();
// //异常通知
// System.out.println("Exception:" + e);
// }
// //后置通知
// System.out.println("End...");
// //返回值
// return result;
// }
}
applicationContext.xml
<!-- 配置自动扫描的包 -->
<context:component-scan base-package="com.MrChengsc.AOP"></context:component-scan>
<!-- 前置通知,使切面里的注解起作用 -->
<!-- 使AspectJ注解起作用:自动为匹配的类生成代理效果 -->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
main:
public static void main(String[] args) {
// AtithmeticCalculator atithmeticCalculator = null;
// atithmeticCalculator = new AtithmeticCalculatorImp();
//
// atithmeticCalculator.add(1, 3);
// System.out.println("---");
// atithmeticCalculator.sub(3, 1);
// System.out.println("---");
// atithmeticCalculator.mul(1, 3);
// System.out.println("---");
// atithmeticCalculator.div(10, 2);
// System.out.println("---");
ApplicationContext ctx = new
ClassPathXmlApplicationContext("AOPContext.xml");
//强制的类型使用接口的类型
AtithmeticCalculator atithmeticCalculator = (AtithmeticCalculator) ctx.getBean(AtithmeticCalculator.class);
int res = atithmeticCalculator.add(, );
System.out.println("res:" + res);
System.out.println("-----");
// int res1 = atithmeticCalculator.mul(2, 3);
// System.out.println("res1:" + res1);
//异常代码的测试
// int res2 = atithmeticCalculator.div(10, 0);
// System.out.println("res2:" + res2);
}
执行的顺序以及结果:
--->beforeMethod1
The method add begins with [, ]
--->beforeMethod1
The method add begins with [, ]
The method add ends
The method add ends with
The method add ends
The method add ends with
res:
-----
注:
1.首先需要在xml文件中进行包的扫描<context:component-scan>
2.使切面的注解起作用:<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
3.使用@Component在要进行处理的类、切面类上
4.使用@Aspect进行标注切面类
5.使用 @Before()在方法上作为前置通知
6. 使用@After()在方法上作为后置通知,无论该方法是否出现异常
7. 使用@AfterReturning(value="",returning=""),正常结束后那倒返回值
8.使用 @AfterThrowing(value="",throwing=""),在执行发生异常时,那倒异常信息
9.使用@Around()作为环绕通知,使用比较少
10.使用@Pointcut()放在空方法上,作为切点表达式,引用切点直接使用方法名
11.使用@Order(1)放在类上指定切面的优先级,数值越小优先级越高
12.@After("execution(public * com.MrChengsc.AOP.AtithmeticCalculator.*(..))")
*:代表所有,任意的
..:代表任意的形参
AOP的实现都有这个符号!

6.spring:AOP(注解)的更多相关文章
- Spring AOP注解为什么失效?90%Java程序员不知道
使用Spring Aop注解的时候,如@Transactional, @Cacheable等注解一般需要在类方法第一个入口的地方加,不然不会生效. 如下面几种场景 1.Controller直接调用Se ...
- Spring aop注解失效
问题 在spring 中使用 @Transactional . @Cacheable 或 自定义 AOP 注解时,对象内部方法中调用该对象的其他使用aop机制的方法会失效. @Transactiona ...
- spring aop注解方式与xml方式配置
注解方式 applicationContext.xml 加入下面配置 <!--Spring Aop 启用自动代理注解 --> <aop:aspectj-autoproxy proxy ...
- spring aop注解配置
spring aop是面向切面编程,使用了动态代理的技术,这样可以使业务逻辑的代码不掺入其他乱七八糟的代码 可以在切面上实现合法性校验.权限检验.日志记录... spring aop 用的多的有两种配 ...
- Spring AOP 注解和xml实现 --转载
AOP是OOP的延续,是Aspect Oriented Programming的缩写,意思是面向切面编程.可以通过预编译方式和运行期动态代理实现在不修改源代码的情况下给程序动态统一添加功能的一种技术. ...
- spring Aop 注解
个人理解: spring Aop 是什么:面向切面编程,类似于自定义拦截操作,支持拦截之前操作@Before,拦截之后操作@After,拦截环绕操作@Around. 什么情况下使用spring Aop ...
- Spring aop 注解参数说明
在spring AOP中,需要使用AspectJ的切点表达式语言来定义切点. 关于Spring AOP的AspectJ切点,最重要的一点是Spring仅支持AspectJ切点指示器(pointcut ...
- 【学习笔记】Spring AOP注解使用总结
Spring AOP基本概念 是一种动态编译期增强性AOP的实现 与IOC进行整合,不是全面的切面框架 与动态代理相辅相成 有两种实现:基于jdk动态代理.cglib Spring AOP与Aspec ...
- 转:Spring AOP 注解方式实现的一些“坑”
使用过Spring AOP的注解方式实现,也入过不少坑,现在做一下记录,希望有同样需求的朋友可以少走弯路 使用之前还是先过一下官方文档吧,至少可以少走弯路,不用担心英文读不懂,其实只看代码例子就能理解 ...
随机推荐
- 有意思的MySQL之最
写在前面 在平时工作中特别是架构设计阶段,咨询量最多的也就是MySQL之最了,在不经意间发现原来MySQL手册里面已经列举了,顺手拿来翻译下,如果有翻译错误或者不当的地方,欢迎批评指正. 最大和最小 ...
- BDD框架之Cucumber研究
BDD框架之Cucumber研究 引用链接:http://kongqingyun123.blog.163.com/blog/static/6377283520134158437813/ Cucumbe ...
- 查找CPU使用率过高的线程
1.在编写程序中有时候设置不恰当,休眠时间不够,一般情况下4核的电脑CPU使用率一直大于23%,8核的大于13%就有可能是这种情况 解决方法: 在VS查看并行线程利用CPU使用工具ProcessExp ...
- C#基础知识-使用XML完成一个小程序(十一)
上一篇中讲到XML基本的结构,还有增删改查的方法,这一篇中我们就来利用XML来完成一个简单的订单系统,主要是实现一个简单学生名单的增删改查,如果想要应用到实际的环境中建议考虑数据量的问题,如果数据量大 ...
- CXF - 拦截器获取调用方法
没想到要弄这么一个东西. 起初只是想用interceptor记录一下webservice调用日志,后来却被要求在页面展示. 展示容易,但只是展示webservice的地址无法让用户从中明白什么. 那么 ...
- wget http://pypi.python.org/packages/source/s/setuptools/setuptools-2.0.tar.gz 下载时报错 ssl is required 解决办法
方法一:使用浏览器下载.在浏览器中输入 http://pypi.python.org/packages/source/s/setuptools/setuptools-2.0.tar.gz 方法二:将h ...
- Effective C++ .09 不在构造和析构过程中调用virtual函数
看过C++对象模型的话就可以知道,在构造基类时,完整的vtable没有建立起来(表项没有被相应的子类函数替换),因而无法调用到子类的函数(即构造函数中的virtual函数是本类里的方法,不是virtu ...
- express的proxy实现前后端分离
var express = require('express') var proxy = require('http-proxy-middleware') var app = express() ap ...
- css3 animation运用
animation:mymove 5s infinite; @keyframes mymove { from {left:0px;} to {left:200px;} } @-webkit-keyfr ...
- 关于ES7里面的async和await
async / await是ES7的重要特性之一,也是目前社区里公认的优秀异步解决方案.目前,async / await这个特性已经是stage 3的建议,可以看看TC39的进度,本篇文章将分享asy ...