原文链接:http://www.orlion.ga/205/

一、AOP简介

1、AOP概念

参考文章:http://www.orlion.ml/57

2、AOP的产生

对于如下方法:

    public class UserDAOImpl implements UserDAO{
    
     public void saveUser(User user){
     doSaveUser();
     }
    }

想在saveUser方法中执行保存用户之前和之后记录当前时间以求出saveUser花费了多少时间,方法有很多种,最直观的写法就是在doSaveUser()前后加代码取出当前时间:

    public class UserDAOImpl implements UserDAO{
    
     public void saveUser(User user){
     int beginTime = getCurrentTime();
    
     doSaveUser();
    
     int endTime = getCurrentTime();
     }
    }

还有一种方法就是重新写一个类继承自UserDAOImpl然后重写saveUser方法,如下:

    public class UserDAOImpl2 extends UserDAOImpl{
        @Override
public void saveUser(User user){
int beginTime = getCurrentTime(); super.saveUser(); int endTime = getCurrentTime();
}
    }

这种方法耦合性太强,一旦父类改变了子类也会改变,慎用继承

再有一种方法就是在调用saveUser()方法时加代码:

    public class UserService{
        
public void saveUser(User user){
        UserDAOImpl userDao = new UserDAOImpl();
int beginTime = getCurrentTime(); userDao.saveUser(); int endTime = getCurrentTime();
}
    }

现在如果让我们将项目中所有的对数据库进行CRUD操作的方法都加上获取时间的代码,显然工作量太大,这时候就用动态代理: (可参考http://www.orlion.ml/207/)

UserDAOImpl.java

    package ml.orlion.dao.impl;
    
    import ml.orlion.dao.UserDAO;
    import ml.orlion.model.User;
    
    public class UserDAOImpl implements UserDAO{
    
     public void saveUser(User user){
     System.out.println("save usering");
     }
    }

TimeInterceptor.java

    package ml.orlion.aop;
    
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    
    public class TimeInterceptor implements InvocationHandler{
    
     private Object target;// 被代理的对象
    
     public Object getTarget() {
     return target;
     }
     public void setTarget(Object target) {
     this.target = target;
     }
     public void beforeMethod(Method m){
     System.out.println(m.getName() + "begin start");
     }
     @Override
     public Object invoke(Object proxy, Method m, Object[] args) throws Throwable {
    
     this.beforeMethod(m);// 插入方法
     m.invoke(target, args);
     return null;
     }
    }

测试

    public static void testProxy(){
// 首先产生一个被代理对象
UserDAO userDao = new UserDAOImpl();
// 下一步将被代理对象交给InvocationHandler即TimeInterceptor
TimeInterceptor ti = new TimeInterceptor();
// 设置被代理对象
ti.setTarget(userDao);
// 根据被代理对象产生一个代理
UserDAO userProxy = (UserDAO)Proxy.newProxyInstance(UserDAO.class.getClassLoader(), new Class[]{UserDAO.class}, ti);
userProxy.saveUser(new User());
    }

运行可以看到控制台打印:saveUserbegin start      save usering

二、使用Spring AOP

UserDAO.java:

package ml.orlion.dao;

import ml.orlion.model.User;

public interface UserDAO {
public void saveUser(User user);
}

UserDAOImpl.java:

package ml.orlion.dao.impl;

import ml.orlion.dao.UserDAO;
import ml.orlion.model.User; public class UserDAOImpl implements UserDAO{ public void saveUser(User user){
System.out.println("save usering");
}
}

UserService.java

package ml.orlion.service;

import ml.orlion.dao.UserDAO;
import ml.orlion.dao.impl.UserDAOImpl;
import ml.orlion.model.User; public class UserService { private UserDAO userDAO = new UserDAOImpl(); public UserDAO getUserDao() { return userDAO;
} public void setUserDao(UserDAO userDAO) {
this.userDAO = userDAO;
} public void saveUser(User user){
this.userDAO.saveUser(user);
}
}

LogInterceptor.java

package ml.orlion.aop;

public class LogInterceptor {

	public void before(){
System.out.println("before");
}
}

beans.xml:

<?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:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans.xsd
           http://www.springframework.org/schema/aop
           http://www.springframework.org/schema/aop/spring-aop.xsd"> <bean id="logInterceptor" class="ml.orlion.aop.LogInterceptor">
</bean>
   <bean id="userDao" class="ml.orlion.dao.impl.UserDAOImpl">
 
   </bean>
   <bean id="userService" class="ml.orlion.service.UserService">
   <property name="userDao" ref="userDao"/>
   </bean>
   <aop:config>
   <aop:pointcut expression="execution(public * ml.orlion.service..*.add(..))"
   id="servicePointcut" />
   <aop:aspect id="logAspect" ref="logInterceptor">
   <aop:before method="before" pointcut-ref="servicePointcut"/>
   </aop:aspect>
   </aop:config>
</beans>

测试:

BeanFactory appContext = new ClassPathXmlApplicationContext("beans.xml");
UserService userService = (UserService) appContext.getBean("userService");
userService.saveUser(new User());

Spring(三)AOP面向切面编程的更多相关文章

  1. Spring 08: AOP面向切面编程 + 手写AOP框架

    核心解读 AOP:Aspect Oriented Programming,面向切面编程 核心1:将公共的,通用的,重复的代码单独开发,在需要时反织回去 核心2:面向接口编程,即设置接口类型的变量,传入 ...

  2. Spring:AOP面向切面编程

    AOP主要实现的目的是针对业务处理过程中的切面进行提取,它所面对的是处理过程中的某个步骤或阶段,以获得逻辑过程中各部分之间低耦合性的隔离效果. AOP是软件开发思想阶段性的产物,我们比较熟悉面向过程O ...

  3. spring框架学习(三)——AOP( 面向切面编程)

    AOP 即 Aspect Oriented Program 面向切面编程 首先,在面向切面编程的思想里面,把功能分为核心业务功能,和周边功能. 所谓的核心业务,比如登陆,增加数据,删除数据都叫核心业务 ...

  4. Spring框架 AOP面向切面编程(转)

    一.前言 在以前的项目中,很少去关注spring aop的具体实现与理论,只是简单了解了一下什么是aop具体怎么用,看到了一篇博文写得还不错,就转载来学习一下,博文地址:http://www.cnbl ...

  5. spring:AOP面向切面编程02

    参考: https://blog.csdn.net/jeffleo/article/details/54136904 一.AOP的核心概念AOP(Aspect Oriented Programming ...

  6. Spring的AOP面向切面编程

    什么是AOP? 1.AOP概念介绍 所谓AOP,即Aspect orientied program,就是面向方面(切面)的编程. 功能: 让关注点代码与业务代码分离! 关注点: 重复代码就叫做关注点: ...

  7. Spring注解 - AOP 面向切面编程

    基本概念: AOP:Aspect Oriented Programming,即面向切面编程 指在程序运行期间动态的将某段代码切入到指定方法指定位置进行运行的编程方式 前置通知(@Before):在目标 ...

  8. Spring框架——AOP面向切面编程

    简介 AOP练习 使用动态代理解决问题 Spring AOP 用AspectJ注解声明切面 前置后置通知 利用方法签名编写AspectJ切入点表达式 指定切面的优先级 基于XML的配置声明切面 Spr ...

  9. Spring之AOP(面向切面编程)_入门Demo

    AOP是OOP的延续,是Aspect Oriented Programming的缩写,意思是面向切面编程.AOP实际是GoF设计模式的延续,设计模式孜孜不倦追求的是调用者和被调用者之间的解耦,AOP可 ...

随机推荐

  1. CI框架之HOOKS使用流程及原理

        Ci框架中Hooks可以理解:在框架的执行流程过程中,允许开发者在固定的某些时间点上(如:调用控制器前,调用控制器后等时间点上),调用其他函数来扩充CI框架执行流程的一种方法.技术上来就是通过 ...

  2. xcode 一般插件

    插件编写 xcode的插件不算多,找遍了网络也就大猫小猫而三只.不过虽然不多,但是大部分的插件都非常有用.以下5歀插件是我几台机器上都安装了并且经常使用的. 1. MiniXcode MiniXcod ...

  3. Xml 建议优先使用属性

    要点:建议优先选用属性的方式记录数据,除非还需要包容层级式的数据. 优点: 1. 可以完全覆盖关系型数据库的数据格式设计,利于交换. 2. 占用空间小.相当于 JSON 格式,不再有大量重复的节点名后 ...

  4. 基于shell脚本比较数字加减乘除

    让用户输入两个数来比较他们的大小 先用touch命令新建一个2.sh文件 在用vi进入i进入编辑状态 输入 保存后检查

  5. PHP图形操作之生成图像验证码

    简单的验证码其实就是在图片中输出了几个字符,通过imagestring函数就能实现. 但是在处理上,为了使验证码更加的安全,防止其他程序自动识别,因此常常需要对验证码进行一些干扰处理,通常会采用绘制一 ...

  6. tomcat在linux下自启动

    Linux下设置tomcat开机自启动  一.以root用户登录系统: 二.进入init.d文件夹 cd /etc/init.d/ 三.创建并打开tomcat文件 vi tomcat 四.tomcat ...

  7. RecyclerView的介绍与使用

    一.什么是RecyclerView 新的视图控件,是Android-support-v7-21版本中新增的一个Widgets,官方对于它的介绍则是:RecyclerView是ListView的升级版本 ...

  8. -[NSNull countByEnumeratingWithState:objects:count:]:

    当数组为空时遍历数组容易出这样的问题, -[NSNull countByEnumeratingWithState:objects:count:]: unrecognized selector sent ...

  9. xml中DTD解析

    DTD的作用是"文档类型的定义" DTD申明始终以<!DOCTYPE开头(开头后空一格). 本标签一共有三种写法 一.内部DTD: <!DOCTYPE 根元素 [ 文档 ...

  10. 八大排序算法Java

    目录(?)[-] 概述 插入排序直接插入排序Straight Insertion Sort 插入排序希尔排序Shells Sort 选择排序简单选择排序Simple Selection Sort 选择 ...