原文链接: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. js学习笔记

    javacript笔记根据EC5.0一共有六种数据类型:number,string,bool undefine,nullobject(广义的) --->object(狭义的),array,fun ...

  2. JS中检测数据类型的几种方式及优缺点【转】

    1.typeof 用来检测数据类型的运算符 typeof value 返回值首先是一个字符串,其次里面包含了对应的数据类型,例如:"number"."string&quo ...

  3. Golang之chan/goroutine(转)

    原文地址:http://tchen.me/posts/2014-01-27-golang-chatroom.html?utm_source=tuicool&utm_medium=referra ...

  4. 安装windows服务批处理代码

    批处理是DOS时代比较常用的方法之一,目前来说也是一种高效的方法,复制代码到文本文件中,保存并修改文件扩展名为“*.bat”. 安装windows服务批处理代码如下: @echo off set fi ...

  5. (转)win7 64 安装mysql-python:_mysql.c(42) : fatal error C1083: Cannot open include file: 'config-win.h': No such file or directory

    原文地址:http://www.cnblogs.com/fnng/p/4115607.html 作者:虫师 今天想在在win7 64位环境下使用python 操作mysql 在安装MySQL-pyth ...

  6. thrift 服务端linux C ++ 与客户端 windows python 环境配置(thrift 自带tutorial为例)

    关于Thrift文档化的确是做的不好.摸索了很久才终于把跨linux与windows跨C++与python语言的配置成功完成.以下是步骤: 1)                 Linux下环境配置 ...

  7. Python之路【第四篇】python基础 之基本数据类型之集合

    基本数据类型之集合 set set集合,是一个无序且不重复的元素集合 # set 不允许重复的集合 set允许重复的列表但是集合是无序的 #例如 # s = {1,23,23,4,55,55} # p ...

  8. 关于 iframe 在ie11 height:100% 无效的巨坑

    好的,今天公司分配了个解决ie中的bug的任务,其中,有一个就是iframe 的高度 100% 没有生效的问题: 一开始,由于我真的没有怎么去了解过iframe这个货,所以,网上各种搜索一大堆关于这货 ...

  9. Ibatis 使用心得

    (1)建表语句 sqlMap: <statement id="createTable" parameterClass="String" > $sql ...

  10. css 清除浮动 clear

    .clearfix{ zoom:1;/*对于老版本的IE进行兼容的设置*/ } .clearfix:after{ content:""; display:block; visibi ...