Spring从菜鸟到高手(二)AOP的真正实现
来源:互联网 发布:女高中生知乎 编辑:程序博客网 时间:2024/05/29 14:43
经过了前面一章的学习大家基本理解了SpringAOP的简单工作原理,但是那只是最基本的一些操作,Spring的设计师们知道我们不想在诸如得到一个代理类、需要实现哪些接口 这些琐碎的事情上牵扯过多的经历,毕竟我们是中国软件产业的栋梁我们还要做更重要的事情。^_^ 所以他们给我们准备了好多好东西,下面我就来介绍一下
拦截器接口MethodBeforeAdvice 所在包org.springframework.aop.MethodBeforeAdvice
功能:可以在调用的目标方法之前加入功能。方法:
void
before(Method method,Object[] args,Object target)
拦截器接口AfterReturningAdvice 所在包org.springframework.aop.AfterReturningAdvice
功能:可以在调用的目标方法之后加入功能。方法:
void
afterReturning(Object returnValue,Method method,Object[] args,Object target)
拦截器接口MethodInterceptor 所在包 org.aopalliance.intercept.MethodInterceptor
功能:可以在调用的目标方法前后(也可以叫周围)加入功能。方法:
java.lang.Object
invoke(MethodInvocation invocation)
接口MethodInvocation 所在包 org.aopalliance.intercept.MethodInvocation
MethodInvocation 接口从父接口Joinpoint处继承到一个方法
java.lang.Object
proceed()
调用proceed方法方法用于执行目标类的目标方法。
下面我通过现实的代码来讲解Spring中AOP的使用方法,我还使用我以前例子中的接口Foo和实现此接口的类FooClass【开发环境为Eclipse】
便于大家阅读我将全部代码贴上来,首先是接口Foo,我在这个接口中增加了一个打印整数的方法
public interface Foo {
public void printMessage(String message);
public void printInteger(int num);
}
public void printMessage(String message);
public void printInteger(int num);
}
实现Foo接口的类FooClass
public class FooClass implements Foo {
public void printMessage(String message) {
System.out.println(this.getClass().getName()+" "+message);
}
public void printInteger(int num)
{
System.out.println(this.getClass().getName()+" "+num);
}
}
System.out.println(this.getClass().getName()+" "+message);
}
public void printInteger(int num)
{
System.out.println(this.getClass().getName()+" "+num);
}
}
实现上面三个拦截器接口【AfterReturningAdvice,MethodBeforeAdvice,MethodInterceptor 】的类MyAdvice
import java.lang.reflect.Method;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.aop.AfterReturningAdvice;
import org.springframework.aop.MethodBeforeAdvice;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.aop.AfterReturningAdvice;
import org.springframework.aop.MethodBeforeAdvice;
public class MyAdvice implements AfterReturningAdvice,MethodBeforeAdvice,MethodInterceptor
{
{
public void afterReturning(Object arg0, Method arg1, Object[] arg2,
Object arg3) throws Throwable {
Log log = LogFactory.getLog(MyAfterReturningAdvice.class);
log.info("我在程序运行之后出现");
}
Object arg3) throws Throwable {
Log log = LogFactory.getLog(MyAfterReturningAdvice.class);
log.info("我在程序运行之后出现");
}
public void before(Method arg0, Object[] arg1, Object arg2) throws Throwable {
Log log = LogFactory.getLog(MyAfterReturningAdvice.class);
log.info("我在程序运行之前出现");
}
Log log = LogFactory.getLog(MyAfterReturningAdvice.class);
log.info("我在程序运行之前出现");
}
public Object invoke(MethodInvocation arg0) throws Throwable {
Log log = LogFactory.getLog(MyAfterReturningAdvice.class);
log.info("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$");
Object obj = arg0.proceed();
log.info("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$");
return obj;
}
log.info("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$");
Object obj = arg0.proceed();
log.info("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$");
return obj;
}
}
由于我使用的Junit测试,所以有一个Junit测试类AOPJunitTest
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import junit.framework.TestCase;
public class AOPJunitTest extends TestCase {
ApplicationContext act = null; //使用的应用上下文类
protected void setUp() throws Exception {
super.setUp();
this.act = new ClassPathXmlApplicationContext("/applicationContext.xml");//读取XML配置文件
}
public void testprintMessage()
{
Foo foo = (Foo)act.getBean("proxy");//通过依赖注入得到FooClass对象的实例这个对象是Spring的一个类 org.springframework.aop.framework.ProxyFactoryBean这个类需要三个注入分别是
ApplicationContext act = null; //使用的应用上下文类
protected void setUp() throws Exception {
super.setUp();
this.act = new ClassPathXmlApplicationContext("/applicationContext.xml");//读取XML配置文件
}
public void testprintMessage()
{
Foo foo = (Foo)act.getBean("proxy");//通过依赖注入得到FooClass对象的实例这个对象是Spring的一个类 org.springframework.aop.framework.ProxyFactoryBean这个类需要三个注入分别是
void
setTarget(Object target)
得到注入一个目标对象(真正要干活的类)void
setProxyInterfaces(String[] interfaceNames)
目标对象所实现的接口数组void
setInterceptorNames(String[] interceptorNames)
拦截器数组(因为我们有多种拦截器)foo.printMessage("Hello!");
foo.printInteger(20);
}
}
下面是我们的XML配置文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "[url]http://www.springframework.org/dtd/spring-beans.dtd[/url]">
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "[url]http://www.springframework.org/dtd/spring-beans.dtd[/url]">
<beans>
<bean id="proxy" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="target">
<ref bean="fooClass"/>
</property>
<property name="proxyInterfaces">
<value>Foo</value>
</property>
<property name="interceptorNames">
<list>
<value>interceptorReturning</value>
</list>
</property>
</bean>
<bean id="fooClass" class="FooClass"></bean>
<bean id="interceptorReturning" class="MyAdvice"></bean>
</beans>
<bean id="proxy" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="target">
<ref bean="fooClass"/>
</property>
<property name="proxyInterfaces">
<value>Foo</value>
</property>
<property name="interceptorNames">
<list>
<value>interceptorReturning</value>
</list>
</property>
</bean>
<bean id="fooClass" class="FooClass"></bean>
<bean id="interceptorReturning" class="MyAdvice"></bean>
</beans>
程序运行结果
INFO - $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
INFO - 我在程序运行之前出现
FooClass Hello!
INFO - 我在程序运行之后出现
INFO - $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
INFO - $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
INFO - 我在程序运行之前出现
FooClass 20
INFO - 我在程序运行之后出现
INFO - $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
INFO - 我在程序运行之前出现
FooClass Hello!
INFO - 我在程序运行之后出现
INFO - $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
INFO - $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
INFO - 我在程序运行之前出现
FooClass 20
INFO - 我在程序运行之后出现
INFO - $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
本文出自 “绝缘材料” 博客,请务必保留此出处http://tonyaction.blog.51cto.com/227462/42040
- Spring从菜鸟到高手(二)AOP的真正实现
- Spring从菜鸟到高手(二)AOP的真正实现
- Spring从菜鸟到高手(二)AOP的真正实现
- Spring从菜鸟到高手(二)AOP的真正实现
- Spring从菜鸟到高手(一)实现AOP的基本原理
- Spring从菜鸟到高手(一)实现AOP的基本原理
- Spring从菜鸟到高手(一)实现AOP的基本原理
- Spring从菜鸟到高手(一)实现AOP的基本原理
- Spring从菜鸟到高手(四)(上)使用JdbcTemplate类实现用户登陆验证、批量更新
- Spring从菜鸟到高手(四)(下)使用JdbcTemplate类实现批量查询
- Spring从菜鸟到高手(四)(上)使用JdbcTemplate类实现用户登陆验证、批量更新
- Spring从菜鸟到高手(四)(下)使用JdbcTemplate类实现批量查询
- Spring从菜鸟到高手(三)依赖注入
- Spring从菜鸟到高手(三)依赖注入
- Spring从菜鸟到高手(三)依赖注入
- Java之美[从菜鸟到高手演变]之Spring中Quartz调度器的使用
- Java之美[从菜鸟到高手演变]之线程同步的引入(二)
- Java之美[从菜鸟到高手演练]之JDK动态代理的实现及原理
- UTF-8规范
- 获取子窗口句柄EnumChildWindows的威力
- Spring从菜鸟到高手(一)实现AOP的基本原理
- Faster Datanodes with less wait io using df instead of du
- winform下UPD通信的简单应用
- Spring从菜鸟到高手(二)AOP的真正实现
- 常见加密算法分,用途,原理以及比较
- Spring从菜鸟到高手(三)依赖注入
- 常见加密算法分类
- Ubuntu 12.04 编译内核步骤 + Fedora 10 编译内核步骤(图)
- SSL算法库的理解与测试
- 现实迷途 第二十五章 重见故人
- mysql替换语句 部分替换
- IT程序员,为什么会无奈苦逼