`
lucky520
  • 浏览: 35837 次
  • 性别: Icon_minigender_2
  • 来自: 武汉
社区版块
存档分类
最新评论

Spring AOP之增强

阅读更多

      继续Spring AOP的学习,总所周知,aop的魅力所在就是它能在方法前后起拦截作用,以便我们定义横切逻辑代码。增强大致分为5类:前置增强(就是在目标方法调用前拦截),后置增强(就是在目标方法调用之后拦截),异常增强(就是在目标方法抛出后拦截),引介增强(它是一种特殊的增强,可以在目标类添加属性和方法,通过拦截定义一个接口,让目标代理实现这个接口,它的连接点是类级别的),而前面三种增强则是方法级别的。以上四种增强接口是Spring定义的,还有只用环绕增强(目标方法前后拦截)是AOP联盟定义的接口。其实aop增强很简单,通过实现这些增强接口,在实现这些接口的方法中定义横切逻辑,然后通过配置spring配置文件,就可以完成将增强织入到目标方法中了。

 

首先,以前置增强为例,大家都知道如果我们到餐厅去,服务员首先会欢迎顾客,然后再为我们提供服务。这里我们一个

Waiter类:

package com.me.services;

public interface Waiter {
	void greetTo(String name);
	void serveTo(String name);
}

 现在我们来看一个训练不足的服务生的服务情况:

package com.me.services.imp;

import com.me.services.Waiter;

public class LuceyWaiter implements Waiter {

	public void greetTo(String name) {
		System.out.println("greet to "+name);
	}

	public void serveTo(String name) {
		System.out.println("server "+name);
	}

}

Lucey走到闷不做声走到顾客面前, 提供服务,那么,我们就需要对每个服务生进行规范,在服务之前要行礼貌用语。

package com.me.advice;

import java.lang.reflect.Method;

import org.springframework.aop.MethodBeforeAdvice;

public class GreetingBeforeAdvice implements MethodBeforeAdvice {

	public void before(Method method, Object[] args, Object obj)
			throws Throwable {
		String clientName = args[0].toString();
		System.out.println("How are you,"+clientName+"!");
	}

}

 这里我们就用到了前置增强,通过实现org.springframework.aop.MethodBeforeAdvice接口的before方法定义逻辑代码。before中的三个参数分别代表:目标方法,目标方法的参数列表,目标实例。

目标对象也有了,增强也有了,接下来如何把增强织入的目标对象生成代理呢?上一次博客写到spring的代理机制,我们知道可以通过JDK和CGLib两种方式动态创建代理。但是那样我们代码太过麻烦,要自定义一个类实现指定接口,那有没有简单的方法呢?当然,spring为我们提供了ProxyFactoryBean,它帮我们完成了上面通过JDK,CGLib创建代理那些复杂的工作,我们只需要在spring中配置一下即可完成织入工作,^-^

<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-2.0.xsd">
	<!-- 需要代理的业务类 -->
	<bean id="target" class="com.me.services.imp.LuceyWaiter"></bean>
	<!-- 指定增强,一个业务类可以有多个增强形成增强链,调用顺序与添加顺序一致 -->
	<bean id="greetAdvice" class="com.me.advice.GreetingBeforeAdvice"></bean>
	<!-- 利用ProxyFactoryBean创建代理 -->
	<bean id="waiter" class="org.springframework.aop.framework.ProxyFactoryBean">
	<!-- 代理要实现的接口,可以是多个接口 -->		
		<property name="proxyInterfaces" value="com.me.services.Waiter"/>
		<property name="target" ref="target"/>
		<!-- 需要织入目标对象的0增强数组 -->
		<property name="interceptorNames">
			<list>
				<value>greetAdvice</value>
			</list>
		</property>
	</bean>
</beans>

关于ProxyFactoryBean的工作原理将在以后写到,但需要进一步了解它的几个常用配置属性,除上面的属性外,还有singleton:返回代理是否为单实例,默认true.

optimize:当设置为true时,强制使用CGLib代理。对于单实例推荐配置true,但对于作用域类型的代理推荐false.

proxyTargetClass:是否对类代理(不是对接口进行代理),设置为true使用CGLib代理。当然如果设置为true就不必设置proxyInterfaces属性了,及时设置了也将被忽略。下面来一段测试代码吧:

package com.me.test;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.me.services.Waiter;

public class TestBeforeAdvice {

	public static void main(String[] args) {
		ApplicationContext cxt = new ClassPathXmlApplicationContext("applicationContext.xml");
        Waiter waiter = (Waiter)cxt.getBean("waiter");
        waiter.greetTo("John");
	}

}

 后置增强,异常抛出增强和环绕增强用法差不多,只是实现的接口不一样罢了。下面就做说明了,我将测试代码上传供大家学习。接下来,来谈谈我们类级别的增强,即引介增强,我们还是根据上一篇博客代理机制的示例来学习引介增强。我们前面用到监测用户添加和删除性能,现在将起改为可控的。即维护人员可控制是否采用性能监控。

首先定义一个用于标志目标类是否支持性能监控的接口:

package com.me.advice;

public interface Monitorable {
	/** 
	 * @param IsActive 
	 * true:性能监控功能激活
	 * false: 性能监控功能关闭
	 */
	public void setMonitorActive(boolean IsActive);
}

  通过继承DelegatingIntroductionInterceptor为目标类引入性能监控功能,代码如下:

package com.me.util;

import org.aopalliance.intercept.MethodInvocation;
import org.springframework.aop.support.DelegatingIntroductionInterceptor;

@SuppressWarnings("serial")
public class ControllablePerformanceMonitor extends
		DelegatingIntroductionInterceptor implements Monitorable {
	//为了解决线程安全问题
	private ThreadLocal<Boolean> statusMap = new ThreadLocal<Boolean>();
	
	public void setMonitorActive(boolean IsActive) {
		statusMap.set(new Boolean(IsActive));		
	}
	
	public Object invoke(MethodInvocation mi)throws Throwable{
		Object obj = null;
		if(statusMap.get()!=null && statusMap.get().booleanValue()){
			PerformanceMonitor pm = new PerformanceMonitor();
			pm.start(mi.getClass().getName()+"."+mi.getMethod().getName());
			obj = super.invoke(mi);
			pm.end();
		}else{
			obj = super.invoke(mi);
		}
		return obj;
	}

}

 

配置引介增强

<bean id="target" class="com.me.services.imp.UserServiceImp"/>
 	<bean id="pmonitor" class="com.me.util.ControllablePerformanceMonitor"/>
 	<!-- 创建代理 -->
 	<bean id="userService" class="org.springframework.aop.framework.ProxyFactoryBean">
 	<!-- 引介增强所实现的接口 -->
 	<property name="interfaces">
 		<value>com.me.util.Monitorable</value>
 	</property>
 	<property name="target" ref="target"/>
 	<property name="interceptorNames">
 		<idref local="pmonitor"/>
 	</property>
 	<!-- 由于引介增强通过子类创建代理,所以强制使用CGLib代理实现机制 -->
 	<property name="proxyTargetClass" value="true"/>
 	</bean>

 测试引介增强

package com.me.test;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.me.services.UserService;
import com.me.entity.*;
import com.me.util.Monitorable;
public class TestCotrollerPerformance {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		 ApplicationContext cxt = new ClassPathXmlApplicationContext("applicationContext.xml");
		 UserService service = (UserService)cxt.getBean("userService");
		 service.deleteUser(1);
		 service.insertUser(new User());
		 //这里强制成果,说明返回的代理引入了Monitorable接口
		 Monitorable monitor = (Monitorable)service;
		 monitor.setMonitorActive(true);
		 
		 service.deleteUser(1);
		 service.insertUser(new User());
	}

}

 

 

 

 

 

3
0
分享到:
评论

相关推荐

    spring aop jar 包

    Spring AOP(Aspect Oriented Programming,面向切面编程)是Spring框架的重要组成部分,它提供了一种在不修改源代码的情况下,对程序进行功能增强的技术。这个"spring aop jar 包"包含了实现这一功能所需的类和接口,...

    Spring AOP 16道面试题及答案.docx

    Spring AOP,全称为Aspect Oriented Programming,是面向切面编程的一种编程范式,它是对传统的面向对象编程(OOP)的一种补充。在OOP中,核心是对象,而在AOP中,核心则是切面。切面是关注点的模块化,即程序中的...

    死磕Spring之AOP篇 - Spring AOP两种代理对象的拦截处理(csdn)————程序.pdf

    Spring AOP 是一种面向切面编程的技术,它允许我们在不修改源代码的情况下,对应用程序的特定部分(如方法调用)进行增强。在 Spring 中,AOP 的实现主要依赖于代理模式,有两种代理方式:JDK 动态代理和 CGLIB 动态...

    Spring AOP完整例子

    Spring AOP(面向切面编程)是Spring框架的核心特性之一,它允许开发者在不修改源代码的情况下,通过插入切面来增强或改变程序的行为。在本教程中,我们将深入探讨Spring AOP的不同使用方法,包括定义切点、通知类型...

    Spring AOP实现机制

    自定义类加载器允许我们在特定条件下加载类,例如,当类需要被CGLIB增强时,自定义类加载器可以在加载过程中应用AOP增强。 ### 4. Spring AOP配置 Spring AOP的配置可以通过XML或注解方式进行: - **XML配置**: ...

    spring aop 五个依赖jar

    使用Spring AOP,开发者可以定义切面,声明切入点(即关注点的定位),编写通知(即实际的增强代码),并通过配置将它们应用到目标对象上。这样,我们可以保持业务逻辑的清晰,同时实现系统级的服务,如事务管理、...

    spring AOP依赖三个jar包

    Spring AOP,即Spring的面向切面编程模块,是Spring框架的重要组成部分,它允许开发者在不修改源代码的情况下,对程序进行横切关注点的处理,如日志、事务管理等。实现这一功能,主要依赖于三个核心的jar包:aop...

    spring AOP 引入jar包,spring IOC 引入Jar包

    Spring AOP(面向切面编程)允许开发者在不修改源代码的情况下,通过“切面”来插入新的行为或增强已有功能,而 Spring IOC(控制反转)则负责管理对象的生命周期和依赖关系,极大地简化了应用的架构。 **Spring ...

    spring aop的demo

    在`springAop1`这个压缩包中,可能包含了一个简单的应用示例,展示了如何定义一个切面类,以及如何在该类中定义通知方法。例如,我们可能会看到一个名为`LoggingAspect`的类,其中包含了`@Before`注解的方法,用于在...

    spring aop用到jar包.rar

    Spring AOP(面向切面编程)是Spring框架的重要组成部分,它提供了一种模块化和声明式的方式来处理系统中的交叉关注点,如日志、事务管理、性能监控等。在使用Spring AOP时,通常需要引入特定的jar包来支持其功能。...

    spring之AOP(动态代理)

    在Spring框架中,AOP(面向切面编程)是一种强大的设计模式,它允许开发者将关注点分离,将横切关注点(如日志、事务管理、权限检查等)与核心业务逻辑解耦。AOP的核心概念是切面、通知、连接点、切入点和织入。在...

    springAOP所需jar包

    Spring AOP,即Spring的面向切面编程模块,是Spring框架的重要组成部分,它提供了一种在不修改源代码的情况下对程序进行扩展和增强的方法。在Java应用中,AOP主要用于日志记录、性能统计、安全控制、事务管理等方面...

    Spring AOP之5种增强方法应用范例

    本篇文章将深入探讨Spring AOP中的5种增强方法,以及如何在实际应用中使用它们。我们将不涉及链接,而是直接在这里详细讲解这些概念。 1. **前置通知(Before Advice)**: 前置通知在目标方法执行之前运行,但不...

    springAOP配置动态代理实现

    Spring AOP(面向切面编程)是Spring框架的重要组成部分,它允许程序员在不修改源代码的情况下,通过在运行时插入额外的行为(如日志记录、性能监控等)来增强对象的功能。动态代理则是Spring AOP实现的核心技术之一...

    spring AOP入门教程

    - **SpringAOP.avi**:可能是一个视频教程,详细讲解了Spring AOP的概念和实践。 - **SpringAOP.doc**:可能是文档教程,包含了详细的步骤和示例代码。 - **SpringAOP_src.rar**:源代码示例,供你参考和实践。 - **...

    Spring AOP IOC源码笔记.pdf

    Spring框架是Java开发中不可或缺的一部分,它主要由两个核心组件构成:IoC(Inversion of Control,控制反转)和AOP(Aspect Oriented Programming,面向切面编程)。本笔记将深入探讨这两个概念以及它们在Spring中...

    Spring AOP依赖jar包

    - **代理(Proxy)**:Spring AOP 通过代理来实现对目标对象的增强,有 JDK 动态代理和 CGLIB 代理两种方式。 2. **AspectJ 1.6.12 Jar 包** `AspectJ` 是一个独立的 AOP 框架,提供了更强大的 AOP 支持,包括...

    spring aop所需jar包

    Spring AOP,即Spring的面向切面编程,是Spring框架中的一个重要组成部分,它提供了一种在不修改源代码的情况下对程序进行功能增强的技术。在Java应用程序中,AOP主要用于日志记录、性能统计、安全控制、事务管理等...

Global site tag (gtag.js) - Google Analytics