现在的位置: 首页 > 综合 > 正文

Spring AOP环绕型Advice简单例子

2012年09月12日 ⁄ 综合 ⁄ 共 2934字 ⁄ 字号 评论关闭

        刚开始学习到Spring AOP的时候,看那些神马连接点,切面,通知之类的概念,完全理解不了,一头雾水。后来照着书敲代码上去运行,成功以后,仔细看看代码,稍作琢磨,再看看那些概念的描述,恍然大悟,哇哦,原来是这样,其实是那么简单。

       所以,感觉很多知识不懂的时候,觉得那个东西特别难特别牛逼,当你明白了以后,发现原来也没神马大不了的。

       我觉得学习这些东西先从简单的应用例子开始,然后再慢慢的体会理论上的东西才是正确的方法。

       所以,要学懂Spring 的AOP,我们也从简单的例子开始吧。下面是一个简单的环绕型Advice的例子。

      情景:我们要调用某个业务逻辑类的某个方法,并且需要在调用方法之前做一些其他处理,比如打个日志之类的,然后调用业务逻辑方法,调用结束后我们又想做一些其他事情,比如还是打一条日志。这样我们就可以用注入环绕型通知的方式来完成了,这一点和Struts2的拦截器非常相似,几乎一样。

     1、新建业务逻辑接口

package leon.springaop.iface;

public interface UserDao {
	public String getUserList();
}

  2、业务逻辑接口实现类,也就是真实的业务逻辑类

package leon.springaop.impl;

import leon.springaop.iface.UserDao;

public class UserDaoImpl implements UserDao {

	@Override
	public void getUserList() {
		System.out.println("UserDaoImpl-getUserList()...");
		System.out.println("get User List form database...");
	}
}

  3、环绕型通知(调用方法之前和之后要做的事情在这里定义)

package leon.springaop.advice;

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

//Around拦截器实现MethodInterceptor接口
public class AroundInterceptor implements MethodInterceptor {
	// 实现MethodInterceptor接口必须实现invoke方法
	public Object invoke(MethodInvocation invocation) throws Throwable {
		System.out.println("Before business logic...");
		Object rval = invocation.proceed();
		System.out.println("After business logic...");
		return rval;
	}
}

  4、Spring的bean配置文件,比如 springaop.xml
  主要配置三个东西:

  (1) 将真实业务实现类配置成为bean

  (2) 将Advice类配置成为 bean

  (3) 配置真实业务逻辑代理

<?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="userDao" class="leon.springaop.impl.UserDaoImpl" />	
	<bean id="myAroundInterceptor" class="leon.springaop.advice.AroundInterceptor" />
			
	<bean id="userProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
		<property name="proxyInterfaces" value="leon.springaop.iface.UserDao"/>
		<property name="target" ref="userDao" />
		<property name="interceptorNames">
			<list>
				<value>myAroundInterceptor</value>
			</list>
		</property>
	</bean>
	
</beans>

说明:业务逻辑代理,使用了org.springframework.aop.framework.ProxyFactoryBean,这是个代理工厂bean,该bean主要注入3个变量proxyInterfaces, target, interceptorNames,其中interceptorNames是拦截器,也是通知,属List类型,可以注入多个拦截器,也就是添加多个value,这样就会按先后顺序进行层层递归拦截。

  5、调用测试

package leon.springaop.test;

import leon.springaop.iface.UserDao;

import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;

public class TestAround {
	public static void main(String[] args) {
		Resource rsc = new ClassPathResource("springaop.xml"); //这种方式springaop.xml保存在工程源文件目录下
		BeanFactory bf = new XmlBeanFactory(rsc);
		UserDao userProxy = (UserDao)bf.getBean("userProxy");		
		userProxy.getUserList();	//proxy invoke the business logic
	}
}

运行这个类:

Before business logic...

UserDaoImpl-getUserList()...

get User List form database

After business logic...

OK,效果出来了。

现在你可以翻开书,或者其他资料去看看那些连接点,切点,切面等概念了,很容易的。

另外,Advice除了上面的环绕型通知,还有前置型、后置型、抛异常,共4种。

每种Advice的定义都是要集成相应的类或者实现相应的接口。

比如上面的环绕型Advice实现了MethodInterceptor接口。

抱歉!评论已关闭.