AOP(Aspect-Oriented Programming。面向方面编程)。能够说是OOP(Object-OrientedPrograming。面向对象编程)的补充和完好。OOP引入封装、继承和多态性等概念来建立一种对象层次结构,用以模拟公共行为的一个集合。

OOP的问题,AOP的补充

当我们须要为分散的对象引入公共行为的时候,OOP则显得无能为力。也就是说,OOP同意你定义从上到下的关系,但并不适合定义从左到右的关系。

比如日志功能。日志代码往往水平地散布在全部对象层次中,而与它所散布到的对象的核心功能毫无关系。对于其它类型的代码,如安全性、异常处理和透明的持续性也是如此。这样的散布在各处的无关的代码被称为横切(cross-cutting)代码。在OOP设计中,它导致了大量代码的反复,而不利于各个模块的重用。

所谓“方面”,简单地说,就是将那些与业务无关。却为业务模块所共同调用的逻辑或责任封装起来。便于降低系统的反复代码,降低模块间的耦合度,并有利于未来的可操作性和可维护性。

Spring中对 AOP的支持

Spring中 AOP代理由Spring的
IoC容器负责生成、管理,其依赖关系也由 IoC容器负责管理。因此,AOP代理能够直接使用容器中的其它 Bean实例作为目标,这样的关系可由
IoC容器的依赖注入提供。Spring默认使用 Java动态代理来创建AOP代理。这样就能够为不论什么接口实例创建代理了。当须要代理的类不是代理接口的时候,
Spring自己主动会切换为使用 CGLIB代理,也可强制使用 CGLIB。

程序猿參与部分

AOP编程事实上是非常easy的事情。

纵观 AOP编程,当中须要程序猿參与的仅仅有三个部分:

定义普通业务组件。

定义切入点,一个切入点可能横切多个业务组件。

定义增强处理,增强处理就是在AOP框架为普通业务组件织入的处理动作。

所以进行 AOP编程的关键就是定义切入点和定义增强处理。一旦定义了合适的切入点和增强处理,AOP框架将会自己主动生成AOP代理。即:代理对象的方法
=增强处理 +被代理对象的方法。

Spring中使用方式:

基于 Annotation的“零配置”方式。

(1)启动注解。配置文件applicationContext.xml

<!-- 启动对@AspectJ注解的支持 -->
<aop:aspectj-autoproxy/> <bean id="user" class="com.tgb.spring.aop.IUserImpl"/> <bean id="check" class="com.tgb.spring.aop.CheckUser"/>

(2)编写切面类

package com.tgb.spring.aop;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut; @Aspect
public class CheckUser { @Pointcut("execution(* com.tgb.spring.aop.*.find*(..))")
public void checkUser(){
System.out.println("**************The System is Searching Information For You****************");
} @Pointcut("execution(* com.tgb.spring.aop.*.add*(..))")
public void checkAdd(){
System.out.println("**************<< Add User >> Checking.....***************");
} @Before("checkUser()")
public void beforeCheck(){
System.out.println(">>>>>>>> 准备搜查用户..........");
} @After("checkUser()")
public void afterCheck(){
System.out.println(">>>>>>>> 搜查用户完成..........");
} @Before("checkAdd()")
public void beforeAdd(){
System.out.println(">>>>>>>> 添加用户--检查ing..........");
} @After("checkAdd()")
public void afterAdd(){
System.out.println(">>>>>>>> 添加用户--检查完成! 未发现异常!..........");
} //声明围绕通知
@Around("checkUser()")
public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
System.out.println("进入方法---围绕通知");
Object o = pjp.proceed();
System.out.println("退出方法---围绕通知");
return o;
}
}

(3)定义接口

package com.tgb.spring.aop;

public interface IUser {

	public String findUser(String username);
public void addUser(String username);
public void findAll();
}

(4)定义实现

package com.tgb.spring.aop;

import java.util.HashMap;
import java.util.Map; public class IUserImpl implements IUser { public static Map map = null;
public static void init(){
String[] list = {"Lucy", "Tom", "小明", "Smith", "Hello"};
Map tmp = new HashMap();
for(int i=0; i<list.length; i++){
tmp.put(list[i], list[i]+"00");
}
map = tmp;
}
public void addUser(String username) {
init();
map.put(username, username+"11");
System.out.println("--------------【addUser】: "+username+" --------------");
System.out.println("【The new List:"+map+"】");
} public void findAll() {
init();
System.out.println("---------------【findAll】: "+map+" ------------------");
} public String findUser(String username) {
init();
String password = "没查到该用户";
if(map.containsKey(username)){
password = map.get(username).toString();
}
System.out.println("-----------------【findUser】-----------------");
System.out.println("-----------------Username:"+username+"-----------------");
System.out.println("-----------------【Result】:"+password+"------------------");
return password; } }

(5)測试

public class Test {

	public static void main(String as[]){
BeanFactory factory = new ClassPathXmlApplicationContext("applicationContext.xml");
IUser user = (IUser) factory.getBean("user");
user.findAll(); User u = new User();
// u.setUsername("Tom");
// user.findUser(u.getUsername()); /*u.setUsername("haha");
user.addUser(u.getUsername());*/
}
}

运行结果:

进入方法---围绕通知

>>>>>>>>准备搜查用户..........

---------------【findAll】: {Smith=Smith00, Tom=Tom00, 小明=小明00, Lucy=Lucy00,Hello=Hello00} ------------------

退出方法---围绕通知

>>>>>>>> 搜查用户完成..........

注:@Before是在所拦截方法运行之前运行一段逻辑。@After是在所拦截方法运行之后运行一段逻辑。@Around是能够同一时候在所拦截方法的前后运行一段逻辑。

以上是针对注解的方式来实现。那么配置文件也一样,仅仅须要在applicationContext.xml中加入例如以下代码:

<!--  <aop:config>
<aop:pointcut id="find" expression="execution(* com.tgb.spring.aop.*.find*(..))" />
<aop:pointcut id="add" expression="execution(* com.tgb.spring.aop.*.add*(..))" /> <aop:aspect id="checkUser" ref="check">
<aop:before method="beforeCheck" pointcut-ref="find"/>
<aop:after method="afterCheck" pointcut-ref="find"/>
</aop:aspect> <aop:aspect id="checkAdd" ref="check">
<aop:before method="beforeAdd" pointcut-ref="add"/>
<aop:after method="afterAdd" pointcut-ref="add"/>
</aop:aspect> </aop:config>-->

总结:

以上是简介了一下怎样使用Spring AOP,在使用的过程中也加深我们对AOP思想的理解。事实上AOP就是要我们实现热插拔效果,下篇会继续介绍Spring
AOP的实现原理。

附:在使用过程中注意JDK版本号与易用的aspectJrt的版本号问题

Spring AOP应用实例demo的更多相关文章

  1. Spring Aop 应用实例与设计浅析

    0.代码概述 代码说明:第一章中的代码为了突出模块化拆分的必要性,所以db采用了真实操作.下面代码中dao层使用了打印日志模拟插入db的方法,方便所有人运行demo. 1.项目代码地址:https:/ ...

  2. Spring AOP 入门实例详解

    目录 AOP概念 AOP核心概念 Spring对AOP的支持 基于Spring的AOP简单实现 基于Spring的AOP使用其他细节 AOP概念 AOP(Aspect Oriented Program ...

  3. Spring学习(十五)----- Spring AOP通知实例 – Advice

    Spring AOP(面向方面编程)框架,用于在模块化方面的横切关注点.简单得说,它只是一个拦截器拦截一些过程,例如,当一个方法执行,Spring AOP 可以劫持一个执行的方法,在方法执行之前或之后 ...

  4. Spring AOP通知实例 – Advice

    Spring AOP(面向方面编程)框架,用于在模块化方面的横切关注点.简单得说,它只是一个拦截器拦截一些过程,例如,当一个方法执行,Spring AOP 可以劫持一个执行的方法,在方法执行之前或之后 ...

  5. SSH框架系列:Spring AOP应用记录日志Demo

    分类: [java]2013-12-10 18:53 724人阅读 评论(0) 收藏 举报 1.简介 Spring 中的AOP为Aspect Oriented Programming的缩写,面向切面编 ...

  6. Spring aop 小例子demo

    由于最近的服务项目提供接口有一个需求,所有操作都必须检查操作的服务可用,所以感觉Aop特别适合实施.完成学习的小例子. 关于spring-Aop原理:http://m.oschina.net/blog ...

  7. [Spring] AOP, Aspect实例解析

    最近要用到切面来统一处理日志记录,写了个小实例练了练手: 具体实现类: public interface PersonServer { public void save(String name); p ...

  8. spring Aop的一个demo

    面向切面是什么我就不说了. 上代码: package com.foreveross.service.weixin.test; import java.lang.annotation.Documente ...

  9. spring aop 的一个demo(未完,待完善)

    假设我们有这样的一个场景 : 对于一个类的众多方法,有些方法需要从缓存读取数据,有些则需要直接从数据库读取数据.怎样实现呢? 实现方案有多种.下面我说下常见的几种实现方案 : 1.直接采用spring ...

随机推荐

  1. CentOS7--Xshell网络中断引起的vi编辑文件问题

    在编写Python的程序时,由于不小心触碰网线使xshell出现网络中断问题,当再次以vi命令打开文件准备编辑时,发现爆出英文错误: 该错误的英文翻译大概是(1)另一个程序也在编译这个文件,如果是这样 ...

  2. 让DIV垂直居中的几种办法

    1.使用CSS3 的伸缩盒布局 <!doctype html> <html> <head> <meta charset="utf-8"&g ...

  3. Javascript进阶篇——(DOM—节点---获取浏览器窗口可视区域大小+获取网页尺寸)—笔记整理

    浏览器窗口可视区域大小获得浏览器窗口的尺寸(浏览器的视口,不包括工具栏和滚动条)的方法:一.对于IE9+.Chrome.Firefox.Opera 以及 Safari: • window.innerH ...

  4. asp Eval()函数的一些使用总结

    一.函数的原型: Eval(string s); s可以是变量,表达式,语句: 二.使用: 1.s为变量时,返回该变量的值,如:string s = "sss";Eval(s);/ ...

  5. unity针对iphone的屏幕旋转

    屏幕旋转可以在引擎里设置: 依次点开 Edit——Project Setting——Player 即可设置如图: 接下来的是 雨松大神的 代码控制,本屌是安卓机器,没能测试. C# using Uni ...

  6. C# 程序打包

    1:新建安装部署项目打开VS,点击新建项目,选择:其他项目类型->安装与部署->安装项目,然后点击确定.(详细见下图) 此主题相关图片如下: 2:开始打包2.1 确定即可进入项目文件夹:双 ...

  7. c++11 auto

    auto 关键字指示编译器使用已声明变量的初始化表达式或 lambda 表达式参数来推导其类型. 在大多情况下,建议您使用 auto 关键字(除非您确实需要转换),因为此关键字可提供以下好处: 可靠性 ...

  8. 交叉编译安装ARM平台上的Qt

    一.宿主机环境搭建: 编译需要x11库的支持,在Ubuntu下安装命令: sudo apt-get install libx11-dev libxext-dev libxtst-dev 二.下载源码包 ...

  9. Sql server统计查询语句消耗时间

    1. set statistics time on go  xxxx go set statistics time off 2. DECLARE @begin dateTime DECLARE @en ...

  10. 如何从数据库(实体提供者)读取安全用户(转自http://wiki.jikexueyuan.com/project/symfony-cookbook/entity-provider.html)

    Symfony 的安全系统可以通过活动目录或开放授权服务器像数据库一样从任何地方加载安全用户.这篇文章将告诉你如何通过一个 Doctrine entity 从数据库加载用户信息. 前言 在开始之前,您 ...