简述AOP

AOP(Aspect-OrientedProgramming,面向方面编程),可以说是OOP(Object-Oriented Programing,面向对象编程)的补充和完善。OOP引入封装、继承和多态性等概念来建立一种对象层次结构,用以模拟公共行为的一个集合。当我们需要为分散的对象引入公共行为的时候,OOP则显得无能为力。也就是说,OOP允许你定义从上到下的关系,但并不适合定义从左到右的关系。例如日志功能。日志代码往往水平地散布在所有对象层次中,而与它所散布到的对象的核心功能毫无关系。对于其他类型的代码,如安全性、异常处理和透明的持续性也是如此。这种散布在各处的无关的代码被称为横切(cross-cutting)代码,在OOP设计中,它导致了大量代码的重复,而不利于各个模块的重用。而AOP技术则恰恰相反,它利用一种称为“横切”的技术,剖解开封装的对象内部,并将那些影响了多个类的公共行为封装到一个可重用模块,并将其名为“Aspect”,即切面。所谓“切面”,简单地说,就是将那些与业务无关,却为业务模块所共同调用的逻辑或责任封装起来,便于减少系统的重复代码,降低模块间的耦合度,并有利于未来的可操作性和可维护性。

使用“横切”技术,AOP把软件系统分为两个部分:核心关注点和横切关注点。业务处理的主要流程是核心关注点,与之关系不大的部分是横切关注点。横切关注点的一个特点是,他们经常发生在核心关注点的多处,而各处都基本相似。比如权限认证、日志、事务处理。Aop 的作用在于分离系统中的各种关注点,将核心关注点和横切关注点分离开来。正如Avanade公司的高级方案构架师Adam Magee所说,AOP的核心思想就是“将应用程序中的商业逻辑同对其提供支持的通用服务进行分离。”

AOP相关概念

        切面(aspect):用来切插业务方法的类。

连接点(joinpoint):是切面类和业务类的连接点,其实就是封装了业务方法的一些基本属性,作为通知的参数来解析。

通知(advice):在切面类中,声明对业务方法做额外处理的方法。

切入点(pointcut):业务类中指定的方法,作为切面切入的点。其实就是指定某个方法作为切面切的地方。

目标对象(target object):被代理对象。

AOP代理(aop proxy):代理对象。

通知:

前置通知(before advice):在切入点之前执行。

后置通知(after returning advice):在切入点执行完成后,执行通知。

环绕通知(around advice):包围切入点,调用方法前后完成自定义行为。

异常通知(after throwing advice):在切入点抛出异常后,执行通知。

Weave(织入):指将aspects应用到target对象并导致proxy对象创建的过程称为织入.

PS:织入是关键,通过织入语法,产生proxy对象,如果类有接口就通过JDK创建代理对象,如果类没有接口则使用cglib创建代理对象。因为电脑JDK的版本,我使用的是Spring4.0。但因为我只学习了Spring3.2,所以我是拿着Spring4.0写着Spring3.2的代码。另外因为我们可能要经常修改服务的需求,例如测一下代码运行时间,所以使用XML的方式来实现AOP比注解的方式更好(毕竟如果我们没有源码,使用注解的方式不能在进行修改服务)。

示例:

配置文件:

 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?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: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-4.0.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context-4.0.xsd
       http://www.springframework.org/schema/aop
       http://www.springframework.org/schema/aop/spring-aop-4.0.xsd" >
     <context:component-scan base-package="net.zmcheng"/>
     <bean id=" logInterceptor" class="net.zmcheng.aop.LogInterceptor"/>
     <aop:config>
          <aop:pointcut expression="execution(public * net.zmcheng.serviceImpl.UserServiceImpl.add())"  id="servicePointCut"/>
          <aop:aspect id="logAspect"  ref=" logInterceptor">
             <aop:before method="before" pointcut-ref="servicePointCut"/>
             <aop:around method="aroundMethod" pointcut-ref="servicePointCut"/>
          </aop:aspect>
     </aop:config>
  
</beans>

需要使用的jar包:

切面类:

 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package net.zmcheng.aop;
 
import org.aspectj.lang.ProceedingJoinPoint;
 
public class LogInterceptor {
 
public void myMethod(){};
 
    public void before(){
     System.out.println("method start");
    }
 
    public void aroundMethod(ProceedingJoinPoint pjp){
     System.out.println("around start");
     try {
pjp.proceed();
} catch (Throwable e) {
e.printStackTrace();
}    
     System.out.println("around end");
    }
    
}

服务层:

 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
package net.zmcheng.service;
 
public interface UserService {
   public void add();
}
 
package net.zmcheng.serviceImpl;
import javax.annotation.Resource;
import org.springframework.stereotype.Component;
import net.zmcheng.dao.UserDao;
import net.zmcheng.service.UserService;
@Component
public class UserServiceImpl implements UserService {
 
private UserDao userDao;
public UserDao getUserDao() {
return userDao;
}
  @Resource
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
public void add() {
userDao.add();
}
 
}

DAO层:

 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package net.zmcheng.dao;
 
public interface UserDao {
  public void add();
}
package net.zmcheng.daoImpl;
 
import org.springframework.stereotype.Component;
 
import net.zmcheng.dao.UserDao;
@Component
public class UserDaoImpl implements UserDao {
public void add(){
   System.out.println("添加员工成功");
   }
}

测试类:

 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package net.zmcheng.demo.test;
 
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
 
import net.zmcheng.service.UserService;
import net.zmcheng.serviceImpl.UserServiceImpl;
 
public class SpringTest {
@Test
public void T() {
ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
UserService us = (UserService)ctx.getBean("userServiceImpl");
us.add();
}
}

执行结果:
method start
around start
添加员工成功
around end

Spring第十篇—举例实现AOP的更多相关文章

  1. 白话Spring(基础篇)---AOP(execution表达式)

    作为AOP的最后一节内容,我们来简单总结一下切面表达式上见的书写方法.下面的那内容有参考其他博文,在此先对开源博客的各位大神表示感谢! -------------------------------- ...

  2. 白话Spring(基础篇)---AOP(execution表达式)(转)

    [一知半解,就是给自己挖坑] 作为AOP的最后一节内容,我们来简单总结一下切面表达式上见的书写方法.下面的那内容有参考其他博文,在此先对开源博客的各位大神表示感谢! ----------------- ...

  3. Spring第六篇【Spring AOP模块】

    前言 Spring的第五篇也算是AOP编程的开山篇了,主要讲解了代理模式-..本博文主要讲解Spring的AOP模块:注解方式和XML方式实现AOP编程.切入点表达式.. AOP的概述 Aop: as ...

  4. Spring(十九):Spring AOP(三):切面的优先级、重复使用切入点表达式

    背景: 1)指定切面优先级示例:有的时候需要对一个方法指定多个切面,而这多个切面有时又需要按照不同顺序执行,因此,切面执行优先级别指定功能就变得很实用. 2)重复使用切入点表达式:上一篇文章中,定义前 ...

  5. Spring第六篇---AOP

    接着Spring第五篇讲 我们今天将叙述以下几个知识点 1 什么是AOP AOP 是一种思想  横向重复  纵向抽取 在软件业,AOP为Aspect Oriented Programming的缩写,意 ...

  6. Spring Cloud第十篇 | 分布式配置中心Config

    ​ 本文是Spring Cloud专栏的第十篇文章,了解前九篇文章内容有助于更好的理解本文: Spring Cloud第一篇 | Spring Cloud前言及其常用组件介绍概览 Spring Clo ...

  7. Spring cloud系列教程第十篇- Spring cloud整合Eureka总结篇

    Spring cloud系列教程第十篇- Spring cloud整合Eureka总结篇 本文主要内容: 1:spring cloud整合Eureka总结 本文是由凯哥(凯哥Java:kagejava ...

  8. Java框架spring 学习笔记(十二):aop实例操作

    使用aop需要在网上下载两个jar包: aopalliance.jar aspectjweaver.jar 为idea添加jar包,快捷键ctrl+shift+alt+s,打开添加jar包的对话框,将 ...

  9. Spring 学习十五 AOP

    http://www.hongyanliren.com/2014m12/22797.html 1: 通知(advice): 就是你想要的功能,也就是安全.事物.日子等.先定义好,在想用的地方用一下.包 ...

随机推荐

  1. bundle的理解笔记

    Bundle是一个键值对这样一个东西.就是一个string类型的东西,对应任何类型的东西.就是用来存值的. 这里可以看到他的作用 public void onClick(View v) { Strin ...

  2. Shtml妙用

    shtml用的是SSI指令, SSI指令虽然不多 但是功能相对而言还是很强大的, 在PHP禁止了命令执行函数和开了安全模式的时候可以试试看 也可以在服务器允许上传shtml后缀脚本的时候试试 PS:只 ...

  3. android之打开网页

    首先改写strings.xml文件 代码如下: <resources> <string name="app_name">Intent应用</strin ...

  4. php函数描述及例子

    /** * xml2array() will convert the given XML text to an array in the XML structure. * Link: http://w ...

  5. 9. Add the Block Storage service

    Block Storage Server: 1. sudo apt-get install python-mysqldb   2. sudo apt-get install lvm2   3. 创建存 ...

  6. angJs使选中的li背景颜色不同

    <!doctype html><html><head><meta charset="UTF-8"><title>test ...

  7. JAVA架构师要求

    JAVA架构师要求专业素质要求:1.理解架构师的职责和架构设计的目标.原则及取舍:2.精通架构模式,Transaction.Security.Persistence等机制及实现,IOC.AOP.SOA ...

  8. POJ 1062 dij

    一道读题读的不明所以的题... 每个人只能接受和自己等级差距不超过m的人进行交易 包括间接交易 所以我们可以枚举每一个长度为m的围绕着酋长的等级区间 每次都对这个等级区间内的人进行操作 求dis[1] ...

  9. MySQL 创建用户 与 授权

    例,需要给 121.52.215.100 连接添加一个用户 dee,密码是 123456,他只能对数据库 vshop 有 select 权限: CREATE USER '; GRANT SELECT ...

  10. PHP 设计模式 笔记与总结(5)PHP 魔术方法的使用

    PHP 魔术方法的使用 ① __get/__set:将对象的属性进行接管 当访问一个不存在的对象属性时: index.php <?php define('BASEDIR',__DIR__); / ...