`
raymond.chen
  • 浏览: 1437444 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

Spring AOP使用整理:常用的Advice接口类

阅读更多

一、基础接口和类

     1、Person接口的源码

public interface Person {
	public void info();
	public void show(String message);
}

 

     2、PersonImpl类的源码

public class PersonImpl implements Person {
	private String name;
	private int age;
	
	public void setName(String name) {
		this.name = name;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public void info() {
		System.out.println("\t我叫" + name + ",今年" + age + "岁。");
	}

	public void show(String message) {
		System.out.println(message);
	}
}

 

    3、bean的配置

<!-- 目标对象 -->
<bean id="personTarget" class="com.cjm.aop.PersonImpl">
	<property name="name" value="Raymond.chen"/>
	<property name="age" value="30"/>
</bean>

 

二、Spring AOP支持的通知类型

     一)环绕通知(Around advice)

          实现环绕通知需要实现org.aopalliance.intercept.MethodInterceptor接口。

               1、PersonAroundAdvice类的源码

public class PersonAroundAdvice implements MethodInterceptor {
	public Object invoke(MethodInvocation invocation) throws Throwable {
		System.out.println("AroundAdvice:方法调用前");
		
		//不要忘记调用invocation的proceed方法哦
		Object result = invocation.proceed(); 
		
		System.out.println("AroundAdvice:方法调用后");
		return result;
	}
}

 

               2、bean配置

<bean id="personAroundAdvice" class="com.cjm.aop.PersonAroundAdvice"/>

<!-- 代理工厂bean -->
<bean id="person" class="org.springframework.aop.framework.ProxyFactoryBean">
	<property name="proxyInterfaces" value="com.cjm.aop.Person"/>
	<property name="target" ref="personTarget"/>
	<property name="interceptorNames">
		<list>
			<value>personAroundAdvice</value>
		</list>
	</property>
</bean>

 

               3、测试代码

ApplicationContext context = new FileSystemXmlApplicationContext("classpath:com/cjm/aop/beans.xml");
Person p = (Person)context.getBean("person");  //注意这里是代理工厂Bean的ID
p.info();

 

     二)前置通知(Before advice)

          实现前置通知需要实现org.springframework.aop.MethodBeforeAdvice接口。

               1、PersonBeforeAdvice类的源码

public class PersonBeforeAdvice implements MethodBeforeAdvice {
	public void before(Method method, Object[] args, Object target) throws Throwable {
		System.out.println("BeforeAdvice:方法调用前");
	}
}

 

               2、bean配置

<bean id="personBeforeAdvice" class="com.cjm.aop.PersonBeforeAdvice"/>

<bean id="person" class="org.springframework.aop.framework.ProxyFactoryBean">
	<property name="proxyInterfaces" value="com.cjm.aop.Person"/>
	<property name="target" ref="personTarget"/>
	<property name="interceptorNames">
		<list>
			<value>personBeforeAdvice</value>
		</list>
	</property>
</bean>

 

     三)返回后通知(After Returning advice)

          实现返回后通知需要实现org.springframework.aop.AfterReturningAdvice接口。

               1、PersonAfterReturningAdvice类的源码

public class PersonAfterReturningAdvice implements AfterReturningAdvice {
	public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
		System.out.println("AfterReturningAdvice:方法调用后");
	}
}

 

               2、bean配置

<bean id="personAfterReturningAdvice" class="com.cjm.aop.PersonAfterReturningAdvice"/>

<bean id="person" class="org.springframework.aop.framework.ProxyFactoryBean">
	<property name="proxyInterfaces" value="com.cjm.aop.Person"/>
	<property name="target" ref="personTarget"/>
	<property name="interceptorNames">
		<list>
			<value>personAfterReturningAdvice</value>
		</list>
	</property>
</bean>

 

               3、以上的配置中,通知对目标对象的所有方法都会起作用。如果需要过滤掉一部分方法,可以用正则表达式切入点配置器或者方法名匹配切入点配置器实现。

<!-- 通知与正则表达式切入点一起配置 -->
<!-- Advisor等于切入点加通知 -->
<!-- 方法名匹配切入点配置器:org.springframework.aop.support.NameMatchMethodPointcutAdvisor -->
<bean id="personPointcutAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
	<property name="advice" ref="personAfterReturningAdvice"/>
	<property name="patterns">
		<list>
			<value>.*info.*</value>
		</list>
	</property>
</bean>

<bean id="person" class="org.springframework.aop.framework.ProxyFactoryBean">
	<property name="proxyInterfaces" value="com.cjm.aop.Person"/>
	<property name="target" ref="personTarget"/>
	<property name="interceptorNames">
		<list>
			<value>personPointcutAdvisor</value>
		</list>
	</property>
</bean>

 

     四)异常通知(Throws advice)

          当连接点抛出异常时,异常通知被调用。实现异常通知需要实现org.springframework.aop.ThrowsAdvice接口,该接口不包含任何方法,但在实现该接口时必须实现如下形式的方法:
                 afterThrowing([Method], [args], [target], Throwable subclass)
          可以实现一个或多个这样的方法。在这些方法中,只有第四个参数是必需的,前三个参数可选。

 

          1、PersonThrowsAdvice类的源码

public class PersonThrowsAdvice implements ThrowsAdvice {
	public void afterThrowing(FileNotFoundException ex){
		System.out.println("ThrowsAdvice >> FileNotFoundException:" + ex.toString());
	}

	public void afterThrowing(Object[] args, Exception ex){
		System.out.println("ThrowsAdvice >> Exception:" + ex.getMessage());
	}

	public void afterThrowing(Method method, Object[] args, Object target, Throwable ex){
		System.out.println("ThrowsAdvice >> Throwable:" + ex.getMessage());
	}
}

 

          2、bean配置

<bean id="personThrowsAdvice" class="com.cjm.aop.PersonThrowsAdvice"/>

<bean id="person" class="org.springframework.aop.framework.ProxyFactoryBean">
	<property name="proxyInterfaces" value="com.cjm.aop.Person"/>
	<property name="target" ref="personTarget"/>
	<property name="interceptorNames">
		<list>
			<value>personThrowsAdvice</value>
		</list>
	</property>
</bean>

 

     五)引入通知(Introduction advice)

           引入通知是一种特殊的通知,它能将新的成员变量、成员方法引入到目标类中。它不能作用于任何切入点,因为它只作用于类层次,而不是方法层次。实现引入通知需要实现IntroductionAdvisor和IntroductionInterceptor接口。

           引入通知不能调用proceed方法。Advisor必须针对每个实例,并且是有状态的。

           引入通知的效果类似于设计模式中的访问者模式(Visitor Pattern)。

 

//类的继承关系
DelegatingIntroductionInterceptor
	IntroductionInfoSupport
		IntroductionInfo
	IntroductionInterceptor
		MethodInterceptor
			Interceptor
				Advice
		DynamicIntroductionAdvice
			Advice

DefaultIntroductionAdvisor
	IntroductionAdvisor
		Advisor
		IntroductionInfo
	ClassFilter
	Ordered

 

 

 

           1、Lockable接口的源码

public interface Lockable {
	void lock();
	void unlock();
	boolean locked();
}

 

           2、LockableImpl类的源码

public class LockableImpl extends DelegatingIntroductionInterceptor implements Lockable {
	private boolean locked;
	
	public void lock() {
		this.locked = true;
	}

	public void unlock() {
		this.locked = false;
	}

	public boolean locked() {
		return this.locked;
	}

	@Override
	public Object invoke(MethodInvocation invocation) throws Throwable {
		if(this.locked){
			throw new RuntimeException("加锁,无法执行");
		}
		
		//这里不能调用invocation的proceed方法
		//通常不需要改写invoke方法,直接调用父类的该方法即可
		return super.invoke(invocation);
	}
}

 

           3、PersonIntroductionAdvice类的源码

public class PersonIntroductionAdvice extends DefaultIntroductionAdvisor {
	public PersonIntroductionAdvice(){
		super(new LockableImpl(), Lockable.class);
	}
}

 

           4、bean配置

<!-- Advice必须针对每个实例,所以scope要设为prototype -->
<bean id="personIntroductionAdvice" class="com.cjm.aop.introduction.PersonIntroductionAdvice" scope="prototype"/>

<bean id="person" class="org.springframework.aop.framework.ProxyFactoryBean">
	<property name="proxyInterfaces" value="com.cjm.aop.Person"/>
	<property name="target" ref="personTarget"/>
	<property name="interceptorNames">
		<list>
			<value>personIntroductionAdvice</value>
		</list>
	</property>
</bean>

 

           5、测试代码

ApplicationContext context = new FileSystemXmlApplicationContext("classpath:com/cjm/aop/beans.xml");

//获得目标bean的代理bean
Person p = (Person)context.getBean("person");

//执行代理bean的方法,此时并未调用lock方法,可以执行
p.info();

Lockable lockable = (Lockable)p;
lockable.lock();

//目标bean已被锁定,此处将抛出异常
p.info();

 

  • 大小: 50.4 KB
分享到:
评论
4 楼 nieweichao 2016-05-09  
   
3 楼 hanmiao 2015-02-09  
Around advice 需要实现 MethodINterceptor 接口;
Before advice 需要实现 MethodBeforeAdvice 接口;
After advice 需要实现 AfterReturningAdvice 接口;
每个代理都要有 proxyInterfaces、target、interceptorNames 三个属性,分别对应被代理的接口,被代理的对象和代理实现类;
Pointcut advisor 则是在前三个 advice 的基础上再封装了壹层,添加了正则表达式解析的属性 patterns,用于匹配方法名称;
2 楼 wangbaosong09 2012-06-15  
wangbaosong09 写道
效果类似于设计模式中的访问者模式(Visitor Pattern)。

1 楼 wangbaosong09 2012-06-15  
效果类似于设计模式中的访问者模式(Visitor Pattern)。

相关推荐

    Spring学习篇AOP知识整理编程开发技术共4页.pdf

    JDK代理用于实现了接口的类,而CGLIB代理则用于没有实现接口的类。这两种代理方式允许Spring在运行时创建目标对象的代理,从而实现切面的功能。 Spring AOP的核心概念包括以下几个部分: 1. **切面(Aspect)**:...

    Spring 2.0 AOP 完整例子

    网上找了很多例子多数都不能运行。包括after,before,round,throw切入,可对类直接拦截,不需要定义接口文件,自己研究了2天整理出来的。 Spring AOP 的完整例子,可直接运行。带jar包。

    Spring IOC和AOP代码与笔记整理

    5. 配置Spring容器,可以是XML配置或使用`@Configuration`注解的Java配置类。 6. 编写测试类,通过ApplicationContext获取Bean并调用相关方法,观察AOP的通知是否按预期执行。 通过这样的实践,你不仅可以掌握...

    个人整理的关于AOP概念

    Spring支持JDK动态代理和CGLIB代理,前者适用于实现了接口的对象,后者则可用于任意类。 #### 五、总结 AOP通过将横切关注点从业务逻辑中抽离,提升了代码的结构化程度和复用性。在Spring框架中,AOP的实现不仅...

    Aop记录执行时间.pdf

    3. 注解和反射(Reflection):在本例中,使用了("@Aspect"注解来标记LogTimeAspect类为一个切面, "@Around"注解定义了一个环绕通知(advice),环绕通知可以在目标方法执行前后提供自定义的行为,通过反射获取目标...

    java-用Java动态代理实现AOP.pdf

    Spring AOP同样基于代理模式,但支持在方法调用前后加入额外的行为(advice),且能够与Spring IoC容器无缝集成。 8. 日志记录:在文档给出的实现示例中,日志记录是一种典型的横切关注点。通过在 ...

    Spring 面试题和答案.zip

    3. Java配置类:进一步简化,Spring 3.0引入了基于Java的配置,通过@Configuration和@Bean注解实现。 三、Spring AOP 1. 面向切面编程:AOP允许开发者定义“横切关注点”,如日志、事务管理等,将它们与业务逻辑...

    spring源码学习

    4. **事务管理**:Spring提供声明式和编程式事务管理,理解TransactionManager接口及其实现,以及@Transactional注解的使用。 5. **数据访问**:包括JDBC抽象、ORM支持(如Hibernate、MyBatis)等,理解Spring如何...

    spring的学习笔记

    Spring框架是Java开发中广泛使用的轻量级框架,以其依赖注入(Dependency Injection,简称DI)和面向切面编程(Aspect-Oriented Programming,简称AOP)的核心特性,极大地简化了企业级应用的开发。以下是对Spring...

    Spring框架

    - **JDK动态代理**:Spring AOP机制中常用的一种动态代理技术,它允许在运行时动态地创建一个实现接口的代理类。 - **AOP术语**:了解Spring AOP的关键术语,如切面(Aspect)、连接点(JoinPoint)、通知(Advice)...

    spring学习笔记共10页.pdf.zip

    笔记可能会介绍Aspect、Join Point、Advice、Pointcut等AOP概念,并展示如何使用Spring AOP进行切面定义和织入。 再者,Spring MVC是Spring框架用于构建Web应用程序的模块,它提供了模型-视图-控制器架构模式的实现...

    【面试】Spring事务面试考点吐血整理(建议珍藏)

    * 使用SpringTransactionAnnotationParser类来解析Spring提供的事务注解。 * 事务属性继承了事务定义接口,用于描述事务的特性。 五、总结 * Spring事务的实现机制是基于AOP切面编程和代理机制的。 * 事务的基本...

    个人整理的3年以上JAVA开发面试资料

    2. **使用场景**:在项目中,我们可以利用Spring AOP来进行切面编程,例如在方法调用前后插入日志记录、性能监控等功能,通过定义切入点(Pointcut)、通知(Advice)等元素,实现对业务逻辑的无侵入式增强。...

    java高级面试框架整理

    - **BeanFactory与ApplicationContext:** Spring提供了两个核心接口——BeanFactory和ApplicationContext,前者是最基础的工厂接口,后者提供了更丰富的应用上下文环境。 **2. Spring的IoC容器** - **Bean的生命...

    aop的实现原理_动力节点Java学院整理

    在Spring AOP中,切面可以是一个通知(Advice)加上一个或多个点cut。通知定义了何时执行切面代码,而切点定义了哪些方法或类会被通知影响。利用Spring AOP,开发者可以以声明的方式定义通知,以及如何通过切点与...

    java后端面试整理.pdf

    代理模式用于实现AOP,模板方法模式如jdbcTemplate和hibernateTemplate用于数据库操作,包装器模式用于需要连接多个数据库的情况,观察者模式是Spring事件驱动的基础,适配器模式在SpringAOP中用于增强或者advice。...

    JAVA面试题总览[整理].pdf

    6. Spring的生命周期管理包括初始化、使用、销毁等阶段,非单例注入使用Prototype scope,循环注入通过依赖注入和集合类实现,AOP实现原理基于动态代理,如JDK或CGLIB。 【操作系统】 1. Linux内核参数涉及调度、...

    2017年阿里Java基础面试题文档

    - **实现方式**:Spring框架通过代理模式实现AOP,主要有两种代理方式:JDK动态代理和CGLIB动态代理。前者基于接口,后者基于继承。 - **核心概念**:AOP涉及几个核心概念,包括切面(Aspect)、连接点(Join Point...

    java技术面试题目及答案

    - **A:** Spring AOP(面向切面编程)提供了一种在不修改源代码的情况下,向程序添加额外功能的方式,如日志记录、事务管理。它通过定义切面(Aspect)、通知(Advice)和连接点(Join Point)实现。 以上只是Java...

Global site tag (gtag.js) - Google Analytics