有段日子没有总结东西了,因为最近确实有点忙,一直在忙于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. 集合的定义,操作及运算 (Python)

    集合的定义: 集合和列表([  ]) 与  字典 ( {    }) 不同,没有特别的特别的语法格式.可以使用set () 创建. 集合同字典一样是无序的.也是不具有重复性的.因此可以把列表变成集合进 ...

  2. (转)java提高篇(五)-----抽象类与接口

    接口和内部类为我们提供了一种将接口与实现分离的更加结构化的方法. 抽象类与接口是java语言中对抽象概念进行定义的两种机制,正是由于他们的存在才赋予java强大的面向对象的能力.他们两者之间对抽象概念 ...

  3. MySQL学习笔记(六):索引

    本文主要介绍MySQL 中关于索引的一些问题,例如:索引的作用:怎么创建索引:设计索引的原则:怎么优化索引等等. 一:索引概述 索引一般是通过排序,然后查找时可以二分查找,这一特点来达到加速查找的目的 ...

  4. ReentrantLock实现原理及源码分析

    ReentrantLock是Java并发包中提供的一个可重入的互斥锁.ReentrantLock和synchronized在基本用法,行为语义上都是类似的,同样都具有可重入性.只不过相比原生的Sync ...

  5. Android学习笔记-绘制圆形ImageView实例

    现在很多的APP都很喜欢圆形的头像,这里就简单的写个圆形的ImageView~ 第三方圆形ImageView控件: RoundedImageView CircleImageView 实现代码: 自定义 ...

  6. 分享 android 源码

    Android精选源码 UI框架 QSkinLoader换肤框架 一款优雅的中国风Android笔记源码 ListView.RecyclerView两种方式实现聊天界面 android仿滴滴时间选择控 ...

  7. 41. leetcode 53. Maximum Subarray

    53. Maximum Subarray Find the contiguous subarray within an array (containing at least one number) w ...

  8. POJ3268 Silver Cow Party Dijkstra最短路

    Description One cow from each of N farms (1 ≤ N ≤ 1000) conveniently numbered 1..N is going to atten ...

  9. 一份关于webpack2和模块打包的新手指南

    webpack已成为现代Web开发中最重要的工具之一.它是一个用于JavaScript的模块打包工具,但是它也可以转换所有的前端资源,例如HTML和CSS,甚至是图片.它可以让你更好地控制应用程序所产 ...

  10. 推荐60个jQuery插件(转)

    jQuery插件jQuery Spin Button自定义文本框数值自增或自减 jQuery插件JQuery Pager分页器实现javascript分页功能 jQuery插件FontSizer实现J ...