34.Spring-Aop.md
http://blog.csdn.net/bigtree_3721/article/details/50759843
目录
目录
1.概念
1.1概念
AOP是Spring提供的关键特性之一。AOP即面向切面编程,是OOP编程的有效补充。使用AOP技术,可以将一些系统性相关的编程工作,独立提取出来,独立实现,然后通过切面切入进系统。从而避免了在业务逻辑的代码中混入很多的系统相关的逻辑——比如权限管理,事物管理,日志记录等等。这些系统性的编程工作都可以独立编码实现,然后通过AOP技术切入进系统即可。从而达到了 将不同的关注点分离出来 的效果。
AOP相关的概念
Aspect :切面,切入系统的一个切面。比如事务管理是一个切面,权限管理也是一个切面;
Join point :连接点,也就是可以进行横向切入的位置;
Advice :通知,切面在某个连接点执行的操作(分为: Before advice , After returning advice , After throwing advice , After (finally) advice , Around advice );
Pointcut :切点,符合切点表达式的连接点,也就是真正被切入的地方;
1.2 AOP 的实现原理
AOP分为静态AOP和动态AOP。静态AOP是指AspectJ实现的AOP,他是将切面代码直接编译到Java类文件中。动态AOP是指将切面代码进行动态织入实现的AOP。Spring的AOP为动态AOP,实现的技术为: JDK提供的动态代理技术 和 CGLIB(动态字节码增强技术) 。尽管实现技术不一样,但 都是基于代理模式 , 都是生成一个代理对象 。
2.开发步骤
2.1注解方式实现AOP
2.1.1不同类型注解的作用
2.1.1.1拦截表达式
使用注解,必须使用拦截表达式。告诉aop中哪些类或者哪些函数是需要被拦截的,也就是切入点。表达式的范例如下(一定不要写错,例如空格和括号一类)
@Pointcut(value = "execution(* per.liyue.aop.annotion..(..))")
其中,execution是固定写法括号中的第一个和其后的一个空格一定不能写错。后面是包和对应的类。如果拦截整个类所有方法那么用匹配,如果指定方法那么要写明。拦截的方法如果没有参数可以空括号表示,如果有可以用..来表示有参数。
2.1.1.2注解类型
在各种类型的注解中指定切入点
- @Around 环绕通知,环绕在切入点的前后
这个注解相对其他不一样,在函数中执行实际的方法,在方法前后完成业务切入 - @Before 前置通知,在切入点前执行
- @After 后置通知,在切入点后执行,无论是否有异常都执行
- @AfterReturning 返回通知,在执行切入点后执行,如果有异常则不执行
- @AfterThrowing 遇到异常时候执行
2.1.2各种类型注解顺序图
2.1.3实例
2.1.3.1引入相关jar包
这几个jar包是必须有,而且要注意版本匹配,如果aspectj的两个相关jar包版本过低,最终运行时候会报各种错误。
例如:error at ::0 can't find referenced pointcut.
2.1.3.2需要抽离的业务类
注意注解@Component是不能少的,因为要注入IOC容器
package per.liyue.aop.annotion;
/**
* Created by liyue on 2016/11/17.
*/
//普通的接口类
public interface IUserDao
{
public void save();
}
package per.liyue.aop.annotion;
import org.springframework.stereotype.Component;
/**
* Created by liyue on 2016/11/17.
*/
@Component//将类对象注入IOC容器
public class UserDao implements IUserDao
{
@Override
public void save()
{
System.out.println("保存数据!");
}
}
2.1.3.3切面类
package per.liyue.aop.annotion;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
/**
* Created by liyue on 2016/11/17.
*/
@Component //指定当前类是组件,加入IOC容器
@Aspect //指定当前类是切入面
public class Aop
{
/*
* 指定切入点
* */
//注解表达式:配置需要拦截的方法,用*表示所有,下面的表达式表示per.liyue.aop.annotion.UserDao类下的所有函数,没有参数可以空括号,有参数用..代替
@Pointcut(value = "execution(* per.liyue.aop.annotion.*.*(..))")
public void aspPointCut(){}
@Before("aspPointCut()")//指定切入点
public void beforeFun()
{
System.out.println("开始之前执行业务。。。");
}
@After("aspPointCut()")//指定切入点
public void afterFun()
{
System.out.println("结束之前执行业务...");
}
@AfterReturning("aspPointCut()")//指定切入点
public void afterReturningFun()
{
System.out.println("返回之后执行业务...");
}
@AfterThrowing("aspPointCut()")//指定切入点
//没有异常的时候不会执行的
public void afterThrowingFun()
{
System.out.println("当捕获异常后执行...");
}
@Around("aspPointCut()")//指定切入点,
public void arroundFun(ProceedingJoinPoint pj) throws Throwable
{
System.out.println("环绕前执行的业务...");
Object obj = pj.proceed();
System.out.println("环绕后执行的业务...");
}
}
2.1.3.4配置xml文件
注意这里需要开启aspect和aop的扫描,否则会报错
<?xml version="1.0" encoding="UTF-8"?>
<!--增加aop命名空间-->
<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">
<context:component-scan base-package="per.liyue.aop.annotion"></context:component-scan>
<!--开启aop的注解方式-->
<aop:config proxy-target-class="true"></aop:config>
<!--开启切面编程-->
<aop:aspectj-autoproxy proxy-target-class="false"></aop:aspectj-autoproxy>
</beans>
2.1.3.5调用实现
package per.liyue.aop.annotion;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* Created by liyue on 2016/11/17.
*/
public class App
{
private ApplicationContext applicationContext = new ClassPathXmlApplicationContext("per/liyue/aop/annotion/bean-aop.xml");
@Test
public void appTest()
{
UserDao userDao = applicationContext.getBean("userDao", UserDao.class);
userDao.save();
}
}
目录
2.2配置方式实现AOP
34.Spring-Aop.md的更多相关文章
- (转)Spring AOP实现方式(转)
我们可以通过三种方式来使用Spring AOP,它们分别是:@Aspect-based(Annotation),Schema-based(XML),以及底层的Spring AOP API 底层的Spr ...
- TinyFrame再续篇:整合Spring AOP实现日志拦截
上一篇中主要讲解了如何使用Spring IOC实现依赖注入的.但是操作的时候,有个很明显的问题没有解决,就是日志记录问题.如果手动添加,上百个上千个操作,每个操作都要写一遍WriteLog方法,工作量 ...
- TinyFrame尾篇:整合Spring AOP实现用户认证
创建Manager用户验证表 这一篇主要讲解使用AOP对用户操作进行验证,如果通过验证,则继续执行,反之,则不能执行.其思想和上一篇完全一致. 由于需要用到用户认证,所以我们新建一个Manager实体 ...
- spring ioc 原理 spring aop原理
大家一直都说spring的IOC如何如何的强大,其实我倒觉得不是IOC如何的强大,说白了IOC其实也非常的简单.我们先从IOC说起,这个概念其实是从我们平常new一个对象的对立面来说的,我们平常使用对 ...
- 利用Spring AOP自定义注解解决日志和签名校验
转载:http://www.cnblogs.com/shipengzhi/articles/2716004.html 一.需解决的问题 部分API有签名参数(signature),Passport首先 ...
- spring aop中pointcut表达式完整版
spring aop中pointcut表达式完整版 本文主要介绍spring aop中9种切入点表达式的写法 execute within this target args @target @with ...
- Spring AOP之使用注解创建切面
上节中我们已经定义了Performance接口,他是切面中的切点的一个目标对象.那么现在就让我们使用AspectJ注解来定义切面吧. 1.定义切面 下面我们就来定义一场舞台剧中观众的切面类Audien ...
- spring AOP自定义注解 实现日志管理
今天继续实现AOP,到这里我个人认为是最灵活,可扩展的方式了,就拿日志管理来说,用Spring AOP 自定义注解形式实现日志管理.废话不多说,直接开始!!! 关于配置我还是的再说一遍. 在appli ...
- Spring 4 官方文档学习(六)核心技术之Spring AOP
目录 1.介绍 1.1.AOP概念 1.2.Spring AOP 能力 和 目标 1.2.1.简介 1.2.2.@AspectJ 支持 1.2.3.声明一个aspect 例子 1.2.4.声明advi ...
- spring aop 样例
基于注解的AOP 方式 1.加入jar包 com.springsource.org.aopalliance-1.0.0.jar com.springsource.org.aspectj.weaver- ...
随机推荐
- 「Poetize3」导弹防御塔
描述 Description Freda控制着N座可以发射导弹的防御塔.每座塔都有足够数量的导弹,但是每座塔每次只能发射一枚.在发射导弹时,导弹需要T1秒才能从防御塔中射出,而在发射导弹后,发射这枚导 ...
- ftp上传下载脚本
#!/usr/bin/env python #encoding=utf-8 # @Date: 2015-08-10 import datetime from ftplib import FTP &qu ...
- (转载)PHP源代码分析- tick(s)
(转载)http://bbs.phpchina.com/forum.php?mod=viewthread&tid=94534 昨天有位朋友在杭州的PHPer群里面贴出了下面的一段代码并给出了运 ...
- page-object使用(1)
创建你的page 你必须做的第一件事情是创建你的page,这是一些包含了PageObject模块的简单的ruby类,请不要创建你自己的initialize方法,因为已经有一个存在而且不能被覆盖.如果你 ...
- 洛谷2583 地铁间谍 (UVa1025A Spy in the Metro)
洛谷2583 地铁间谍(UVa1025A Spy in the Metro) 本题地址:http://www.luogu.org/problem/show?pid=2583 题目描述 特工玛利亚被送到 ...
- tcpCopy
tcpcopy是一种应用请求复制(基于tcp的packets)工具,其应用领域较广,我们曾经应用于网易的广告投放系统,urs系统,nginx hmux协议开发等系统,避免了上线带来的很多问题. 总体说 ...
- UITextField知多少
//初始化textfield并设置位置及大小 UITextField *text = [[UITextField alloc]initWithFrame:CGRectMake(20, 20, 130, ...
- 301重定向与CNAME
CNAME记录是域名指向另一个域名A记录是域名指向IP地址URL跳转是打开这个网址的时候会跳转到另一个指定的网址,URL跳转分为301永久重定向和302临时重定向. 301永久重定向会使搜索引擎抓取新 ...
- 理解RESTful架构(转)
理解RESTful架构 作者: 阮一峰 http://www.ruanyifeng.com/blog/2011/09/restful 越来越多的人开始意识到,网站即软件,而且是一种新型的软件. 这 ...
- dubbo源码分析二:服务发布
本文将深入分析dubbo的服务发布涉及到的流程及主要类的代码.首先,我们先从类的关系图来看一下dubbo发布服务涉及到的相关类. 1.类图 上图展示了部分服务发布过程中需要使用到的类和接口,其中: s ...