一、Srping AOP

  AOP(Aspect Oriented Programming)解释为面向切面编程,何为切面,用刀把一块面包切成两半,刀切下去形成的面就叫切面,那么面向切面的就是形成切面的这把,刀切在哪(切入点),怎么切(通知),切成什么样(通知实现方法),切的过程就是切面织入的过程。这种编程方式主要为了分离关注点并且能够增强类的辅助功能。比如做日志管理,权限控制等工作,在特定的时候和位置做特定的事情,而无需在原来方法中做特殊处理。

  AOP概念:

      • 切面:多个对象或方法要实现的交叉功能的集合。
      • 连接点:被关注的方法,执行了该方法会触发通知。
      • 切入点:一系列连接点的集合。
      • 通知:切面的实际实现,在连接点方法被执行的时候在适当的地方插入通知。
        1. before:前置通知,在方法被调用之前调用
        2. after:后置通知,在方法执行结束之后调用,无论方法是否执行成功
        3. around:环绕通知,在目标方法执行前和执行结束之后分别执行自定义方法
        4. after-return:在方法成功执行之后调用,
        5. after-throwing:在方法抛出异常后调用
      • 目标对象:被通知的对象,可以是自己的编写的类也可以是,第三方类对象。(连接点就是目标对象中的某些方法)
      • 代理:将通知应用到目标对象后创建的对象。
      • 织入:将切面应用到目标对象从而创建一个新的代理对象的过程。
      • 引入:为类添加新的方法和属性。(<aop:declare-parents ../>)

二、AOP配置范例:

  1.spring中的aop的xml配置方式简单实例

  2.spring中aop的注解实现方式简单实例

  3.利用切面为特定的类添加新功能:

<aop:config>
<!-- 两个切面-->
<aop:aspect ref="company">
<!-- 利用切面为特定的类添加新功能 -->
<aop:declare-parents types-matching="com.springAop.InstanceMine+" <!-- 实现了InstanceMine接口的实现类可以强转成InstanceOtheer类型的对象并使用他的实现类的方法的方法 -->
        implement-interface="com.springAop.InstanceOther"  
default-impl="com.springAop.OtherImpl"/>  <!--InstanceOther的默认实现类,当InstanceMine对象强转成InstanceOther的对象时,默认实现类为OtherImpl-->
</aop:aspect>
</aop:config>

  接口类:instanceMine和instanceOther

public interface InstanceMine {
public void speak1(String meg);
} public interface InstanceOther {
public void speak2(String meg);
}

  接口实现类: OtherImple和MineImpl

public class MineImpl implements instanceMine {

    public void speak1(String meg) {
System.out.println("s1");
}
} public class OtherImpl implements instanceOther {
public void speak2(String meg) {
System.out.println(meg);
}
}

  测试类:Test

public class Test {
@org.junit.jupiter.api.Test
public void TestDemo(){
ApplicationContext app = new FileSystemXmlApplicationContext("src/main/java/com/springAop/bean.xml"); InstanceMine mine = app.getBean("mine",instanceMine.class);
((InstanceOther)mine).speak2("我可以说话吗");//强转成InstanceOther,并调用实现类OtherImpl的实现方法
}
}

  结果:

  

三.以代理对象的方式实现AOP:

  首先理解一下三种代理模式:理解三种代理模式

  1.前置通知:

 /**
* 前置通知:实现MethodBeforeAdvice接口,在目标方法执行之前执行
* 相当于aop配置<aop:before method="before" pointcut-ref="当前类的bean"/>
*/
public class BeforeNotify implements MethodBeforeAdvice { public void before(Method method, Object[] objects, Object o) throws Throwable {
System.out.println("=========== 前置通知 =========");
}
}

  

  2.后置通知:

 /**
* 后置(返回)通知:在方法结束返回时调用,一般包含在环绕通知结束前执行,
* 方法成功执行有效,异常结束则该方法无效。
* 相当于aop配置:<aop:after-returning method="afterReturning" pointcut-ref="当前类的bean"/>
*/
public class AfterNotify implements AfterReturningAdvice {
public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
System.out.println("=========== 后置通知 =========");
}
}

  

  3.环绕通知:

 /**
* 环绕通知:在方法执行前和执行后均可以执行自定义的方法,
* 相当于aop配置:<aop:around method="invoke" pointcut-ref="当前类的Bean"/>
*/
public class AroundNotify implements MethodInterceptor { public Object invoke(MethodInvocation methodInvocation) throws Throwable {
System.out.println("=========== 环绕通知 =========");
Object obj = methodInvocation.proceed();//执行目标方法
System.out.println("=========== 环绕通知 =========");
return obj;
}
}

  

  4.异常通知:

 /**
* 异常通知:在目标方法执行异常时执行,
* 注意:ThrowsAdvice是个空接口,里面未定义任何待实现类
* 相当于aop配置:<aop:after-throwing method="afterThrowing" pointcut-ref="当前类的bean"/>
*/
public class ExceptionNotify implements ThrowsAdvice {
public void afterThrowing(Method method, Object[] args, Object target, Exception ex){
System.out.println("方法:"+method.getName()+"出错了\n原因:"+ex.getMessage());
}
}

  此处的ThrowAdvice接口是没有实现方法的,但是又不允许随便定义,在源码中我们看到了规定的几个方法,因为此接口中,没有任何实现方法,当被利用反射机制调用的时候,必须实现一下方法中的一种,这是源码注释的说明:

  5.bean配置

 <beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!-- 被代理对象 -->
<bean class="com.springAop.proxyAOP.UserDao" id="userDao"/> <!-- 关联通知 -->
<bean class="com.springAop.proxyAOP.BeforeNotify" id="before"/>
<bean class="com.springAop.proxyAOP.AroundNotify" id="aroundNotify"/>
<bean class="com.springAop.proxyAOP.ExceptionNotify" id="exceptionNotify"/>
<bean class="com.springAop.proxyAOP.AfterNotify" id="afterNotify"/> <!-- 代理对象 -->
<bean id="proxyFactoryBean" class="org.springframework.aop.framework.ProxyFactoryBean">
<!-- 代理对象接口,接口方法就是连接点 -->
<property name="proxyInterfaces">
<list>
<!-- 目标对象实现的接口类,实现了那些接口都可以补充进去,接口的方法就是一个个连接点 -->
<value>com.springAop.proxyAOP.IUserDao</value>
<value>com.springAop.proxyAOP.BookDao</value>
</list>
</property> <!-- 关联通知类型 -->
<property name="interceptorNames">
<list>
<value>before</value><!-- 前置通知织入 -->
<value>aroundNotify</value><!-- 环绕通知织入 -->
<value>exceptionNotify</value><!-- 异常通知织入 -->
<value>afterNotify</value><!-- 后置通知织入 -->
</list>
</property> <!-- 关联被代理对象(aop的目标对象) -->
<property name="target" ref="userDao"/>
</bean>
</beans>

  6.目标对象:(实现了两个接口)

 public class UserDao implements IUserDao,BookDao{
public void save() {
System.out.println("保存用户信息中。。。。");
// int i=1/0;
} public void getBook() {
System.out.println("拿到一本书");
}
}

  7.测试类:

 public class Test{
@org.junit.jupiter.api.Test
public void testDemo(){
ApplicationContext app = new FileSystemXmlApplicationContext("file:G:\\DevelopSoftware\\IDEA\\workspace\\springDemo\\src\\main\\java\\com\\springAop\\proxyAOP\\bean.xml");
/**
* 获取的bean是目标对象的代理对象,可以将代理对象强转成任何目标对象实现的接口对象
*/
IUserDao userDao = app.getBean("proxyFactoryBean",IUserDao.class);
userDao.save();
System.out.println("=========================");
/**
* 将代理对象强转成BookDao接口对象,并调用该接口方法。
*/
((BookDao)userDao).getBook();
}
}

  运行结果:

  

Spring AOP梳理的更多相关文章

  1. Spring Aop 梳理

    Aspect Oriented Programming  面向切面编程.解耦是程序员编码开发过程中一直追求的.AOP也是为了解耦所诞生. 具体思想是:定义一个切面,在切面的纵向定义处理方法,处理完成之 ...

  2. [转]彻底征服 Spring AOP 之 理论篇

    基本知识 其实, 接触了这么久的 AOP, 我感觉, AOP 给人难以理解的一个关键点是它的概念比较多, 而且坑爹的是, 这些概念经过了中文翻译后, 变得面目全非, 相同的一个术语, 在不同的翻译下, ...

  3. [Spring框架]Spring AOP基础入门总结一.

    前言:前面已经有两篇文章讲了Spring IOC/DI 以及 使用xml和注解两种方法开发的案例, 下面就来梳理一下Spring的另一核心AOP. 一, 什么是AOP 在软件业,AOP为Aspect ...

  4. 转载:Spring AOP (下)

    昨天记录了Spring AOP学习的一部分(http://www.cnblogs.com/yanbincn/archive/2012/08/13/2635413.html),本来是想一口气梳理完的.但 ...

  5. (转)spring aop(下)

    昨天记录了Spring AOP学习的一部分(http://www.cnblogs.com/yanbincn/archive/2012/08/13/2635413.html),本来是想一口气梳理完的.但 ...

  6. 彻底征服 Spring AOP 之 理论篇

    基本知识 其实, 接触了这么久的 AOP, 我感觉, AOP 给人难以理解的一个关键点是它的概念比较多, 而且坑爹的是, 这些概念经过了中文翻译后, 变得面目全非, 相同的一个术语, 在不同的翻译下, ...

  7. Spring AOP 学习例子

    http://outofmemory.cn/code-snippet/3762/Spring-AOP-learn-example     工作忙,时间紧,不过事情再多,学习是必须的.记得以前的部门老大 ...

  8. Spring AOP 知识点入门

    一.基本知识点 1.AOP概念 AOP(Aspect-Oriented Programming), 即 面向切面编程, 它与 OOP( Object-Oriented Programming, 面向对 ...

  9. Spring AOP概述

    一.AOP的基本概念: 首先先给出一段比较专业的术语: 在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的 ...

随机推荐

  1. JBoss AS7(Application Server 7)的Standalone模式和Domain模式

    JBoss AS7(Application Server 7)支持两种引导模式:standalone和domain(域). Standalone模式对于很多应用,并不需要domain管理能力,JBos ...

  2. ASP.NET根据当前时间获取,本周,本月,本季度等时间段

    DateTime dt = DateTime.Now; //当前时间 DateTime startWeek = dt.AddDays(1 - Convert.ToInt32(dt.DayOfWeek. ...

  3. spring core 与 context理解

    Spring core是核心层,拥有这BeanFactory这个强大的工厂,是所有bean的管理器: 而spring context是上下文运行环境,基于spring core之上的一个架构, 它之上 ...

  4. 傅里叶变换 - Fourier Transform

    傅里叶级数 傅里叶在他的专著<热的解析理论>中提出,任何一个周期函数都可以表示为若干个正弦函数的和,即: \[f(t)=a_0+\sum_{n=1}^{\infty}(a_ncos(n\o ...

  5. ANTD mobile源码分析 -- popover

    最近的开发中要用到很多的各式各样的组件.但是发现ant design mobile(后面简称ANTDM)里很多的资源.于是就分析一下,学习学习. ANTDM直接使用了typescript,没有用ES2 ...

  6. 我博客上的围棋js程序

    作为一个围棋爱好者,就决定在博客里加个围棋js程序.于是,申请了博客的js权限,美化美化我的博客. 好在js的语法像C系的,看了看,写个程序应该还是可以的. 围棋里,设计好基本的数据结构: //a是1 ...

  7. 在Hadoop2.2基础上安装Spark(伪分布式)

    没想到,在我的hadoop2.2.0小集群上上安装传说中的Spark竟然如此顺利,可能是因为和搭建Hadoop时比较像,更多需要学习的地方还是scala编程和RDD机制吧 总之,开个好头 原来的集群: ...

  8. 区块链 PoW 与 PoS 的纷争

    最近在研究区块链,可能会有一些非前端文章,感兴趣的可以关注关注哟. 有关注区块链的,肯定会经常看到这两个名词 -- PoW 与 PoS.但是很多人对他们的含义的理解存在很多偏差.那么他们的含义与区别是 ...

  9. python 常见错误和异常 函数 正则表达式及多线程编程

    生成随机密码#!/usr/bin/env python import stringfrom random import choice def gen_pass(num=9): all_chs = st ...

  10. DM6446的Bootloader

    RBL(ARM ROM Boot Loader)在芯片出厂的时候就已经烧写到ROM里了,这不需要大家关心,上电后,RBL会自动从EMIFA EM_CS2 memory space (0x0200 00 ...