`
szlxh002
  • 浏览: 34462 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

Spring AOP 基础

 
阅读更多

 

1.AOP的述语

(1)Joinpoint连接点

程序运行过程中的某一点.比如方法调用、属性访问、异常抛出

(2)Pointcut切点

需要进行增加的位置

(3)Advice增强

在不修改原有代码的前提下,为某一个对象增加新的功能

(4)Advisor(Aspect)切面

把散落在系统各处与横切关注点相关的重复代码抽取出来归整到一处形成一个模块,我们称为方面.

(5)Target目标对象

需要增加的目标类

(6)Introduction引介

特殊的Advice,为类添加一性属性和方法

(7)Weaving织入

将增加添加到目标类具体连接点的过程。有编译期织入,类装载期织入,动态代理织入三种,Spring采用动态代理织入。

(8)Proxy代理

一个类被AOP织入增强后,产出一个结果类。Spring AOP可以采用JDK动态代理和基于CGLib动态代理

2.Advice类型

spring共提供了五种类型的通知:

通知类型 接口 描述
Around 环绕增强 org.aopalliance.intercept.MethodInterceptor 拦截对目标方法调用
Before 前置增强 org.springframework.aop.MethodBeforeAdvice  在目标方法调用前调用
After  后置增强 org.springframework.aop.AfterReturningAdvice 在目标方法调用后调用
Throws 异常增强 org.springframework.aop.ThrowsAdvice 当目标方法抛出异常时调用

还有一类是引入增强,用来定义切入点的。

 

(1)前置增强MethodBeforeAdvice

package com.baobaotao.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 = (String)args[0];
		System.out.println("How are you!Mr."+clientName+".");
	}
}

 (2)后置增强AfterReturningAdvice

 

package com.baobaotao.advice;

import java.lang.reflect.Method;
import org.springframework.aop.AfterReturningAdvice;

public class GreetingAfterAdvice implements AfterReturningAdvice {

	public void afterReturning(Object returnObj, Method method, Object[] args,
			Object obj) throws Throwable {
		System.out.println("Please enjoy yourself!");
	}
}

 (3)环绕增强MethodInterceptor

 

package com.baobaotao.advice;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;

public class GreetingInterceptor implements MethodInterceptor {

	public Object invoke(MethodInvocation invocation) throws Throwable {
		Object[] args = invocation.getArguments();
		String clientName = (String)args[0];
		System.out.println("How are you!Mr."+clientName+".");
		
		Object obj = invocation.proceed();
		
		System.out.println("Please enjoy yourself!");
		
		return obj;
	}
}

 (4)异常抛出增强ThrowsAdvice

 

package com.baobaotao.advice;

import java.lang.reflect.Method;

import org.springframework.aop.ThrowsAdvice;

public class TransactionManager implements ThrowsAdvice {
	public void afterThrowing(Method method, Object[] args, Object target,
			Exception ex) throws Throwable {
		System.out.println("-----------");
		System.out.println("method:" + method.getName());
		System.out.println("抛出异常:" + ex.getMessage());
		System.out.println("成功回滚事务。");
	}
}

 (5)引介增强DelegatingIntroductionInterceptor

 

 

package com.baobaotao.introduce;

import org.aopalliance.intercept.MethodInvocation;
import org.springframework.aop.support.DelegatingIntroductionInterceptor;
public class ControllablePerformaceMonitor
		extends
			DelegatingIntroductionInterceptor implements Monitorable{
	private ThreadLocal<Boolean> MonitorStatusMap = new ThreadLocal<Boolean>();
	public void setMonitorActive(boolean active) {
		MonitorStatusMap.set(active);
	}
	public Object invoke(MethodInvocation mi) throws Throwable {
		Object obj = null;
		if (MonitorStatusMap.get() != null && MonitorStatusMap.get()) {
			PerformanceMonitor.begin(mi.getClass().getName() + "."
					+ mi.getMethod().getName());
			obj = super.invoke(mi);
			PerformanceMonitor.end();
		} else {
			obj = super.invoke(mi);
		}
		return obj;
	}
}

 

 

 

package com.baobaotao.introduce;

public interface Monitorable {
   void setMonitorActive(boolean active);
}

 

(6)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:p="http://www.springframework.org/schema/p"
	xsi:schemaLocation="http://www.springframework.org/schema/beans 
     http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

	<bean id="greetingBefore" class="com.baobaotao.advice.GreetingBeforeAdvice" />
	<bean id="greetingAfter" class="com.baobaotao.advice.GreetingAfterAdvice" />
	<bean id="greetingAdvice" class="com.baobaotao.advice.GreetingBeforeAdvice" />
	<bean id="greetingAround" class="com.baobaotao.advice.GreetingInterceptor" />
	<bean id="target" class="com.baobaotao.advice.NaiveWaiter" />


	<!--1. greetingAdvice -->
	<!--
		bean id="waiter"
		class="org.springframework.aop.framework.ProxyFactoryBean"
		p:proxyInterfaces="com.baobaotao.advice.Waiter" p:target-ref="target"
		p:interceptorNames="greetingAdvice"/
	-->


	<!--2. before and after advice -->
	<!--
		bean id="waiter"
		class="org.springframework.aop.framework.ProxyFactoryBean"
		p:proxyInterfaces="com.baobaotao.advice.Waiter" p:target-ref="target"
		p:interceptorNames="greetingBefore,greetingAfter"/
	-->
    <!--3. around advice -->
	<bean id="waiter" class="org.springframework.aop.framework.ProxyFactoryBean"
		p:proxyInterfaces="com.baobaotao.advice.Waiter" p:target-ref="target"
		p:interceptorNames="greetingAround" />


	<!--4. 异常抛出增强  
	<bean id="forumServiceTarget" class="com.baobaotao.advice.ForumService" />
	<bean id="transactionManager" class="com.baobaotao.advice.TransactionManager" />
	<bean id="forumService" class="org.springframework.aop.framework.ProxyFactoryBean"
	  p:interceptorNames="transactionManager"
	  p:target-ref="forumServiceTarget"
	  p:proxyTargetClass="true"/>
	  -->

<!--5..引介增强-->
	<bean id="pmonitor" class="com.baobaotao.introduce.ControllablePerformaceMonitor" />

	<bean id="forumService" class="org.springframework.aop.framework.ProxyFactoryBean"
		p:interfaces="com.baobaotao.introduce.Monitorable" 
		p:target-ref="forumServiceTarget"
		p:interceptorNames="pmonitor" 
		p:proxyTargetClass="true" />

</beans>

 

 3.Pointcut类型

(1)StaticMethodMatcherPointcut静态方法

      NameMatchMethodPointcut和AbstractRegexpMethodPointcut子类

(2)DynamicMethodMatcherPointcut动态方法

(3)AnnotationMatchingPointcut注解切点

(4)ExpressionPointcut表达式

(5)ControlFlowPointcut流程

(6)ComposablePointcut复合切点

 

例子

 

4.Advisor类型

(1)Advisor

一般要面,只有一个Advice

(2)PointcutAdvisor

具有切点的切面,包含Pointcut和Advice

(3)IntroductionAdvisor

引介切面.

 

5.使用例子

 

Waiter

 

package com.baobaotao.advisor;

public class Waiter {

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

 WaiterDelegate

 

package com.baobaotao.advisor;

public class WaiterDelegate {
	private Waiter waiter;
	public void service(String clientName) {
		waiter.greetTo(clientName);
		waiter.serveTo(clientName);
	}
	public void setWaiter(Waiter waiter) {
		this.waiter = waiter;
	}
}

 

 

GreetingBeforeAdvice

package com.baobaotao.advisor;

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 = (String)args[0];
		System.out.println(obj.getClass().getName()+"."+method.getName());
		System.out.println("How are you!Mr."+clientName+".");
	}
}

  

 

 

StaticMethodMatcherPointcutAdvisor

package com.baobaotao.advisor;

import java.lang.reflect.Method;

import org.springframework.aop.ClassFilter;
import org.springframework.aop.support.StaticMethodMatcherPointcutAdvisor;

public class GreetingAdvisor extends StaticMethodMatcherPointcutAdvisor {

	public boolean matches(Method method, Class clazz) {
		return "greetTo".equals(method.getName());
	}	
	public ClassFilter getClassFilter(){
		return new ClassFilter(){
			public boolean matches(Class clazz){
				return Waiter.class.isAssignableFrom(clazz);
			}
		};
		
	}

}

 

 

DynamicMethodMatcherPointcut

package com.baobaotao.advisor;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

import org.springframework.aop.ClassFilter;
import org.springframework.aop.support.DynamicMethodMatcherPointcut;

public class GreetingDynamicPointcut extends DynamicMethodMatcherPointcut {
	private static List<String> specialClientList = new ArrayList<String>();
	static {
		specialClientList.add("John");
		specialClientList.add("Tom");
	}
	public ClassFilter getClassFilter() {
		return new ClassFilter() {
			public boolean matches(Class clazz) {
				System.out.println("调用getClassFilter()对"+clazz.getName()+"做静态检查.");
				return Waiter.class.isAssignableFrom(clazz);
			}
		};
	}
//	public boolean matches(Method method, Class clazz) {
//		System.out.println("调用matches(method,clazz)对"+clazz.getName()+"."+method.getName()+"做静态检查.");
//		return "greetTo".equals(method.getName());
//	}
	public boolean matches(Method method, Class clazz, Object[] args) {
		System.out.println("调用matches(method,clazz)对"+clazz.getName()+"."+method.getName()+"做动态检查.");
		String clientName = (String) args[0];
		return specialClientList.contains(clientName);
	}

}

 Bean.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:p="http://www.springframework.org/schema/p"
	xmlns:util="http://www.springframework.org/schema/util"
	xsi:schemaLocation="http://www.springframework.org/schema/beans 
	http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
	http://www.springframework.org/schema/util 
	http://www.springframework.org/schema/util/spring-util-3.0.xsd">

	<!-- 普通方法名匹配切面 -->
	<bean id="waiterTarget" class="com.baobaotao.advisor.Waiter" />
	<bean id="sellerTarget" class="com.baobaotao.advisor.Seller" />
	<bean id="greetingAdvice" class="com.baobaotao.advisor.GreetingBeforeAdvice" />
	<bean id="greetingAdvisor" class="com.baobaotao.advisor.GreetingAdvisor"
		p:advice-ref="greetingAdvice" />

	<bean id="parent" abstract="true"
		class="org.springframework.aop.framework.ProxyFactoryBean"
		p:interceptorNames="greetingAdvisor" p:proxyTargetClass="true" />
	<bean id="waiter" parent="parent" p:target-ref="waiterTarget" />
	<bean id="seller" parent="parent" p:target-ref="sellerTarget" />
	
	
	<bean id="nameAdvisor"
		class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor"
		p:advice-ref="greetingAdvice">
		<property name="mappedName">
			<value>serve*</value>
		</property>
		
	</bean>
	<bean id="waiterName" class="org.springframework.aop.framework.ProxyFactoryBean"
		p:interceptorNames="nameAdvisor" p:target-ref="waiterTarget"
		p:proxyTargetClass="true" />	

	<!-- 正则表达式方法名匹配切面 -->
	<bean id="regexpAdvisor"
		class="org.springframework.aop.support.RegexpMethodPointcutAdvisor"
		p:advice-ref="greetingAdvice">
		<property name="patterns">
			<list>
				<value>.*greet.*</value>
			</list>
		</property>
	</bean>
	<bean id="waiter1" class="org.springframework.aop.framework.ProxyFactoryBean"
		p:interceptorNames="regexpAdvisor" p:target-ref="waiterTarget"
		p:proxyTargetClass="true" />


	<!-- 动态切面 -->
	<bean id="dynamicAdvisor" class="org.springframework.aop.support.DefaultPointcutAdvisor">
		<property name="pointcut">
			<bean class="com.baobaotao.advisor.GreetingDynamicPointcut" />
		</property>
		<property name="advice">
			<bean class="com.baobaotao.advisor.GreetingBeforeAdvice" />
		</property>
	</bean>


	<bean id="waiter2" class="org.springframework.aop.framework.ProxyFactoryBean"
		p:interceptorNames="dynamicAdvisor" p:target-ref="waiterTarget"
		p:proxyTargetClass="true" />

	<!-- 控制流程切面 -->
	<bean id="controlFlowPointcut" class="org.springframework.aop.support.ControlFlowPointcut">
		<constructor-arg type="java.lang.Class"
			value="com.baobaotao.advisor.WaiterDelegate" />
		<constructor-arg type="java.lang.String" value="service" />
	</bean>
	<bean id="controlFlowAdvisor" class="org.springframework.aop.support.DefaultPointcutAdvisor"
		p:pointcut-ref="controlFlowPointcut" p:advice-ref="greetingAdvice" />
	<bean id="waiter3" class="org.springframework.aop.framework.ProxyFactoryBean"
		p:interceptorNames="controlFlowAdvisor" p:target-ref="waiterTarget"
		p:proxyTargetClass="true" />

	<!-- 复合切点切面 -->
	<bean id="gcp" class="com.baobaotao.advisor.GreetingComposablePointcut" />
	<bean id="composableAdvisor" class="org.springframework.aop.support.DefaultPointcutAdvisor"
		p:pointcut="#{gcp.intersectionPointcut}" p:advice-ref="greetingAdvice" />
	<bean id="waiter4" class="org.springframework.aop.framework.ProxyFactoryBean"
		p:interceptorNames="composableAdvisor" p:target-ref="waiterTarget"
		p:proxyTargetClass="true" />

	<!--引入切面-->
	<bean id="introduceAdvisor"
		class="org.springframework.aop.support.DefaultIntroductionAdvisor">
		<constructor-arg>
			<bean class="com.baobaotao.introduce.ControllablePerformaceMonitor" />
		</constructor-arg>
	</bean>
	<bean id="forumServiceTarget" class="com.baobaotao.introduce.ForumService" />
	<bean id="forumService" class="org.springframework.aop.framework.ProxyFactoryBean"
	      p:interceptorNames="introduceAdvisor"
	      p:target-ref="forumServiceTarget"
	      p:proxyTargetClass="true"/>
</beans>

 

 

 

 6.自动创建代理

(1)BeanNameAutoProxyCreator

基于Bean配置名规则的自动代理创建器

(2)DefaultAdvisorAutoProxyCreator

基于Advisor匹配机制的自动代理创建器

(3)AnnotationAwareAspectJAutoProxyCreator

基于AspectJ注解标签的自动代理创建器

<?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:p="http://www.springframework.org/schema/p"
	xsi:schemaLocation="http://www.springframework.org/schema/beans 
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
	<bean id="waiter" class="com.baobaotao.advisor.Waiter" />
	<bean id="seller" class="com.baobaotao.advisor.Seller" />
	<bean id="greetingAdvice" class="com.baobaotao.advisor.GreetingBeforeAdvice" />
	<!-- 通过Bean名称自动创建代理 -->
	<!--
		<bean
		class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator"
		p:beanNames="*er" p:interceptorNames="greetingAdvice"
		p:optimize="true"/>
	-->


	<!--通过Advisor自动创建代理-->
	<bean id="regexpAdvisor"
		class="org.springframework.aop.support.RegexpMethodPointcutAdvisor"
		p:patterns=".*greet.*" p:advice-ref="greetingAdvice" />
	<bean
		class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" />
</beans>

 

 

 

分享到:
评论

相关推荐

    Spring AOP基础关于AOP是什么的理解

    Spring AOP 基础关于 AOP 是什么的理解 AOP(Aspect Oriented Programming 面向方面的编程)是一种实现横切面的工具,它是 OOP 的补充,而不是 OOP 的竞争对手。AOP 的出现是为了解决 OOP 中的缺陷,即 OOP 中的类...

    第二章:Spring AOP 基础1

    在本章"Spring AOP 基础1"中,我们主要探讨了Spring AOP(面向切面编程)的核心概念和实现方式。AOP是一种编程范式,它允许程序员定义"切面",这些切面封装了跨越多个对象的横切关注点,如日志、事务管理等。以下是...

    SpringSpring Aop基础入门

    Spring Aop基于xml练习

    springAop的配置实现

    Spring AOP 基础概念** - **切面(Aspect)**:切面是关注点的模块化,比如日志、事务管理等,这些关注点可以被定义为一个独立的模块,称为切面。 - **通知(Advice)**:在特定连接点上执行的代码,也就是切面要...

    Spring Aop基础入门

    Spring Aop基于annotation注解练习

    springAOP配置动态代理实现

    一、Spring AOP基础知识 1. **什么是AOP**:AOP是一种编程范式,用于处理系统中的横切关注点,即那些跨越多个类或方法的共同功能,如事务管理、日志记录等。AOP通过切面(Aspect)将这些关注点与业务逻辑分离,提高...

    spring aop 附带测试实例

    ### 一、Spring AOP基础 1. **切面(Aspect)**:切面是关注点的模块化,例如日志、事务等。在Spring AOP中,一个切面通常由一个或多个通知(advises)和一个切点(join point)定义组成。 2. **通知(Advice)**...

    spring aop实例

    **一、Spring AOP基础知识** 1. **切面(Aspect)**:切面是跨越多个对象的行为或关注点的模块化。在Spring AOP中,切面由通知(advises)和切点(pointcuts)定义。 2. **通知(Advice)**:通知是在特定连接点上...

    spring aop实例annotation方法实现

    一、Spring AOP基础 Spring AOP是Spring框架的一部分,它提供了一种在运行时织入横切关注点(如日志、事务管理等)到目标对象的能力。AOP的核心概念包括切面(Aspect)、连接点(Join Point)、通知(Advice)、切入...

    spring AOP 基础

    Spring AOP(面向切面编程)是Spring框架的一个核心组件,它允许开发者在不改变原有代码的情况下,通过预编译和运行期动态代理技术,向程序中动态地添加额外的功能。本教程主要介绍AOP的基本概念,使用代理模式实现...

    Spring AOP完整例子

    首先,我们需要理解Spring AOP的基础概念。AOP的核心是切点(Pointcut),它定义了关注点在何处应用。在Spring中,我们通常使用表达式或者注解来定义切点。例如,我们可以使用`@Before`、`@After`、`@Around`、`@...

    spring aop依赖jar包

    现在,我们回到主题——"springaop依赖的jar包"。在Spring 2.5.6版本中,使用Spring AOP通常需要以下核心jar包: - `spring-aop.jar`:这是Spring AOP的核心库,包含了AOP相关的类和接口。 - `spring-beans.jar`:...

    spring 的AOP 基础

    **Spring AOP基础** 在Java开发中,Spring框架以其强大的功能和灵活性被广泛使用,而Spring AOP(面向切面编程)是其重要组成部分之一。AOP允许开发者将关注点从核心业务逻辑中分离出来,比如日志记录、权限检查等...

    Spring Aop四个依赖的Jar包

    Spring AOP就是基于这些接口进行设计的,因此这个库是Spring AOP和其他AOP实现之间协作的基础。 在实际使用中,我们需要在项目的类路径下包含这些Jar包,并在Spring配置文件中启用AOP支持。例如,可以通过以下XML...

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

    了解这些基础知识可以帮助我们更好地掌握 Spring AOP 的实现细节。在分析源码时,可以参考作者的源码注释和相关文章,以便更深入地理解每一步操作。 总的来说,Spring AOP 通过动态代理技术实现了切面的插入,使得...

    Spring AOP面向方面编程原理:AOP概念

    Spring AOP是在Spring框架的基础上实现的一种面向方面编程机制。 1. **方面(Aspect)**:这是AOP的核心概念之一,指代一个关注点的模块化,该关注点可能会横切多个对象。例如事务管理就是一个典型的横切关注点,...

    spring aop 自定义注解保存操作日志到mysql数据库 源码

    3、对spring aop认识模糊的,不清楚如何实现Java 自定义注解的 4、想看spring aop 注解实现记录系统日志并入库等 二、能学到什么 1、收获可用源码 2、能够清楚的知道如何用spring aop实现自定义注解以及注解的逻辑...

    使用Spring配置文件实现AOP

    二、Spring AOP基础 在Spring中,AOP的实现依赖于两个主要组件:通知(Advice)和切点(Pointcut)。通知是实际执行的增强代码,如方法调用前的记录日志;切点是通知应该应用到的方法或类。Spring支持五种类型的的...

    基于注解配置和使用spring AOP(spring mvc框架)

    一、Spring AOP基础知识 1. **切面(Aspect)**:切面是关注点的模块化,例如日志、事务管理等。在Spring AOP中,切面可以是Java类或@Aspect注解的类。 2. **通知(Advice)**:通知是指在特定连接点执行的代码块...

    spring aop hessian 基础demo 部署即可运行

    Spring AOP和Hessian是两个在Java开发中广泛使用的技术,尤其在分布式系统和服务治理中。下面将详细解释这两个概念以及它们如何结合使用。 **Spring AOP(面向切面编程)** Spring AOP是Spring框架的一个重要组成...

Global site tag (gtag.js) - Google Analytics