有段日子没有总结东西了,因为最近确实有点忙,一直在忙于hadoop集群的搭建,磕磕碰碰现在勉强算是能呼吸了,因为这都是在自己的PC上,资源确实有点紧张(搭建过程后期奉上),今天难得大家都有空(哈哈哈~~~),给各位总结一下Java开发猿人尽皆知的Spring框架它的核心组件——AOP(面向切面编程)。

老规矩,首先给各位说说它吧。AOP作为面向切面编程,是一种横向抽取的思想体现,不错,有了"横向切"这个概念呢,我们就应该会联想到之后的横切面、切入点,接着你有可能就会闭上眼睛想入非非,但是哥们你千万不要走歪,咱们现在讨论的是Java领域的切面编程,啊哈哈哈~好了,既然是面向切面编程,那么就避免不了"切",都知道,咱们的项目都会从web层到service层到dao层依次执行,既然是切,那么就会从某个层和某个层之间切开,接着就会做一些我们想做的事儿。反正大概的意思就是我所理解的切面编程,譬如切面编程的底层采用动态代理实现,在Spring框架中具体是如何执行的,我就不在这儿啰嗦了,因为这个点儿我也对源码不是理解的那么透彻,一直在学习的路上,等后期吃到点儿精华再回来给各位完善,下面我就会将我使用2中方式实现AOP切面编程的案例给各位共享一下。

小小一张图,请给位笑纳:

Spring框架的AOP切面编程分为俩种:注解式开发和XML配置式开发。

项目结构图:

AOP注解式开发:

首先我们使用注解式开发,最重要的一点就是能够让这些注解生效,何为生效?就是能够让它们活着看到spring框架的临幸,为什么说这个不起眼的问题呢,我在昨天使用注解都开发完了,但是怎么也执行不到切面上的方法,说白了就是注解没有扫描到,按理论说,切面都是会出现在service层前后,也就是说一般切面会作用在service层上,比如:在更新操作前进行权限校验、在检索操作时记录检索时长等等。那么我们通常使用spring的容器来扫描这些注解,但是在一些springMVC和spring共存的项目中,我们还不得不注意一下它们父子容器的关系,千万不要认为父子容器和谐共存,和谐共事【这里打个广告:有关父子容器的问题,请参考http://www.cnblogs.com/1315925303zxz/p/7211037.html】。我这里扫描切面是由spring容器完成的,因为我的切面类都在service层中了,所以我的切面组件的注解是由父容器spring的配置文件扫描的:

1、开启AOP注解解析器:

 <!-- 【启动AOP的注解解析器】(基于注解方式必须添加该注解解析器)  -->
<aop:aspectj-autoproxy/>

2、实现注解切面编程,附:切入点表达式,AOP切入点表达式的书写格式: 方法返回值 完整包名.类名.方法名(参数)。 注:如果方法返回值和参数类型不限则可以使用*代替,如果以什么什么开头的方法也可以使用*代替,就如我们配置spring管理事务的传播行为雷同。涉及到的AOP的通知类型,在第二种XML配置方式中会详细介绍,哥们儿别停继续看着。

 @Component
@Aspect //声明这是一个切面类
public class SelecctAop { public static final String REGEX_IP_ADDR = "([1-9]|[1-9]\\d|1\\d{2}|2[0-4]\\d|25[0-5])(\\.(\\d|[1-9]\\d|1\\d{2}|2[0-4]\\d|25[0-5])){3}"; private Date startDate = null; //专门用于存放开始时间 /**
* 定义一个切入点
*/
@Pointcut("execution(* cn.base.service.*.find*(..))")
private void selectPointcut(){} /**
* 检索开始前的时间记录
* @return
* @throws Exception
*/
@Before("selectPointcut()")    //通知类型
public void startTime() throws Exception{
String hostAddress = InetAddress.getLocalHost().getHostAddress(); //获取操作用户的IP地址
boolean isLegal = hostAddress.matches(REGEX_IP_ADDR); //验证IP地址
if(StringUtil.isNullOrBlank(hostAddress) && !isLegal){
//如果IP地址为空并且IP地址不合法
System.err.println("=============警告:非法用户操作==============");
}
startDate = DateTimeUtils.getCurrentDate("yyyy-MM-dd HH:mm:ss"); //开始时间
System.err.println(startDate+"【开始】==="+hostAddress+"用户开始操作");
} /**
* 检索结束后的时间记录、共计操作时长
* @throws Exception
*/
@After("selectPointcut()")    //通知类型
public void timeConsuming() throws Exception{
String hostAddress = InetAddress.getLocalHost().getHostAddress(); //获取操作用户的IP地址
boolean isLegal = hostAddress.matches(REGEX_IP_ADDR); //验证IP地址
if(StringUtil.isNullOrBlank(hostAddress) && !isLegal){
//如果IP地址为空并且IP地址不合法
System.err.println("=============警告:非法用户操作==============");
}
Date endDate = DateTimeUtils.getCurrentDate("yyyy-MM-dd HH:mm:ss"); //结束时间
System.err.println(endDate+"【终止】==="+hostAddress+"用户结束操作");
long startTime = startDate.getTime();
long endTime = endDate.getTime();
long time = endTime - startTime;
System.err.println("================【共计耗时:" + time+ "】=====================");
} public static void main(String[] args) { } }

3、只要你访问调用了service层中检索操作的方法,就会触发切面上的方法,我这里是只要用户进行检索操作,就会实时记录该次检索操作的检索时长。

4、效果如图:

XML配置式开发:

这种方式相对来说比较原始一点儿,就是通过在spring的核心配置文件中进行配置实现AOP切面编程,就是通过将切面类交由spring容器管理,然后通过spring容器的配置将切面类作用与相关业务方法上。

1、更新操作的切面类:

 package cn.base.service.aspect;

 import java.net.InetAddress;
import java.net.UnknownHostException;
import com.zxz.utils.DateTimeUtils;
import com.zxz.utils.StringUtil; /**
* 更新操作切面类:执行删除、修改、保存操作时需配置的切面类。[基于XML配置方式实现]
* @author zxz
*/ public class UpdateAop { public static final String REGEX_IP_ADDR = "([1-9]|[1-9]\\d|1\\d{2}|2[0-4]\\d|25[0-5])(\\.(\\d|[1-9]\\d|1\\d{2}|2[0-4]\\d|25[0-5])){3}"; /**
* 用户进行更新操作之前的IP记录
*/
public void recordIP(){
String hostAddress = "";
try {
hostAddress = InetAddress.getLocalHost().getHostAddress(); //获取操作用户的IP地址
boolean isLegal = hostAddress.matches(REGEX_IP_ADDR); //验证IP地址
if(StringUtil.isNullOrBlank(hostAddress) && !isLegal){
//如果IP地址为空并且IP地址不合法
System.err.println("=============警告:非法用户操作==============");
}
} catch (UnknownHostException e) {
e.printStackTrace();
}
System.err.println("【==="+DateTimeUtils.getCurrentMsLocal() + "---IP为:" + hostAddress + "进行了更新操作。===】");
} public static void main(String[] args) throws Exception {
// String hostAddress = InetAddress.getLocalHost().getHostAddress();
// System.out.println(hostAddress);
// System.out.println(hostAddress.matches(REGEX_IP_ADDR));
} }

2、通过spring的配置实现切面编程:

 <!-- 配置更新切面类 -->
<bean id="updateAop" class="cn.base.service.aspect.UpdateAop"/> <!-- spring的aop配置(基于XML方式的) -->
<aop:config>
<!-- 配置切入点:
AOP切入点表达式的书写格式: 方法返回值 完整包名.类名.方法名(参数)。 注:如果方法返回值和参数类型不限则可以使用*代替。
-->
<aop:pointcut expression="execution(* cn.base.service.*.delete*(..))" id="updatePointcut"/>
<!-- 配置切面 -->
<aop:aspect ref="updateAop">
<!-- 切面的通知类型:
AOP的通知类型有:
1、前置通知【before】在方法执行之前进行增强,获得切入点信息。
2、后置通知【after】在方法执行之后进行增强,获得方法的返回值。
3、环绕通知【around】在方法执行前后进行增强,[阻止]目标方法执行。
4、异常抛出通知【after-throwing】在方法执行出现异常的时候进行增强,获得异常信息。
5、最终通知【after-returning】无论方法是否出现异常,最终通知中代码总是会执行的。
-->
<aop:before method="recordIP" pointcut-ref="updatePointcut"/>
</aop:aspect>
</aop:config>

3、同理,只要你访问调用了service层中删除操作时就会触发切面类上的方法,我这里是当用户进行删除操作,则会记录执行删除操作的用户的IP地址并打印在日志中。

4、效果如图:

[好了,哥们儿到站了,醒醒吧,是不是没什么技术含量,把你都看醉了,哈哈哈~~~后期会给各位奉上hadoop相关的文章,因为一直在学习的路上,天气甚好在首都向各位问好!]

总结切面编程AOP的注解式开发和XML式开发的更多相关文章

  1. AOP面向切面编程(使用注解和使用配置文件)

    Aop(面向切面编程) 使用注解的方式: 加入相应的jar包: com.springsource.org.aopalliance-1.0.0.jar com.springsource.org.aspe ...

  2. Spring学习手札(二)面向切面编程AOP

    AOP理解 Aspect Oriented Program面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术. 但是,这种说法有些片面,因为在软件工程中,AOP的价值体现的并 ...

  3. 04 Spring:01.Spring框架简介&&02.程序间耦合&&03.Spring的 IOC 和 DI&&08.面向切面编程 AOP&&10.Spring中事务控制

    spring共四天 第一天:spring框架的概述以及spring中基于XML的IOC配置 第二天:spring中基于注解的IOC和ioc的案例 第三天:spring中的aop和基于XML以及注解的A ...

  4. Spring框架系列(4) - 深入浅出Spring核心之面向切面编程(AOP)

    在Spring基础 - Spring简单例子引入Spring的核心中向你展示了AOP的基础含义,同时以此发散了一些AOP相关知识点; 本节将在此基础上进一步解读AOP的含义以及AOP的使用方式.@pd ...

  5. 设计模式之面向切面编程AOP

    动态的将代码切入到指定的方法.指定位置上的编程思想就是面向切面的编程. 代码只有两种,一种是逻辑代码.另一种是非逻辑代码.逻辑代码就是实现功能的核心代码,非逻辑代码就是处理琐碎事务的代码,比如说获取连 ...

  6. Spring框架学习笔记(2)——面向切面编程AOP

    介绍 概念 面向切面编程AOP与面向对象编程OOP有所不同,AOP不是对OOP的替换,而是对OOP的一种补充,AOP增强了OOP. 假设我们有几个业务代码,都调用了某个方法,按照OOP的思想,我们就会 ...

  7. Spring之控制反转——IoC、面向切面编程——AOP

      控制反转——IoC 提出IoC的目的 为了解决对象之间的耦合度过高的问题,提出了IoC理论,用来实现对象之间的解耦. 什么是IoC IoC是Inversion of Control的缩写,译为控制 ...

  8. [译]如何在ASP.NET Core中实现面向切面编程(AOP)

    原文地址:ASPECT ORIENTED PROGRAMMING USING PROXIES IN ASP.NET CORE 原文作者:ZANID HAYTAM 译文地址:如何在ASP.NET Cor ...

  9. Spring学习笔记:面向切面编程AOP(Aspect Oriented Programming)

    一.面向切面编程AOP 目标:让我们可以“专心做事”,避免繁杂重复的功能编码 原理:将复杂的需求分解出不同方面,将公共功能集中解决 *****所谓面向切面编程,是一种通过预编译方式和运行期动态代理实现 ...

随机推荐

  1. Echarts报错[MODULE_MISS]"echarts/config" is not exists!

    项目用到Echarts插件,时下比较流行的是模块化包引入,但是很悲催的是楼主用的是标签式引入,所以从官网copy来的代码总是报一个 [MODULE_MISS]"echarts/config的 ...

  2. poj 1161 Walls

    https://vjudge.net/problem/POJ-1161 题意:有m个区域,n个小镇,有c个人在这些小镇中,他们要去某一个区域中聚会,从一个区域到另一个区域需要穿墙,问这些人聚到一起最少 ...

  3. linux系统编程之文件IO

    1.打开文件的函数open,第一个参数表示文件路径名,第二个为打开标记,第三个为文件权限 代码: #include <sys/types.h> #include <sys/stat. ...

  4. C++学习(五)入门篇——基本类型

    面向对象编程的本质是设计并扩展自己的数据类型,让类型和数据匹配. 内置C++分成两种类型:基本类型和复合类型 1.简单变量 程序需要存储信息时,必须记录三个基本属性 (1)信息将存储在哪 (2)要存储 ...

  5. 用Maven创建web项目

    使用eclipse插件创建一个web project 首先创建一个Maven的Project如下图 我们勾选上Create a simple project (不使用骨架) 这里的Packing 选择 ...

  6. (转)递归算法的时间复杂度终结篇与Master method

    开篇前言:为什么写这篇文章?笔者目前在学习各种各样的算法,在这个过程中,频繁地碰到到递归思想和分治思想,惊讶于这两种的思想的伟大与奇妙的同时,经常要面对的一个问题就是,对于一个给定的递归算法或者用分治 ...

  7. Objective-C 自定义UISlider滑杆 分段样式

    效果 自定义一个功能简单的分段的滑杆 可显示分段名 为了显示效果,我们将滑块和节点都设置为不规则 这里只实现了分段的slider,未分段的没有实现,有兴趣的可以定义另一种类型做个判断修改下 需求分析 ...

  8. python之二维码生成

    生成的二维码只是网址的链接 直接上代码: import qrcode title = input("要生成的内容:") img = qrcode.make(title) with ...

  9. business meeting

    Metting are all about discussions . discussion expression 开始会议 Let's get started We need to discuss. ...

  10. 蓝桥杯比赛javaB组练习《饮料换购》

    题目如下: 饮料换购 乐羊羊饮料厂正在举办一次促销优惠活动.乐羊羊C型饮料,凭3个瓶盖可以再换一瓶C型饮料,并且可以一直循环下去,但不允许赊账. 请你计算一下,如果小明不浪费瓶盖,尽量地参加活动,那么 ...