Spring的AOP的用法
来源:互联网 发布:软件服务器租用 编辑:程序博客网 时间:2024/06/10 22:25
AOP称为面向切面编程,在程序开发中主要用来解决一些系统层面上的问题,比如日志,事务,权限等。
一 AOP的基本概念
(1) Aspect(切面):通常是一个类,里面可以定义切入点和通知
(2) JointPoint(连接点):程序执行过程中明确的点,一般是被调用的方法
(3) Advice(通知):AOP在特定的切入点上执行的增强处理,有before,after,afterReturning,afterThrowing,around。也就是在连接点JointPoint方法执行时,用于增强处理。
(4) Pointcut(切入点):就是带有通知的连接点,在程序中主要体现为书写切入点表达式。可以理解为一系列的JointPoint。
(5) AOP代理:AOP框架创建的对象,代理就是目标对象的加强。Spring中的AOP代理可以使JDK动态代理,也可以是CGLIB代理,前者基于接口,后者基于子类
二 Spring AOP
Spring中的AOP代理还是离不开Spring的IOC容器,代理的生成,管理及其依赖关系都是由IOC容器负责,Spring默认使用JDK动态代理,在需要代理类而不是代理接口的时候,Spring会自动切换为使用CGLIB代理,不过现在的项目都是面向接口编程,所以JDK动态代理相对来说用的还是多一些。
三 基于注解的AOP配置方式
1.启用@AsjectJ支持
在applicationContext.xml中配置下面一句,用于识别Aspect的注解配置:
<aop:aspectj-autoproxy />
加入下面的一句话,用于识别Spring的注解配置
<context:component-scan base-package="com.springcode"/>
2.通知类型介绍
(1)Before:在目标方法被调用之前做增强处理,@Before只需要指定切入点表达式即可
(2)After:在目标方法完成之后做增强,无论目标方法时候成功完成。@After可以指定一个切入点表达式
(3)AfterReturning:在目标方法正常完成后做增强,@AfterReturning除了指定切入点表达式后,还可以指定一个返回值形参名returning,代表目标方法的返回值
(4)AfterThrowing:主要用来处理程序中未处理的异常,@AfterThrowing除了指定切入点表达式后,还可以指定一个throwing的返回值形参名,可以通过该形参名来访问目标方法中所抛出的异常对象
(5)Around:环绕通知,在目标方法完成前后做增强处理,环绕通知是最重要的通知类型,像事务,日志等都是环绕通知,注意编程中核心是一个ProceedingJoinPoint
3.例子
(1)LogAspectModel.java --> 切面类
@Component@Aspectpublic class LogAspectModel {// 定义切点表达式@Pointcut("execution(* com.baowei.dao.*.*(..))")public void pointCut_() {}// 前置通知 : 在执行目标方法之前执行@Before("pointCut_()")public void begin() {System.out.println("before ... (可用于开启事务)");}// 后置/最终通知:在执行目标方法之后执行 【无论是否出现异常最终都会执行】@After("pointCut_()")public void after() {System.out.println("after ... (可用于关闭事务)");}// 返回后通知: 在调用目标方法结束后执行 【出现异常不执行】@AfterReturning("pointCut_()")public void afterReturning() {System.out.println("afterReturning...");}// 异常通知: 当目标方法执行异常时候执行此关注点代码@AfterThrowing("pointCut_()")public void afterThrowing() {System.out.println("afterThrowing()");}// 环绕通知:环绕目标方式执行@Around("pointCut_()")public void around(ProceedingJoinPoint pjp) throws Throwable {System.out.println("@Around 环绕前....");pjp.proceed(); // 执行目标方法System.out.println("@Around 环绕后....");}}(2)UserDao.java
@Repositorypublic class UserDao {public User getUser(int id) {System.out.println("get User ...");User user = new User();user.setId(id);user.setName("zhang");return user;}public void deleteUser(int id) {System.out.println("delete User ...");}}
(3)UserService.java
@Servicepublic class UserService {// 持有UserDaoprivate UserDao userdao;public void setUserdao(UserDao userdao) {this.userdao = userdao;}public User getUser(int id) {return userdao.getUser(id);}public void deleteUser(int id) {userdao.deleteUser(id);}}
(4)User.java
public class User {private int id;private String name;public User() {}public int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String toString() {return "User [id=" + id + ", name=" + name + "]";}}
(5)UserTest.java
public class UserTest {public static void main(String[] args) {ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");UserDao userDao = context.getBean(UserDao.class);userDao.deleteUser(1);}}
(6)bean.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:p="http://www.springframework.org/schema/p"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="com.baowei" /><!-- 开启aop注解方式 --><aop:aspectj-autoproxy /></beans>
(7) 注意
上面是一个比较简单的测试,基本涵盖了各种增强定义。注意:做环绕通知的时候,调用ProceedingJoinPoint的proceed()方法才会执行目标方法。
4.通知执行的优先级
进入目标方法时,先织入Around,再织入Before,退出目标方法时,先织入Around,再织入After,最后才织入AfterReturning。
注意:Spring AOP的环绕通知会影响到AfterThrowing通知的运行,不要同时使用!同时使用也没啥意义。
5.切入点的定义和表达式
@Pointcut("execution(* com.aijava.springcode.service..*.*(..))")
第一个*表示匹配任意的方法返回值,..(两个点)表示零个或多个,上面的第一个..表示service包及其子包,第二个*表示所有类,第三个*表示所有方法,第二个..表示方法的任意参数个数
@Pointcut("within(com.aijava.springcode.service.*)")
within限定匹配方法的连接点,上面的就是表示匹配service包下的任意连接点
6.基于XML形式的配置方式
开发中如果选用XML配置方式,通常就是POJO+XML来开发AOP,大同小异,无非就是在XML文件中写切入点表达式和通知类型。
例子:
(1)LogXml.java
@Componentpublic class LogXml {public void begin() {System.out.println("before ... (可用于开启事务)");}public void after() {System.out.println("after ... (可用于关闭事务)");}public void afterReturning() {System.out.println("afterReturning...");}public void afterThrowing() {System.out.println("afterThrowing()");}public void around(ProceedingJoinPoint pjp) throws Throwable {System.out.println("@Around 环绕前....");pjp.proceed(); // 执行目标方法System.out.println("@Around 环绕后....");}}
(2)bean_xml.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:p="http://www.springframework.org/schema/p"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="com.baowei.dao" /><!-- 基于XML的AOP配置 --><bean id="logXml" class="com.baowei.aspectmodel.LogXml" /><aop:config><!-- 定义切点表达式 --><aop:pointcut expression="execution(* com.baowei.dao.*.*(..))"id="pt" /><!-- <aop:config>里面可以多个Aspect --><aop:aspect ref="logXml"><aop:around method="around" pointcut-ref="pt" /><aop:before method="begin" pointcut-ref="pt" /><aop:after method="after" pointcut-ref="pt" /><aop:after-returning method="afterReturning" pointcut-ref="pt" /><aop:after-throwing method="afterThrowing" pointcut-ref="pt" /></aop:aspect></aop:config></beans>
(3)UserXMlTest.java
public class UserXMlTest {public static void main(String[] args) {ApplicationContext context = new ClassPathXmlApplicationContext("bean_xml.xml");UserDao userDao = context.getBean(UserDao.class);userDao.deleteUser(1);}}
7.源码下载
- Spring的AOP用法
- Spring的AOP的用法
- AOP、Spring的AOP
- spring的aop用法个人使用总结
- Spring -- AOP入门基础&基于Aspect的AOP通知用法
- spring(AOP)Aop的概念
- spring的的AOP
- Spring AOP中RegexpMethodPointCut使用的正则表达式用法
- Spring的AOP实现
- spring的AOP介绍
- Spring的aop
- 6.2 Spring的AOP
- Spring 的AOP运用
- spring aop的理解
- spring aop的讲解
- spring的aop原理
- spring的aop
- spring的AOP配置
- Reorder the Books hdu 5500 贪心
- 二叉树的遍历
- 脚本安装php5.5+mysql+apache+phpmyadmin
- linux C学习一站式学习资料链接
- Mysql的with rollup(5.1以上版本)
- Spring的AOP的用法
- Java学习笔记(三)
- Chapeau Linux 发布!
- 文章标题
- C++分数的表达,C++的<ratio>头文件
- Thread 传值 跨线程
- Ruby递归删除空目录
- 并查集略解
- 常见对象_StringBuffer的替换功能