- 浏览: 311249 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
zhou363667565:
看到你的这个配置 有个地方有点问题:
< aop:po ...
spring ibatis 事务配置 -
wo17796452:
[b][/b][i][/i][u][/u]引用[*][img] ...
crowd Jira confluence 集成 -
wo17796452:
<input type="button&quo ...
crowd Jira confluence 集成 -
benbear2008:
这些类图呢?
Spring MVC框架类图与顺序图 -
TTLtry:
谢了 最近学习spring时候 却总是登不上官方网站 很多 ...
Spring 2.5.5 api 帮助文档 chm格式 下载
有时候我们要跟踪方法的执行时间,来观察系统的性能、时间分布。特别是要找出那些十分耗时的操作。如果是在每个方法中起始和结束位置记下时间相减,那是不太现实的,对代码的侵入性太过份,而且在产品环境中又得屏闭那部份代码。 幸好现在有了 AOP,通过配置方式再加上外部辅助代码就能达到我们的要求,正式上线时只需要简单改个配置项拆卸下来即可。 下面介绍三种方式来打印每个方法的执行时间,分别是: 1. Spring 2.0 用 AspectJ 实现 AOP 1. Spring 2.0 用 AspectJ 实现 AOP 这个实例由五个文件构成,两个配置文件和三个类文件。需要在项目中引用 Spring 2.0 以上版本的相关包,还要日志包。 1) log4j.properties 放在 src 目录下 2) applicationContext.xml 放在 src 目录下 3) MethodTimeAdvice.java 记录时间的类 4) HelloService.java 被拦截的业务类 5) Main.java 主程序类 执行 Main 后输出的结果是: Hello Unmi(1) 如果不需要这个功能,只要在 applicationContext.xml 中把 id="methodTimeLog" 和 id="methodTimeAdvice" 配置项注释掉就行了。 2. Spring 通用的方法拦截 Spring 1.x 因为不能用 AspectJ 来对方法进行拦截,要用到 ProxyFactoryBean 使用 AOP,具体操作方法只需要更换以上例子中的 applicationContext.xml 文件就行,内容如下: 上面的配置方式需为每个应用方法执行时间记录的 Bean 在外层包一个 ProxyFactoryBean,原来的 Bean 设为一个 Target 实在时麻烦了。 下面用一种应用自动代理的配置方式,指定 BeanNameAutoProxyCreator 的 beanNames 匹配模式即可,如果写成 <value>*Service,*Manager</value>,逗号分隔开,以 Service 或 Manager 结层类的方法都被拦截,这样方便许多。 3. 直接用 AspectJ 实现 AJDT 安装成功后,你可以新建 AspectJ 项目,或者把前面项目转换成 AspectJ 项目。从项目的上下文菜单中可以看到 AspectJ Tools -> Convert to Aspectj Project。然后在包 com.unmi.util 中新建一个方面,包 com.unmi.util 的上下文菜单中 New -> Aspect,输入名字 MethodTimeAdviceRecipe,然后 Finish,这时就会在包 com.unmi.util 中产生一个文件 MethodTimeAdviceRecipe.aj,内容如下: MethodTimeAdviceRecipe.aj (那么 MethodTimeAdvice.java 就派不上用场了,可删去) 再就是因为无需用到 Spring 了,不需要 IOC 了,相应的 Main.java 的内容如下: Main.java (以前如何创建 HelloService,现在还是怎么做) OK,现在就可以在 Eclipse 中开始运行 Main 类了,对 methodTimeAdviceRecipe.aj 的编译工作由插件 AJDT 自动帮你作了(实质是相匹配的类中插入了代码)。运行 Main 的结果如下: Hello Unmi(1) 用 AspectJ 可以很灵活的定义方面,局限就是对方面的改变须重新编译相关类,而非配置方式。
2. Spring 通用的方法拦截
3. 直接用 AspectJ 实现log4j.rootLogger=DEBUG,stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d [%5p] %c{1}.%M(%L) %n%m%n
<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-2.0.xsd
http://www.spridngframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">
<aop:config>
<!-- Spring 2.0 可以用 AspectJ 的语法定义 Pointcut,这里拦截 service 包中的所有方法 -->
<aop:advisor id="methodTimeLog" advice-ref="methodTimeAdvice" pointcut="execution(* *..service..*(..))"/>
</aop:config>
<bean id="methodTimeAdvice" class="com.unmi.util.MethodTimeAdvice"/>
<bean id="helloService" class="com.unmi.service.HelloService"/>
</beans>
package com.unmi.util;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.time.StopWatch;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* 记录方法的执行时间
* @author Unmi
*/
public class MethodTimeAdvice implements MethodInterceptor {
protected final Log log = LogFactory.getLog(MethodTimeAdvice.class);
/**
* 拦截要执行的目标方法
*/
public Object invoke(MethodInvocation invocation) throws Throwable {
//用 commons-lang 提供的 StopWatch 计时,Spring 也提供了一个 StopWatch
StopWatch clock = new StopWatch();
clock.start(); //计时开始
Object result = invocation.proceed();
clock.stop(); //计时结束
//方法参数类型,转换成简单类型
Class[] params = invocation.getMethod().getParameterTypes();
String[] simpleParams = new String[params.length];
for (int i = 0; i < params.length; i++) {
simpleParams[i] = params[i].getSimpleName();
}
log.debug("Takes:" + clock.getTime() + " ms ["
+ invocation.getThis().getClass().getName() + "."
+ invocation.getMethod().getName() + "("+StringUtils.join(simpleParams,",")+")] ");
return result;
}
}
package com.unmi.service;
/**
* @author Unmi
*/
public class HelloService {
public void sayHello(int id,String name){
try {
Thread.sleep(512);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Hello "+name+"("+id+")");
}
}
package com.unmi;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.unmi.service.HelloService;
/**
* 测试主类
* @author Unmi
*/
public class Main {
/**
* @param args
*/
public static void main(String[] args) {
BeanFactory factory =new ClassPathXmlApplicationContext("applicationContext.xml");
HelloService helloService = (HelloService)factory.getBean("helloService");
helloService.sayHello(1,"Unmi");
}
}
2008-01-18 13:41:25,593 [DEBUG] MethodTimeAdvice.invoke(34)
Takes:516 ms [com.unmi.service.HelloService.sayHello(int,String)]<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<bean id="methodTimeAdvice" class="com.unmi.util.MethodTimeAdvice"/>
<bean id="helloServiceTarget" class="com.unmi.service.HelloService"/>
<bean id="methodTimeAdvisor"
class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
<property name="advice">
<ref bean="methodTimeAdvice"/>
</property>
<!--对指定类的任何方法有效-->
<property name="patterns">
<value>.*.*</value>
</property>
</bean>
<bean id="helloService" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="interceptorNames">
<list>
<value>methodTimeAdvisor</value>
</list>
</property>
<property name="target">
<ref bean="helloServiceTarget"/>
</property>
</bean>
</beans>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<bean id="methodTimeAdvice" class="com.unmi.util.MethodTimeAdvice" />
<bean id="helloService" class="com.unmi.service.HelloService" />
<bean id="methodTimeAdvisor"
class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
<property name="advice">
<ref bean="methodTimeAdvice" />
</property>
<!--对指定类的任何方法有效-->
<property name="patterns">
<value>.*.*</value>
</property>
</bean>
<!-- 根据 Bean 的名字自动实现代理拦截 -->
<bean
class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
<property name="interceptorNames">
<list>
<value>methodTimeAdvisor</value>
</list>
</property>
<property name="beanNames">
<list>
<!-- 添加到其中的 Bean 自动就被代理拦截了 -->
<value>*Service</value>
</list>
</property>
</bean>
</beans>
AspectJ 提供了一套语法来定义切面,Spring 2.0 开始引入了 AspectJ 的部分功能,但如果要用上 AspectJ 更多强大完善的功能,诸如实例构造时,属性被访问时,动态改变类定义,滋生新的属性、方法,更强基于流程的控制时,恐怕非得显式的使用 AspectJ。当然,首先你得去 http://www.eclipse.org/aspectj/ 下载到 AspectJ 或者 AspectJ 的 Eclipse 插件。本人强烈建议使用 AspectJ 的 Eclipse 插件,请下载相应 Eclipse 版本的 AspectJ 插件,Eclipse 3.3 要搭配 AJDT: The AspectJ Development Tools 1.5。不要插件的话就得命令行下 ajc 编译你的方面,不容易习惯的。 package com.unmi.util;
import org.apache.commons.lang.time.StopWatch;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* 记录方法的执行时间
* @author Unmi
*/
public aspect MethodTimeAdviceRecipe {
protected final Log log = LogFactory.getLog(MethodTimeAdvice.class);
//拦截所有以 Service 结尾类的方法
pointcut callServicePointCut() : call(* *..*Service.*(..))
&& !within(MethodTimeAdviceRecipe +);
/**
* 在方连接点(业务类方法)周围执行的通知
*/
Object around() : callServicePointCut(){
//用 commons-lang 提供的 StopWatch 计时,Spring 也提供了一个 StopWatch
StopWatch clock = new StopWatch();
clock.start(); //计时开始
Object result = proceed();
clock.stop(); //计时结束
//显示出方法原型及耗时
log.debug("Takes: " + clock.getTime() + " ms ["+thisJoinPoint.getSignature()+"("+
thisJoinPoint.getSourceLocation().getLine()+")]");
return result;
}
}
package com.unmi;
import com.unmi.service.HelloService;
/**
* 测试主类
* @author Unmi
*/
public class Main {
/**
* @param args
*/
public static void main(String[] args) {
HelloService helloService = new HelloService();
helloService.sayHello(1,"Unmi");
}
}
2008-01-21 13:48:16,171 [DEBUG] MethodTimeAdvice.sayHello_aroundBody1$advice(130)
Takes: 515 ms [void com.unmi.service.HelloService.sayHello(int, String)(16)]
发表评论
-
入门 21 - Controller的单元测试
2011-03-14 08:09 1127现在假设您要设 ... -
Spring MVC框架类图与顺序图
2011-03-14 08:08 4980藉由了解Spring的框架组成,我们可以了解框架之中的类与 ... -
Spring入门19 - ModelAndView类别
2011-03-14 08:07 1351入门 19 - ModelAndView类别 ... -
DispatcherServlet定义档
2011-03-14 08:07 883DispatcherServlet预设使用servlet名 ... -
入门 17 - 第一个Spring MVC Web程序
2011-03-14 08:06 1117进行这个程序之前,请您先完成入门 04 - 第一个Spri ... -
入门 16 - BeanFactoryPostProcessor接口
2011-03-14 08:05 1012撰写Bean定义档通常使用XML来撰写,XML阶层式的组织 ... -
入门 15 - Aware相关接口
2011-03-14 08:05 991Spring中提供一些Aware相关接口,像是BeanFa ... -
入门 14 - 资源文件的取得
2011-03-14 08:04 883首先来看看ApplicationContext接口的实作 ... -
入门 13 - MessageResource接口
2011-03-14 08:03 1124ApplicationContext继承了org.spri ... -
入门 12 - ApplicationContext接口
2011-03-14 08:03 913在Spring中,BeanFactory提供的是个比较API层 ... -
入门 11 - DataSource注入
2011-03-14 08:02 1058对于不同的数据库存取需求,我们使用JDBC来解决这个 ... -
入门 10 - 集合对象注入
2011-03-14 08:01 822对于像数组、java.util.List、java. ... -
入门 09 - 属性参考与自动绑定
2011-03-14 08:00 872在定义Bean时,除了直接指定值给属性值之外,还可以直接参 ... -
入门 08 - 不使用XML定义档
2011-03-14 07:59 849XML档案的阶层格式非常适用于于组态设定,也因此几 ... -
入门 07 - Bean生命周期
2011-03-14 07:59 796在Spring中,从BeanFactory取得的实 ... -
入门 06 - Bean定义档进阶读取
2011-03-14 07:58 873BeanFactory可以接受InputStrea ... -
Constructor注入
2011-03-14 07:57 1052Spring鼓励的是setter injection,但也 ... -
第一个Spring程序
2011-03-14 07:57 878首先我们要先取得Sprin ... -
入门 03 - 依赖注入DI
2011-03-14 07:56 863IoC模式基本上是一个高层的概念,在Martin Fow ... -
控制反转IoC
2011-03-14 07:55 840IoC全名Inversion of Control,如果 ...
相关推荐
在Spring中,我们可以使用AspectJ来实现AOP,AspectJ是一个强大的AOP框架,它可以与Spring无缝集成,提供更细粒度的控制。 首先,让我们了解一下AOP中的通知类型: 1. **前置通知**(Before Advice):在目标方法...
**Spring AOP 概念理解** Spring AOP(Aspect Oriented Programming,面向切面编程)是Spring框架的一个重要组成部分,它允许我们通过...理解和熟练运用Spring AOP及其@AspectJ注解是每个Spring开发者必备的技能之一。
`logBefore`方法会在匹配到的每个方法执行前被调用,打印出即将执行的方法名。 接下来,我们需要在Spring配置文件中启用@AspectJ支持,并注册我们的切面类。在`src/main/resources`下的`applicationContext.xml`或`...
在本案例中,我们将探讨如何使用AspectJ注解来开发Spring AOP。 首先,我们要了解Spring AOP的主要目标是为方法调用提供拦截机制,也就是在方法执行前、后或发生异常时执行特定的操作。这通常被称为通知(advises)...
Spring AOP(面向切面编程)是Spring框架中的一个重要组件,它允许我们在不修改源代码的情况下,通过在程序运行时动态地将代码插入到方法调用中,来实现跨切面的关注点,如日志记录、性能监控、事务管理等。而Spring...
在本文中,我们将深入探讨如何使用Spring AOP(面向切面编程)来记录方法的执行时间,以便评估和优化方法的性能。AOP允许我们在不修改原有代码的情况下,添加额外的功能,如日志记录、安全性检查或性能监控。 首先...
每种类型的的通知都在不同的时间点执行,例如,环绕通知可以在方法调用前后完全控制执行流程。 3. **切点(Pointcut)**:切点是匹配通知应该应用到的方法或类的定义。切点表达式通常基于方法签名、注解或其他条件...
在Spring AOP中,我们无需深入到每个方法的实现细节,而是可以定义“切面”,在合适的时机(如方法调用前、后、异常发生时等)执行特定的逻辑。这样,业务代码和关注点(如日志、事务管理等)得以分离,提高了代码的...
例如,可以通过定义一个切面来处理所有服务层方法的日志记录,而无需在每个服务方法中显式调用日志代码。这样提高了代码的整洁性和可维护性。 在实际开发中,首先需要将这些库添加到项目的依赖管理中,然后定义切面...
例如,可能会有一个自定义的MyBatis拦截器用于分页查询,一个Spring AOP切面用于记录操作日志,Spring事务管理确保数据的一致性,而反射工具类可能用于动态加载配置或处理某些通用的反射任务。通过这些组件的组合,...
在提供的四个jar包中,每个都有其特定的功能和作用,对于理解Spring AOP的工作原理至关重要。 1. **aspectj-1.7.3.jar**:这是AspectJ库的一部分,AspectJ是一个全面的面向切面编程(AOP)的Java语言扩展。在Spring ...
通过以上知识,我们可以创建一个简单的Spring AOP实例,例如创建一个日志切面,记录每个服务方法的执行时间: ```java @Aspect @Component public class LoggingAspect { @Before("execution(* ...
AOP是一种编程范式,它允许程序员定义“切面”,这些切面可以包含业务逻辑的各个部分,如日志、事务管理等,而无需在每个业务方法中显式编写这些代码。 首先,我们来理解Spring AOP的基本概念。在Spring中,切面由...
例如事务管理就是一个典型的横切关注点,因为它几乎涉及到每个服务层的方法。 2. **连接点(Joinpoint)**:在程序执行过程中的某个具体点,如方法调用、异常抛出等,这些点就是连接点。Spring AOP主要支持方法...
Spring AOP 1.0是Spring框架早期的一个版本,它引入了面向切面编程(Aspect Oriented Programming,AOP)的概念,使得开发者可以方便地实现横切关注点,如日志记录、事务管理、性能监控等,从而提高代码的可读性和可...
除了使用 AspectJ 进行 AOP 开发之外,Spring 还提供了另外两种方式来实现 AOP: 1. **基于注解的配置**:通过在切面类和方法上使用特定的注解来定义切面和通知。 2. **基于 XML 的配置**:通过 XML 文件来配置切面...
例如,我们可以定义一个切面来处理日志记录,这样就无需在每个被记录的方法中插入日志代码。只需在切面中定义切入点(pointcut)表达式,匹配需要记录日志的方法,然后在通知(advice)中编写日志逻辑即可。 在实际...
这意味着在controller层的每个方法执行前和执行后,对应的日志记录方法都会被调用。 接下来,我们需要在Spring配置中启用AOP代理。在Spring XML配置文件中,添加以下代码: ```xml <aop:aspectj-autoproxy /> ``` ...
Spring AOP 是Spring框架提供的一个功能模块,它允许开发者将横切关注点(cross-cutting concerns)从业务逻辑中解耦出来,通过在方法调用前后进行拦截来实现。这些横切关注点通常是一些与业务逻辑不直接相关的服务...
Spring框架的每个主要模块都有对应的jar文件,例如spring-aop.jar,它包含了实现AOP功能的核心类和接口。 描述中的“额外jar包”可能指的是如AspectJ的库,AspectJ是一个强大的静态和动态AOP框架,可以与Spring AOP...