AOP(Aspect Oriented Programming),是面向切面编程的技术。AOP基于IoC基础,是对OOP的有益补充。

AOP之所以能得到广泛应用,主要是因为它将应用系统拆分分了2个部分:核心业务逻辑(Core business concerns)及横向的通用逻辑,也就是所谓的切面Crosscutting enterprise concerns。例如,所有大中型应用都要涉及到的持久化管理(Persistent)、事务管理(Transaction Management)、权限管理(Privilege
Management)、日志管理(Logging)和调试管理(Debugging)等。

使用AOP技术,可以让开发人员只专注核心业务,而通用逻辑则使用AOP技术进行横向切入,由专人去处理这些通用逻辑,会使得任务简单明了,提高开发和调试的效率。

使用AOP,我们要注意关注横切性的功能,即抽象出独立服务,进行模块化使我们以前习惯性的纵向思维的方法再改变,注意横向思考问题的方式,我们结合现在的系统可以把判断文本框一些了的验证、日志的记录、事务的开启、数据库的开启和关闭等等,都可以抽象出使用切面的形式把这些方法切入进去,我们只需要关心我们的业务逻辑,这样代码简单,间接,开发效率大大提高,更重要的是复用效率大大提高了。

基本概念

要想了解AOP,首先得了解几个重要的基本概念:


  • 切面(Aspect):一个关注点的模块化,这个关注点实现可能另外横切多个对象。比如说事务管理就是J2EE应用中一个很好的横切关注点例子。切面用Spring的Advisor或拦截器实现。
  • 连接点(Joinpoint):程序执行过程中明确的点,如方法的调用或特定的异常被抛出。
  • 通知(Advice):在特定的连接点,AOP框架执行的动作。各种类型的通知包括“around”、“before”和“throws”通知。通知类型将在下面讨论。许多AOP框架包括Spring都是以拦截器做通知模型,维护一个“围绕”连接点的拦截器链。
  • 切入点(Pointcut):指定一个通知将被引发的一系列连接点的集合。AOP框架必须允许开发者指定切入点,例如,使用正则表达式。
  • 目标对象(Target Object):包含连接点的对象,也被称作被通知或被代理对象。
  • AOP代理(AOP Proxy):AOP框架创建的对象,包含通知。在Spring中,AOP代理可以是JDK动态代理或CGLIB代理。
  • 编织(Weaving):组装方面来创建一个被通知对象。这可以在编译时完成(例如使用AspectJ编译器),也可以在运行时完成。Spring和其他纯Java AOP框架一样,在运行时完成织入。

各种通知(Advice)类型

    为了符合各种流程处理,通知类型提供了5种,可以对目标方法进行全方位处理:
  • Before advice:在某连接点(JoinPoint)之前执行的通知,但这个通知不能阻止连接点前的执行。

    ApplicationContext中在<aop:aspect>里面使用<aop:before>元素进行声明。
  • After advice:当某连接点退出的时候执行的通知(不论是正常返回还是异常退出)。

    ApplicationContext中在<aop:aspect>里面使用<aop:after>元素进行声明。
  • After returnadvice:在某连接点正常完成后执行的通知,不包括抛出异常的情况。

    ApplicationContext中在<aop:aspect>里面使用<aop:after-returning>元素进行声明。
  • Around advice:包围一个连接点的通知,类似Web中Servlet规范中的Filter的doFilter方法。可以在方法的调用前后完成自定义的行为,也可以选择不执行。

    ApplicationContext中在<aop:aspect>里面使用<aop:around>元素进行声明。
  • Afterthrowing advice:在方法抛出异常退出时执行的通知。

    ApplicationContext中在<aop:aspect>里面使用<aop:after-throwing>元素进行声明。

本文采用的JDK代理方式

AspectJ注解方式配置AOP,实例讲解

SecurityHandler,这个通知类可以换成安全性检测、日志管理、事务开启关闭等等。

<span style="font-family:FangSong_GB2312;font-size:18px;">package com.bjpowernode.spring;

import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut; @Aspect
public class SecurityHandler { /**
* 定义Pointcut,Pointcut的名称为addAddMethod(),此方法没有返回值和参数
* 该方法就是一个标识,不进行调用
*/
@Pointcut("execution(* add*(..))")
private void addAddMethod(){}; /**
* 定义Advice,表示我们的Advice应用到哪些Pointcut订阅的Joinpoint上
*/
//@Before("addAddMethod()")
@After("addAddMethod()")
private void checkSecurity() {
System.out.println("-------checkSecurity-------");
}
}
</span>

UserManager接口

<span style="font-family:FangSong_GB2312;font-size:18px;">package com.bjpowernode.spring;

public interface UserManager {

	public void addUser(String username, String password);

	public void delUser(int userId);

	public String findUserById(int userId);

	public void modifyUser(int userId, String username, String password);
}
</span>

UserManagerImpl实现

<span style="font-family:FangSong_GB2312;font-size:18px;">package com.bjpowernode.spring;

public class UserManagerImpl implements UserManager {

	public void addUser(String username, String password) {
//checkSecurity();
System.out.println("---------UserManagerImpl.add()--------");
} public void delUser(int userId) {
//checkSecurity();
System.out.println("---------UserManagerImpl.delUser()--------");
} public String findUserById(int userId) {
//checkSecurity();
System.out.println("---------UserManagerImpl.findUserById()--------");
return "张三";
} public void modifyUser(int userId, String username, String password) {
//checkSecurity();
System.out.println("---------UserManagerImpl.modifyUser()--------");
} // private void checkSecurity() {
// System.out.println("-------checkSecurity-------");
// }
}
</span>

application-config.xml中,只需要配置业务逻辑bean和Aspect bean,并启用Aspect注解即可:

<span style="font-family:FangSong_GB2312;font-size:18px;"><?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:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd"> <!-- 启用AspectJ对Annotation的支持 -->
<aop:aspectj-autoproxy/> <bean id="userManager" class="com.bjpowernode.spring.UserManagerImpl"/> <bean id="securityHandler" class="com.bjpowernode.spring.SecurityHandler"/>
</beans>
</span>

Client客户端

<span style="font-family:FangSong_GB2312;font-size:18px;">package com.bjpowernode.spring;

import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.support.ClassPathXmlApplicationContext; public class Client { public static void main(String[] args) {
BeanFactory factory = new ClassPathXmlApplicationContext("applicationContext.xml");
UserManager userManager = (UserManager)factory.getBean("userManager");
userManager.addUser("张三", "123");
} }
</span>

效果图

当然我们通过注解的方式可以实现灵活的配置

<span style="font-family:FangSong_GB2312;font-size:18px;">/**
* 定义Advice,表示我们的Advice应用到哪些Pointcut订阅的Joinpoint上
*/
@Before("addAddMethod()")
//@After("addAddMethod()")
private void checkSecurity() {
System.out.println("-------checkSecurity-------");
} </span>

修改后的效果:

总结

Annotation

优点

保存在 class 文件中,降低维护成本。

无需工具支持,无需解析。

编译期即可验证正确性,查错变得容易。 

   缺点

         若要对配置项进行修改,不得不修改 Java 文件,重新编译打包应用。

总的来说,AOP这样的好处是我们抽象出公共的方法之后,我们的代码,方法复用性大大提高,实现了可灵活的配置,提高了系统的可靠性。



接下来

SSH深度历险(十一) AOP原理及相关概念学习+xml配置实例(对比注解方式的优缺点)

SSH深度历险(十) AOP原理及相关概念学习+AspectJ注解方式配置spring AOP的更多相关文章

  1. SSH深度历险(十一) AOP原理及相关概念学习+xml配置实例(对比注解方式的优缺点)

    接上一篇 SSH深度历险(十) AOP原理及相关概念学习+AspectJ注解方式配置spring AOP,本篇我们主要是来学习使用配置XML实现AOP 本文采用强制的CGLB代理方式 Security ...

  2. Spring Aop(二)——基于Aspectj注解的Spring Aop简单实现

    转发地址:https://www.iteye.com/blog/elim-2394762 2 基于Aspectj注解的Spring Aop简单实现 Spring Aop是基于Aop框架Aspectj实 ...

  3. Spring Aop实例@Aspect、@Before、@AfterReturning@Around 注解方式配置

    用过spring框架进行开发的人,多多少少会使用过它的AOP功能,都知道有@Before.@Around和@After等advice.最近,为了实现项目中的输出日志和权限控制这两个需求,我也使用到了A ...

  4. Spring学习4-面向切面(AOP)之aspectj注解方式

    一.简介    1.AOP用在哪些方面:AOP能够将那些与业务无关,却为业务模块所共同调用的逻辑或责任,例如事务处理.日志管理.权限控制,异常处理等,封装起来,便于减少系统的重复代码,降低模块间的耦合 ...

  5. Spring——AOP(面向切面编程)@AspectJ注解方式

    一.什么是AOP? AOP: (Aspect Oriented Programming)即面向切面编程. 试想这样的场景:项目中需要在业务方法执行完打印日志记录.最笨的办法就是在每个方法核心业务执行完 ...

  6. SpringInAction--XML配置Spring Aop

    前面学习了如何用注解的方式去配置Spring aop,今天把XML配置的方法也看了下,下面顺便也做了个记录 先把spring中用xml配置aop的配置元素给贴出来: <aop:advisor&g ...

  7. 基于@AspectJ配置Spring AOP之一--转

    原文地址:http://tech.it168.com/j/2007-08-30/200708302209432.shtml 概述 在低版本Spring中定义一个切面是比较麻烦的,需要实现特定的接口,并 ...

  8. ssh整合随笔(注解方式,Spring 管理action)

    Web.xml<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi=" ...

  9. 自定义注解实现(spring aop)

    1.基本概念 1.1 aop 即面向切面编程,优点是耦合性低,能使业务处理和切面处理分开开发,扩展和修改方面,当引入了注解方式时,使用起来更加方便. 1.2 应用场景 打日志.分析代码执行时间.权限控 ...

随机推荐

  1. 【Bzoj 1835 基站选址】

    基站选址的区间里隐藏着DP优化的机密…… 分析:       不论是做过乘积最大还是石子合并,或者是其他的入门级别的区间DP题目的人呐,大米并认为读题后就能够轻松得出一个简洁明了的Dp转移方程.    ...

  2. 【UOJ UNR #1】火车管理

    来自FallDream的博客,未经允许,请勿转载,谢谢. 题面 考虑用可持久化线段树直接维护每个点在不同时刻,第一辆车的编号. 这样3操作就变成了区间赋值,1操作变成区间和 2操作的话,只需要查询一下 ...

  3. Spring源码分析(一)--BeanProcessor

    一.何谓BeanProcessor BeanProcessor是SpringFramework里非常重要的核心接口之一,我先贴出一段源代码: /* * Copyright 2002-2015 the ...

  4. Linux学习之CentOS(一)--CentOS6.5环境搭建

    一.前言 作为一个从事运维工作好几年的老运维来说,linux系统怎能不学呢?所以,这几天自己准备学习一下linux操作系统.废话不多说,直奔主题. 要学linux开发,首先得要安装linux系统吧,这 ...

  5. 从 vCenter Server 使用的数据库中清除旧数据 (2075138)(转)

    Document Id 2075138 Symptoms 免责声明: 本文为 Purging old data from the database used by VMware vCenter Ser ...

  6. JS 中判断空值 undefined 和 null

    1.JS 中如何判断 undefined JavaScript 中有两个特殊数据类型:undefined 和 null,下节介绍了 null 的判断,下面谈谈 undefined 的判断. 以下是不正 ...

  7. Oracle10g以上sysaux表空间的维护和清理

    SYSAUX表空间在Oracle 10g中引入,其作为SYSTEM表空间的辅助表空间.之前,一些使用独立表空间或系统表空间的数据库组件,现在SYSAUX表空间中存在.通过分离这些组件,减轻了SYSTE ...

  8. Exchange Server 2010升级到Exchange Server 2016

    Hello各位小伙伴们,失踪人口回归啦~~~这次和大家分享Exchange Server 2010升级到Exchange Server 2016的方法.正式开始前先啰嗦几句,为什么我要写这篇文章呢?一 ...

  9. Java finalize方法使用

    <JAVA编程思想>: Java提供finalize()方法,垃圾回收器准备释放内存的时候,会先调用finalize(). (1).对象不一定会被回收. (2).垃圾回收不是析构函数. ( ...

  10. 阿里云部署Node.js项目(CentOS)

    Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境,用来方便地搭建快速的易于扩展的网络应用.Node.js 使用了一个事件驱动.非阻塞式 I/O 的模型,使其轻量又 ...