struts2拦截器实现原理案例分析
2012-03-07 22:28
387 查看
今天学习了struts2的拦截器的相关知识。下面是自己自定义的一个拦截器的实现原理。下面为大家解析一下编写一个自定义拦截器原理的步骤及代码。
大部分时候,拦截器方法都是通过代理的方式来调用的,下面以JDK动态代理为例来介绍如何调用拦截器方法。
第一步:
首先要定义一个简单的Dog接口,因为JDK动态代理只能对实现了接口的实例来生成代理,因此必须提供一个Dog接口,该接口代码非常简单。在接口中要定义两个简单的方法。
public interface Dog {
//狗的信息
public void info();
//狗跑
public void run();
}
第二步:
在以上接口中,并没有实现其方法,为了能正常使用Dog实例,必须要提供一个该接口的实现类。实现类的代码:如下:
public class DogImpl implements Dog{
public void info() {
//info方法实现,仅仅打印一个字符串
System.out.println("他是一只小猎狗!");
}
public void run() {
// run方法实现,仅仅打印一个字符串
System.out.println("他奔跑迅速!");
}
}
第三步:
下面就来编写一个拦截Dog实例的拦截器。
系统用于拦截Dog实例的拦截器类如下:
public class DogInterceptor {
//第一个拦截器的方法
public void log(){
System.out.println("*****通用方法一******");
}
//第二个拦截器的方法
public void safe(){
System.out.println("*****通用方法二******");
}
}
通过以上的拦截器,它也是一个普通的java类。假设我们需要上面的info方法执行前后分别调用拦截器里的方法,系统应该如何来实现呢?关键是要编写ProxyHandler类。该类需要实现InvocationHandler接口,该接口是JDK反射体系里的一个接口,它可以动态调用目标对象的方法。
ProxyHandler类的代码如下:
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class ProxyHandler implements InvocationHandler{
//需要声明被代理的目标对象
private Object target;
//创建一个拦截器的实例
DogInterceptor dogInterceptor = new DogInterceptor();
//执行代理目标方法的时候,该invoke被自动调用
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
Object result = null;
//proxy
//method方法
if(method.getName().equals("info")){
dogInterceptor.log();
result = method.invoke(target, args);
dogInterceptor.safe();
}else{
result = method.invoke(target, args);
}
//args方法参数
return result;
}
public Object getTarget() {
return target;
}
public void setTarget(Object target) {
this.target = target;
}
}
第四步:
通过ProxyHandler的帮助,系统实现了在执行info方法之前,调用拦截器的method方法:在指定info方法之后,调用拦截器的run方法。
只因为上面类与被拦截对象没有丝毫耦合,从而提供了更好解耦,以及更好的可扩展性。但上面的类与两个地方耦合了:
(1) 与拦截器类耦合:上面类固定使用DogIntercepter拦截器。
(2) 与被拦截器的方法耦合:上面类指定拦截名为info的方法。
系统还需要提供一个代理工厂,代理工厂的主要作用就是根据目标对象生成一个代理对象。
下面就是一个代理工厂类的代码:
package cn.csdn.hr.jdk.inter;
import java.lang.reflect.Proxy;
//根据目标对象 产生代理对象
public class MyProxyFactory {
public static Object getProxy(Object target){
//创建代理类的处理类
ProxyHandler proxyHandler = new ProxyHandler();
//传递目标对象 到代理对象中
proxyHandler.setTarget(target);
return Proxy.newProxyInstance(DogImpl.class.getClassLoader(),target.getClass().getInterfaces(),proxyHandler);
}
}
第五步:
通过这种方式,实现了在目标方法之前或者之后,自动调用拦截器方法的目的。
下面是测试的方法,代码如下:
public class DogTest {
public static void main(String[] args){
Dog targetDog = new DogImpl();
Object proxy = MyProxyFactory.getProxy(targetDog);
Dog dog = null;
if(proxy instanceof Dog){
dog = (Dog) proxy;
}
if(dog != null){
dog.info();
dog.run();
}
}
}
第六步:
上面的代码先是创建了一个Dog实例作为目标对象,然后以该目标对象,创建该对象的搭理对象——代理对象里的方法,是拦截器方法和目标对象方法的组合,这就是为什么可以在执行目标方法的前后,执行拦截器方法的原因。
上面程序执行后的结果:
*****通用方法一******
他是一只小猎狗!
*****通用方法二******
他奔跑迅速!
大部分时候,拦截器方法都是通过代理的方式来调用的,下面以JDK动态代理为例来介绍如何调用拦截器方法。
第一步:
首先要定义一个简单的Dog接口,因为JDK动态代理只能对实现了接口的实例来生成代理,因此必须提供一个Dog接口,该接口代码非常简单。在接口中要定义两个简单的方法。
public interface Dog {
//狗的信息
public void info();
//狗跑
public void run();
}
第二步:
在以上接口中,并没有实现其方法,为了能正常使用Dog实例,必须要提供一个该接口的实现类。实现类的代码:如下:
public class DogImpl implements Dog{
public void info() {
//info方法实现,仅仅打印一个字符串
System.out.println("他是一只小猎狗!");
}
public void run() {
// run方法实现,仅仅打印一个字符串
System.out.println("他奔跑迅速!");
}
}
第三步:
下面就来编写一个拦截Dog实例的拦截器。
系统用于拦截Dog实例的拦截器类如下:
public class DogInterceptor {
//第一个拦截器的方法
public void log(){
System.out.println("*****通用方法一******");
}
//第二个拦截器的方法
public void safe(){
System.out.println("*****通用方法二******");
}
}
通过以上的拦截器,它也是一个普通的java类。假设我们需要上面的info方法执行前后分别调用拦截器里的方法,系统应该如何来实现呢?关键是要编写ProxyHandler类。该类需要实现InvocationHandler接口,该接口是JDK反射体系里的一个接口,它可以动态调用目标对象的方法。
ProxyHandler类的代码如下:
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class ProxyHandler implements InvocationHandler{
//需要声明被代理的目标对象
private Object target;
//创建一个拦截器的实例
DogInterceptor dogInterceptor = new DogInterceptor();
//执行代理目标方法的时候,该invoke被自动调用
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
Object result = null;
//proxy
//method方法
if(method.getName().equals("info")){
dogInterceptor.log();
result = method.invoke(target, args);
dogInterceptor.safe();
}else{
result = method.invoke(target, args);
}
//args方法参数
return result;
}
public Object getTarget() {
return target;
}
public void setTarget(Object target) {
this.target = target;
}
}
第四步:
通过ProxyHandler的帮助,系统实现了在执行info方法之前,调用拦截器的method方法:在指定info方法之后,调用拦截器的run方法。
只因为上面类与被拦截对象没有丝毫耦合,从而提供了更好解耦,以及更好的可扩展性。但上面的类与两个地方耦合了:
(1) 与拦截器类耦合:上面类固定使用DogIntercepter拦截器。
(2) 与被拦截器的方法耦合:上面类指定拦截名为info的方法。
系统还需要提供一个代理工厂,代理工厂的主要作用就是根据目标对象生成一个代理对象。
下面就是一个代理工厂类的代码:
package cn.csdn.hr.jdk.inter;
import java.lang.reflect.Proxy;
//根据目标对象 产生代理对象
public class MyProxyFactory {
public static Object getProxy(Object target){
//创建代理类的处理类
ProxyHandler proxyHandler = new ProxyHandler();
//传递目标对象 到代理对象中
proxyHandler.setTarget(target);
return Proxy.newProxyInstance(DogImpl.class.getClassLoader(),target.getClass().getInterfaces(),proxyHandler);
}
}
第五步:
通过这种方式,实现了在目标方法之前或者之后,自动调用拦截器方法的目的。
下面是测试的方法,代码如下:
public class DogTest {
public static void main(String[] args){
Dog targetDog = new DogImpl();
Object proxy = MyProxyFactory.getProxy(targetDog);
Dog dog = null;
if(proxy instanceof Dog){
dog = (Dog) proxy;
}
if(dog != null){
dog.info();
dog.run();
}
}
}
第六步:
上面的代码先是创建了一个Dog实例作为目标对象,然后以该目标对象,创建该对象的搭理对象——代理对象里的方法,是拦截器方法和目标对象方法的组合,这就是为什么可以在执行目标方法的前后,执行拦截器方法的原因。
上面程序执行后的结果:
*****通用方法一******
他是一只小猎狗!
*****通用方法二******
他奔跑迅速!
相关文章推荐
- struts2源码分析及拦截器实现原理
- Struts2中拦截器实现AOP的原理分析
- Struts2之拦截器原理分析及使用-上
- 浅谈Struts2拦截器的原理与实现
- mybatis -- 由浅入深分析mybatis通过动态代理实现拦截器(插件)的原理
- Struts2系统学习(10)文件上传与下载案例及原理分析
- 由浅入深分析mybatis通过动态代理实现拦截器(插件)的原理
- Java程序员从笨鸟到菜鸟之(四十六)细谈struts2(八)拦截器的实现原理及源码剖析
- Struts2拦截器的原理与实现
- 浅谈Struts2拦截器的原理与实现
- struts2 拦截器的原理和实现
- 由浅入深分析mybatis通过动态代理实现拦截器(插件)的原理
- Java程序员从笨鸟到菜鸟之(四十六)细谈struts2(八)拦截器的实现原理及源码剖析
- struts2拦截器的实现原理及源码剖析
- Struts2拦截器的原理与实现
- 细谈struts2(八)拦截器的实现原理及源码剖析
- struts2拦截器的实现原理及源码剖析
- struts2拦截器的实现原理及源码剖析
- 浅谈Struts2拦截器的原理与实现
- Struts2拦截器的实现原理及源码剖析