Spring AOP的案例

屌丝的时间总是有那么多。

无聊等球赛中,不知道尽头的巴西会如何拾取被德国摧残的尊严。突然想起teamleader周5的时候让我给现在刚上线的一个项目中加入一个切面,以便统一输出一些日志。之所以会有这个想法,是因为在周5的早上我跟teamleader提交了一个关于项目中缺少业务日志问题产生的。至于为什么会有这个问题,我不得不吐槽下我现在的团队兄弟们,算了,还是言归正传,说说我刚才写的一个AOP案例吧。

因为初衷只是为了给代码中加入一些日志,而我后来想到顺便加上一个对service层的方法执行时间的统计。对于这个,衍生出一个线程安全问题,统计时间意味着在Before需要有一个变量去接收起始时间,在After时获得之前的变量值进行计算并输出。这样一来之前的变量在并发情况下,后来的访问的起始时间将会覆盖这个变量值,想到ThreadLocal,泛型Long。由此解决线程安全问题。

关于ThreadLocal,请自行google。

切面类

package com.eric.aop.aspect;

import java.lang.reflect.Method;
import java.text.MessageFormat;

import org.springframework.aop.AfterReturningAdvice;
import org.springframework.aop.MethodBeforeAdvice;
import org.springframework.aop.ThrowsAdvice;

public class MyAspect implements MethodBeforeAdvice, AfterReturningAdvice,
		ThrowsAdvice {
	private ThreadLocal<Long> tl=new ThreadLocal<Long>();

	public void before(Method method, Object[] objArr, Object target)
			throws Throwable {
		// 获得当前时间,set到ThreadLocal中
		tl.set(System.currentTimeMillis());
	}

	public void afterReturning(Object obj, Method method, Object[] objArr,
			Object target) throws Throwable {
		// 从ThreadLocal中get值并进行计算
		long runTime=System.currentTimeMillis()-tl.get();
		System.out.println(MessageFormat.format("{0}>>>本次耗时>>>{1}ms", 
				Thread.currentThread().getName(),runTime));
	}
	public void afterThrowing(Method method, Object[] objArr, Object target,
			Exception ex) throws Throwable {
		System.out.println("err>>>"+ex);
	}
}

业务接口类

package com.eric.aop.service;

public interface VOService {
        public void print();
}

业务实现类

package com.eric.aop.service.imp;

import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;

import com.eric.aop.service.VOService;

@Service("vOService")
@Scope("prototype")
public class VOServiceImpl implements VOService {

	public void print() {
		System.out.println("我是VO");
		try {
			Thread.sleep(new Random().nextInt(10000));
			// Object obj=null;
			// obj.toString();
		} catch (InterruptedException e) {
		}
	}

}

Spring配置

<?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"  
    xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context"  
    xsi:schemaLocation="http://www.springframework.org/schema/beans     
    http://www.springframework.org/schema/beans/spring-beans-2.5.xsd     
    http://www.springframework.org/schema/context     
    http://www.springframework.org/schema/context/spring-context-2.5.xsd  
    http://www.springframework.org/schema/tx  
    http://www.springframework.org/schema/tx/spring-tx-2.5.xsd  
    http://www.springframework.org/schema/aop  
    http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">  
  
    <context:annotation-config />  
    <!-- 扫描com.eric 下所有的包-->  
    <context:component-scan base-package="com.eric" />  
  
    <bean id="testAdvice" class="com.eric.aop.aspect.MyAspect" />  
    <aop:config>  
       <aop:advisor pointcut="execution(* com.eric.aop.*.*Service.*(..))"  
            advice-ref="testAdvice" />  
    </aop:config>  
</beans>

测试类

package com.eric.aop.test;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.eric.aop.service.VOService;

public class AopTest {
	public static void main(String[] args) throws InterruptedException {
		ApplicationContext ac = new ClassPathXmlApplicationContext(
				"applicationContext.xml");
		int t = 9;
		for (int i = 0; i < t; i++) {
			new Thread(new ThreadTest(ac)).start();
		}
	}
}
class ThreadTest implements Runnable {
	private ApplicationContext ac;

	public ThreadTest(ApplicationContext ac) {
		this.ac = ac;
	}
	public void run() {
		VOService vo = (VOService) ac.getBean("vOService");
		vo.print();
	}
}

输出结果

我是VO
我是VO
我是VO
我是VO
我是VO
我是VO
我是VO
我是VO
我是VO
Thread-7>>>本次耗时>>>292ms
Thread-2>>>本次耗时>>>1,387ms
Thread-5>>>本次耗时>>>1,707ms
Thread-1>>>本次耗时>>>2,686ms
Thread-9>>>本次耗时>>>4,874ms
Thread-3>>>本次耗时>>>5,173ms
Thread-6>>>本次耗时>>>6,033ms
Thread-8>>>本次耗时>>>9,379ms
Thread-4>>>本次耗时>>>9,740ms

Spring AOP的案例

时间: 2024-10-27 06:12:35

Spring AOP的案例的相关文章

关于 Spring AOP (AspectJ) 你该知晓的一切

[版权申明]未经博主同意,谢绝转载!(请尊重原创,博主保留追究权) http://blog.csdn.net/javazejian/article/details/54629058 出自[zejian的博客] 关联文章: 关于Spring IOC (DI-依赖注入)你需要知道的一切 关于 Spring AOP (AspectJ) 你该知晓的一切 本篇是年后第一篇博文,由于博主用了不少时间在构思这篇博文,加上最近比较忙,所以这篇文件写得比较久,也分了不同的时间段在写,已尽最大能力去连贯博文中的内容

关于 Spring AOP (AspectJ) 该知晓的一切

关联文章: 关于Spring IOC (DI-依赖注入)你需要知道的一切 关于 Spring AOP (AspectJ) 你该知晓的一切 本篇是年后第一篇博文,由于博主用了不少时间在构思这篇博文,加上最近比较忙,所以这篇文件写得比较久,也分了不同的时间段在写,已尽最大能力去连贯博文中的内容,尽力呈现出简单易懂的文字含义,如文中有错误请留言,谢谢. OOP的新生机 OOP新生机前夕 神一样的AspectJ-AOP的领跑者 AspectJ的织入方式及其原理概要 基于Aspect Spring AOP

161920、使用Spring AOP实现MySQL数据库读写分离案例分析

一.前言 分布式环境下数据库的读写分离策略是解决数据库读写性能瓶颈的一个关键解决方案,更是最大限度了提高了应用中读取 (Read)数据的速度和并发量. 在进行数据库读写分离的时候,我们首先要进行数据库的主从配置,最简单的是一台Master和一台Slave(大型网站系统的话,当然会很复杂,这里只是分析了最简单的情况).通过主从配置主从数据库保持了相同的数据,我们在进行读操作的时候访问从数据库Slave,在进行写操作的时候访问主数据库Master.这样的话就减轻了一台服务器的压力. 在进行读写分离案

使用Spring AOP实现MySQL数据库读写分离案例分析

一.前言 分布式环境下数据库的读写分离策略是解决数据库读写性能瓶颈的一个关键解决方案,更是最大限度了提高了应用中读取 (Read)数据的速度和并发量. 在进行数据库读写分离的时候,我们首先要进行数据库的主从配置,最简单的是一台Master和一台Slave(大型网站系统的话,当然会很复杂,这里只是分析了最简单的情况).通过主从配置主从数据库保持了相同的数据,我们在进行读操作的时候访问从数据库Slave,在进行写操作的时候访问主数据库Master.这样的话就减轻了一台服务器的压力. 在进行读写分离案

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

前言:前面已经有两篇文章讲了Spring IOC/DI 以及 使用xml和注解两种方法开发的案例, 下面就来梳理一下Spring的另一核心AOP. 一, 什么是AOP 在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术.AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型.利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务

spring Aop 注解

个人理解: spring Aop 是什么:面向切面编程,类似于自定义拦截操作,支持拦截之前操作@Before,拦截之后操作@After,拦截环绕操作@Around. 什么情况下使用spring Aop:举例如下 当需要统计某些方法 or 指定xx开头的方法名 or 指定xx结尾的方法名 or 某些类下的方法 or 某些包下的方法 or 所有的方法的耗时统计或添加日志信息时,使用spring Aop 切面编程可以不用修改任何需要统计或添加日志的方法,只需很少一部分代码实现需要做的操作. 某交易系统

Spring Aop的理解和简单实现

1.AOP概念 所说的面向切面编程其实就是在处理一系列业务逻辑的时候这一系列动作看成一个动作集合.比如连接数据库来说: 加载驱动-----获取class--------获取连接对象-------访问数据库------查询---------操作结果 对于上面的这一系列动作我们把其中的虚线看成是一个个的切面.然后我们在虚线的位置上加入一些逻辑.哪怕是日志,这也就成就了在不知不觉中将逻辑处理加入到了相应的位置上.而形成了所谓的面向切面编程! 下面通过@Before演示Aop织入到方法之前执行一些逻辑

Spring AOP潜入易懂的讲解

为什么会有面向切面编程(AOP),我们知道Java是一个面向对象(OOP)的语言,但它有一些弊端,比如当我们需要为多个不具有继承关系的对象引入一个公共行为,例如日志,权限验证,事务等功能时,只能在每个对象里引用公共行为,这样做不便于维护,而且有大量重复代码.AOP的出现弥补了OOP的这点不足. 为了阐述清楚Spring AOP,我们从将以下方面进行讨论: 1.代理模式. 2.静态代理原理及实践. 3.动态代理原理及实践. 4.Spring AOP原理及实战. 1.代理模式 代理模式:为其他对象提

【转】Spring AOP 实现原理与 CGLIB 应用

AOP(Aspect Orient Programming),作为面向对象编程的一种补充,广泛应用于处理一些具有横切性质的系统级服务,如事务管理.安全检查.缓存.对象池管理等.AOP 实现的关键就在于 AOP 框架自动创建的 AOP 代理,AOP 代理则可分为静态代理和动态代理两大类,其中静态代理是指使用 AOP 框架提供的命令进行编译,从而在编译阶段就可生成 AOP 代理类,因此也称为编译时增强:而动态代理则在运行时借助于 JDK 动态代理.CGLIB 等在内存中"临时"生成 AOP