- 浏览: 230050 次
- 性别:
- 来自: 上海
最新评论
-
iwindyforest:
pinocchio2mx 写道iwindyforest 写道H ...
VMware Workstation 11 或者 VMware Player 7安装MAC OS X 10.10 Yosemite -
nng119:
找不到设备的安装信息 这个问题怎么解决的?
VMware Workstation 11 或者 VMware Player 7安装MAC OS X 10.10 Yosemite -
pinocchio2mx:
iwindyforest 写道Hi pinocchio2mx ...
VMware Workstation 11 或者 VMware Player 7安装MAC OS X 10.10 Yosemite -
iwindyforest:
Hi pinocchio2mx 兄弟, 这个镜像是好的, 我安 ...
VMware Workstation 11 或者 VMware Player 7安装MAC OS X 10.10 Yosemite -
pinocchio2mx:
蛋疼啊,折腾一晚上还没搞定!网上的教程没一篇靠谱的,摸摸索索到 ...
VMware Workstation 11 或者 VMware Player 7安装MAC OS X 10.10 Yosemite
AOP技术是spring框架的一个重要特征。通过该特性能够在函数运行之前,之后,或者异常处理的时候执行我们需要的一些操作。
下面我们就是需要抛开AOP,Spring这样成型的框架不用,而仅仅使用java反射机制中的Proxy,InvocationHandler来实现类似Spring框架的拦截器的效果。
动态代理DynamicProxy
首先,在设计这个拦截器框架之前,我们需要明白java中动态代理是什么?我想如果早就清楚请直接跳过,如果需要了解,那我想你手边最好有一个javadoc的电子书。
Java.lang.reflect.Proxy是反射包的成员之一。具体说明请查javadoc。
用法就是比如有一个对象,我们需要在调用它提供的方法之前,干点别的什么,就不能直接调用它,而是生成一个它的代理,这个代理有这个对象所提供的所有接口方法,我们通过直接调用代理的这些方法,来实现:函数既能像原来对象的那样工作,又能在函数运行过程前后加入我们自己的处理。
这个类有个非常重要的函数用来实现某个类的代理:
参数有点迷惑人,解释下:
ClassLoader 是类加载器,这个参数用来定义代理类,一般使用原对象的即可,也可以为null用上下文解决。
Class<?>[] 接口数组,就是我们需要这个代理能够提供原来的类的什么函数。如果全部则直接class.getInterfaces()来解决.
InvocationHandler 调用处理器,这个就是如果你调用代理的方法,那么这个处理器就会被关联过来,处理调用这个函数的整个过程。这个接口只定义了一个方法:
参数中proxy就是你调用的代理,method指的是你调用的代理的那个方法,args是传给该方法的参数。
我们生成某个类的代理步骤,一般需要先考虑我们在调用这个类的函数的时候(之前,或者之后)如何处理某些事情,因此我们首先考虑的就是如何实现InvocationHandler这个接口。
让我们做一个实践,做这么一个调用处理器:任何使用此处理器的代理在调用它的任何方法的时候,都打印被代理的类的类名+“.”+方法名+”(“+参数+”,”+参数+...+”)”。
步骤1: 定义接口IUser
步骤2: 写IUser接口的实现类User
步骤3: 写TraceHandler实现调用处理器InvocationHandler,即在invoke()方法里我们要打印被代理的类的类名+“.”+方法名+”(“+参数+”,”+参数+...+”)”。
步骤4: 最后,让我们写测试类ProxyTest
好了,所有代码写好了,运行一下,测试结果是:
com.cyh.proxy.impl.User.setName(David Beckham)
讲一下运行原理:
首先我们初始化了user对象,user.name = = “LaraCroft”;
然后创建了user对象的代理proxy。
注意这里:Proxy.newProxyInstance()函数的返回值使用接口IUser转型的,你或许会想到
用User来做强制类型转换,但是会抛出下面的异常
Exception in thread "main" java.lang.ClassCastException: $Proxy0 cannot be cast to com.cyh.proxy.impl.User
因为:代理类是实现了User类的所有接口,但是它的类型是$Proxy0,不是User。
最后,我们调用代理的setName()方法:
proxy.setName("David Beckham");
代理在执行此方法的时候,就好触发调用处理器 TraceHandler,并执行 TraceHandler的invoke()方法,然后就会打印:
com.cyh.proxy.impl.User.setName(David Beckham)
可重用拦截器机制的实现
好了,关于代理的知识我们讲完了,我们可以考虑如何实现这个拦截器的框架,所谓拦截器就是在函数的运行前后定制自己的处理行为,也就是通过实现InvocationHandler达到的。
设计思路
我们来理清一下思路,在使用一个拦截器的时候?什么是不变的,什么是变化的?
不变的:
每次都要创建代理
拦截的时间:函数执行之前,之后,异常处理的时候
变化的:
每次代理的对象不同
拦截器每次拦截到执行时的操作不同
好了,废话少说,看类图:
图中:
DynamicProxyFactory 和它的实现类,是一个工厂,用来创建代理
Interceptor 这个接口用来定义拦截器的拦截处理行为配合DynamicProxyInvocationHandler达到拦截效果
DynamicProxyInvocationHandler 调用处理器的实现,它有两个成员,一个是Object target指的是被代理的类,另一个是Interceptor interceptor就是在invoke()方法执行target的函数之前后,异常处理时,调用interceptor的实现来达到拦截,并处理的效果。
代码实现
步骤1: 定义接口DynamicProxyFactory
步骤2: 定义接口Interceptor
步骤3: 实现接口DynamicProxyFactory
步骤4: 实现调用处理器
好了,目前为止,这个框架算完成了,怎么用呢?
接下来我们完成测试包。
完成测试
步骤1: 首先,给需要代理的类定义一个接口Service
步骤2: 实现这个接口,编写类ServiceImpl
步骤3: 实现拦截器接口Interceptor,编写类InterceptorImpl
步骤4:编写测试类TestDynamicProxy
好了,整个测试包完成了,让我们运行下看看运行结果:
before invoking method: greet
Hello, iwindyforest
after invoking method: greet
afterFinally invoking method: greet
完善设计
现在,让我们回顾一下:接口DynamicProxyFactory,真的需要么?
它只是一个工厂,负责生产代理的,但是我们并没有过多的要求,因此可以说它的实现基本上是不变的。鉴于此,我们在使用createProxy()函数的时候,只需要一个静态方法就可以了,没有必要再初始化整个类,这样才比较方便么。
因此,我在com.cyh.proxy.interceptor.impl包里加了一个默认的工厂DefaultProxyFactory:
参考书籍:
Core java Volume I
深入浅出JDK6.0
P.S:本来想系统的写一下反射的学习笔记来,刚刚写了个开头,回来在看,发现写的东西真是很基本很基本,心想这样的东西放到java区没准就会被打到“新手区”了,因此还是没有写,不过临发这篇文章,我心里还是比较忐忑:又是一篇写轮子的文章,这次会不会又进新手区了?
说aop没啥,
写个类就是框架,框架就漫天飞了
-------------------
5楼增强了下,
楼下的哪位可以再加个序列化的类,rpc框架就出来了~
好像这年头,什么都是框架~ NB
下面我们就是需要抛开AOP,Spring这样成型的框架不用,而仅仅使用java反射机制中的Proxy,InvocationHandler来实现类似Spring框架的拦截器的效果。
动态代理DynamicProxy
首先,在设计这个拦截器框架之前,我们需要明白java中动态代理是什么?我想如果早就清楚请直接跳过,如果需要了解,那我想你手边最好有一个javadoc的电子书。
Java.lang.reflect.Proxy是反射包的成员之一。具体说明请查javadoc。
用法就是比如有一个对象,我们需要在调用它提供的方法之前,干点别的什么,就不能直接调用它,而是生成一个它的代理,这个代理有这个对象所提供的所有接口方法,我们通过直接调用代理的这些方法,来实现:函数既能像原来对象的那样工作,又能在函数运行过程前后加入我们自己的处理。
这个类有个非常重要的函数用来实现某个类的代理:
Object java.lang.reflect.Proxy.newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) throws IllegalArgumentException
参数有点迷惑人,解释下:
ClassLoader 是类加载器,这个参数用来定义代理类,一般使用原对象的即可,也可以为null用上下文解决。
Class<?>[] 接口数组,就是我们需要这个代理能够提供原来的类的什么函数。如果全部则直接class.getInterfaces()来解决.
InvocationHandler 调用处理器,这个就是如果你调用代理的方法,那么这个处理器就会被关联过来,处理调用这个函数的整个过程。这个接口只定义了一个方法:
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable;
参数中proxy就是你调用的代理,method指的是你调用的代理的那个方法,args是传给该方法的参数。
我们生成某个类的代理步骤,一般需要先考虑我们在调用这个类的函数的时候(之前,或者之后)如何处理某些事情,因此我们首先考虑的就是如何实现InvocationHandler这个接口。
让我们做一个实践,做这么一个调用处理器:任何使用此处理器的代理在调用它的任何方法的时候,都打印被代理的类的类名+“.”+方法名+”(“+参数+”,”+参数+...+”)”。
步骤1: 定义接口IUser
package com.cyh.proxy.sample; public interface IUser { public String getName(); public void setName(String name); }
步骤2: 写IUser接口的实现类User
package com.cyh.proxy.sample.impl; import com.cyh.proxy.sample.IUser; public class User implements IUser { String name; public User(String name) { this.name = name; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
步骤3: 写TraceHandler实现调用处理器InvocationHandler,即在invoke()方法里我们要打印被代理的类的类名+“.”+方法名+”(“+参数+”,”+参数+...+”)”。
package com.cyh.proxy.sample.impl; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; public class TraceHandler implements InvocationHandler { private Object target; public TraceHandler(Object target) { this.target = target; } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { // print implicit argument System.out.print(target.getClass().getName()); // print method name System.out.print("." + method.getName() + "("); // print explicit arguments if (args != null) { for (int i = 0; i < args.length; i++) { System.out.print(args[i]); if (i < args.length - 1) { System.out.print(","); } } } System.out.println(")"); return method.invoke(this.target, args); } }
步骤4: 最后,让我们写测试类ProxyTest
package com.cyh.proxy.sample.test; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Proxy; import com.cyh.proxy.sample.IUser; import com.cyh.proxy.sample.impl.TraceHandler; import com.cyh.proxy.sample.impl.User; public class ProxyTest { User user; public ProxyTest() { user = new User("LaraCroft"); ClassLoader classLoader = user.getClass().getClassLoader(); Class[] interfaces = user.getClass().getInterfaces(); InvocationHandler handler = new TraceHandler(user); IUser proxy = (IUser) Proxy.newProxyInstance(classLoader, interfaces, handler); proxy.setName("David Beckham"); } public static void main(String[] args) { new ProxyTest(); } }
好了,所有代码写好了,运行一下,测试结果是:
com.cyh.proxy.impl.User.setName(David Beckham)
讲一下运行原理:
首先我们初始化了user对象,user.name = = “LaraCroft”;
然后创建了user对象的代理proxy。
注意这里:Proxy.newProxyInstance()函数的返回值使用接口IUser转型的,你或许会想到
用User来做强制类型转换,但是会抛出下面的异常
Exception in thread "main" java.lang.ClassCastException: $Proxy0 cannot be cast to com.cyh.proxy.impl.User
因为:代理类是实现了User类的所有接口,但是它的类型是$Proxy0,不是User。
最后,我们调用代理的setName()方法:
proxy.setName("David Beckham");
代理在执行此方法的时候,就好触发调用处理器 TraceHandler,并执行 TraceHandler的invoke()方法,然后就会打印:
com.cyh.proxy.impl.User.setName(David Beckham)
可重用拦截器机制的实现
好了,关于代理的知识我们讲完了,我们可以考虑如何实现这个拦截器的框架,所谓拦截器就是在函数的运行前后定制自己的处理行为,也就是通过实现InvocationHandler达到的。
设计思路
我们来理清一下思路,在使用一个拦截器的时候?什么是不变的,什么是变化的?
不变的:
每次都要创建代理
拦截的时间:函数执行之前,之后,异常处理的时候
变化的:
每次代理的对象不同
拦截器每次拦截到执行时的操作不同
好了,废话少说,看类图:
图中:
DynamicProxyFactory 和它的实现类,是一个工厂,用来创建代理
Interceptor 这个接口用来定义拦截器的拦截处理行为配合DynamicProxyInvocationHandler达到拦截效果
DynamicProxyInvocationHandler 调用处理器的实现,它有两个成员,一个是Object target指的是被代理的类,另一个是Interceptor interceptor就是在invoke()方法执行target的函数之前后,异常处理时,调用interceptor的实现来达到拦截,并处理的效果。
代码实现
步骤1: 定义接口DynamicProxyFactory
package com.cyh.proxy.interceptor; public interface DynamicProxyFactory { /** * 生成动态代理,并且在调用代理执行函数的时候使用拦截器 * * @param clazz * 需要实现的接口 * @param target * 实现此接口的类 * @param interceptor * 拦截器 * @return */ public <T> T createProxy(T target, Interceptor interceptor); }
步骤2: 定义接口Interceptor
package com.cyh.proxy.interceptor; import java.lang.reflect.Method; public interface Interceptor { public void before(Method method, Object[] args); public void after(Method method, Object[] args); public void afterThrowing(Method method, Object[] args, Throwable throwable); public void afterFinally(Method method, Object[] args); }
步骤3: 实现接口DynamicProxyFactory
package com.cyh.proxy.interceptor.impl; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Proxy; import com.cyh.proxy.interceptor.DynamicProxyFactory; import com.cyh.proxy.interceptor.Interceptor; public class DynamicProxyFactoryImpl implements DynamicProxyFactory { /** * 生成动态代理,并且在调用代理执行函数的时候使用拦截器 * * @param target * 需要代理的实例 * @param interceptor * 拦截器实现,就是我们希望代理类执行函数的前后, * 抛出异常,finally的时候去做写什么 */ @Override @SuppressWarnings("unchecked") public <T> T createProxy(T target, Interceptor interceptor) { // 当前对象的类加载器 ClassLoader classLoader = target.getClass().getClassLoader(); // 获取此对象实现的所有接口 Class<?>[] interfaces = target.getClass().getInterfaces(); // 利用DynamicProxyInvocationHandler类来实现InvocationHandler InvocationHandler handler = new DynamicProxyInvocationHandler(target, interceptor); return (T) Proxy.newProxyInstance(classLoader, interfaces, handler); } }
步骤4: 实现调用处理器
package com.cyh.proxy.interceptor.impl; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import com.cyh.proxy.interceptor.Interceptor; /** * 动态代理的调用处理器 * * @author chen.yinghua */ public class DynamicProxyInvocationHandler implements InvocationHandler { private Object target; private Interceptor interceptor; /** * @param target * 需要代理的实例 * @param interceptor * 拦截器 */ public DynamicProxyInvocationHandler(Object target, Interceptor interceptor) { this.target = target; this.interceptor = interceptor; } /** * @param proxy * 所生成的代理对象 * @param method * 调用的方法示例 * @args args 参数数组 * @Override */ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object result = null; try { // 在执行method之前调用interceptor去做什么事 this.interceptor.before(method, args); // 在这里我们调用原始实例的method result = method.invoke(this.target, args); // 在执行method之后调用interceptor去做什么事 this.interceptor.after(method, args); } catch (Throwable throwable) { // 在发生异常之后调用interceptor去做什么事 this.interceptor.afterThrowing(method, args, throwable); throw throwable; } finally { // 在finally之后调用interceptor去做什么事 interceptor.afterFinally(method, args); } return result; } }
好了,目前为止,这个框架算完成了,怎么用呢?
接下来我们完成测试包。
完成测试
步骤1: 首先,给需要代理的类定义一个接口Service
package com.cyh.proxy.interceptor.test; public interface Service { public String greet(String name); }
步骤2: 实现这个接口,编写类ServiceImpl
package com.cyh.proxy.interceptor.test; public class ServiceImpl implements Service { @Override public String greet(String name) { String result = "Hello, " + name; System.out.println(result); return result; } }
步骤3: 实现拦截器接口Interceptor,编写类InterceptorImpl
package com.cyh.proxy.interceptor.test; import java.lang.reflect.Method; import com.cyh.proxy.interceptor.Interceptor; public class InterceptorImpl implements Interceptor { @Override public void after(Method method, Object[] args) { System.out.println("after invoking method: " + method.getName()); } @Override public void afterFinally(Method method, Object[] args) { System.out.println("afterFinally invoking method: " + method.getName()); } @Override public void afterThrowing(Method method, Object[] args, Throwable throwable) { System.out.println("afterThrowing invoking method: " + method.getName()); } @Override public void before(Method method, Object[] args) { System.out.println("before invoking method: " + method.getName()); } }
步骤4:编写测试类TestDynamicProxy
package com.cyh.proxy.interceptor.test; import com.cyh.proxy.interceptor.DynamicProxyFactory; import com.cyh.proxy.interceptor.Interceptor; import com.cyh.proxy.interceptor.impl.DynamicProxyFactoryImpl; public class TestDynamicProxy { public TestDynamicProxy() { DynamicProxyFactory dynamicProxyFactory = new DynamicProxyFactoryImpl(); Interceptor interceptor = new InterceptorImpl(); Service service = new ServiceImpl(); Service proxy = dynamicProxyFactory.createProxy(service, interceptor); // Service proxy = DefaultProxyFactory.createProxy(service, // interceptor); proxy.greet("iwindyforest"); } public static void main(String[] args) { new TestDynamicProxy(); } }
好了,整个测试包完成了,让我们运行下看看运行结果:
before invoking method: greet
Hello, iwindyforest
after invoking method: greet
afterFinally invoking method: greet
完善设计
现在,让我们回顾一下:接口DynamicProxyFactory,真的需要么?
它只是一个工厂,负责生产代理的,但是我们并没有过多的要求,因此可以说它的实现基本上是不变的。鉴于此,我们在使用createProxy()函数的时候,只需要一个静态方法就可以了,没有必要再初始化整个类,这样才比较方便么。
因此,我在com.cyh.proxy.interceptor.impl包里加了一个默认的工厂DefaultProxyFactory:
package com.cyh.proxy.interceptor.impl; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Proxy; import com.cyh.proxy.interceptor.Interceptor; public class DefaultProxyFactory { @SuppressWarnings("unchecked") public static <T> T createProxy(T target, Interceptor interceptor) { // 当前对象的类加载器 ClassLoader classLoader = target.getClass().getClassLoader(); // 获取此对象实现的所有接口 Class<?>[] interfaces = target.getClass().getInterfaces(); // 利用DynamicProxyInvocationHandler类来实现InvocationHandler InvocationHandler handler = new DynamicProxyInvocationHandler(target, interceptor); return (T) Proxy.newProxyInstance(classLoader, interfaces, handler); } }
参考书籍:
Core java Volume I
深入浅出JDK6.0
P.S:本来想系统的写一下反射的学习笔记来,刚刚写了个开头,回来在看,发现写的东西真是很基本很基本,心想这样的东西放到java区没准就会被打到“新手区”了,因此还是没有写,不过临发这篇文章,我心里还是比较忐忑:又是一篇写轮子的文章,这次会不会又进新手区了?
评论
10 楼
jacky68147527
2009-08-25
写的不错,支持一下!
9 楼
kimmking
2009-03-03
云中苍月 写道
很支持楼主!不断的思考,不断的实践。
造自己的轮子,让别人说去吧。
造自己的轮子,让别人说去吧。
说aop没啥,
写个类就是框架,框架就漫天飞了
-------------------
5楼增强了下,
楼下的哪位可以再加个序列化的类,rpc框架就出来了~
好像这年头,什么都是框架~ NB
8 楼
云中苍月
2009-03-03
很支持楼主!不断的思考,不断的实践。
造自己的轮子,让别人说去吧。
造自己的轮子,让别人说去吧。
7 楼
kimmking
2009-03-03
很基本,很低效
动态代理的使用 讲的还是很清楚的~~
动态代理的使用 讲的还是很清楚的~~
6 楼
kekeemx
2009-03-03
最近刚好在看反射方面的东西.不错的入门级资料。
5 楼
iwindyforest
2008-11-16
to jander:
:D 不错,好想法,谢谢你!
引用
给你增强一下,实现aop链。
:D 不错,好想法,谢谢你!
4 楼
jander
2008-11-03
给你增强一下,实现aop链。
public class DynamicProxyInvocationHandler implements InvocationHandler { private Object target; private Interceptor[] interceptors; /** * @param target * 需要代理的实例 * @param interceptor * 拦截器 */ public DynamicProxyInvocationHandler(Object target, Interceptor[] interceptorList) { this.target = target; this.interceptors = interceptorList; } /** * @param proxy * 所生成的代理对象 * @param method * 调用的方法示例 * @args args 参数数组 * @Override */ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object result = null; try { // 在执行method之前调用interceptor去做什么事 for(Interceptor interceptor :interceptors){ interceptor.before(method, args); } // 在这里我们调用原始实例的method result = method.invoke(this.target, args); // 在执行method之后调用interceptor去做什么事 for(Interceptor interceptor :interceptors){ interceptor.after(method, args); } } catch (Throwable throwable) { for(Interceptor interceptor :interceptors){ interceptor.afterThrowing(method, args, throwable); } throw throwable; } finally { // 在finally之后调用interceptor去做什么事 for(Interceptor interceptor :interceptors){ interceptor.afterFinally(method, args); } } return result; } } public class DynamicProxyFactory { @SuppressWarnings("unchecked") public static <T> T getProxyInstance(T target, Interceptor[] interceptors) { // 当前对象的类加载器 ClassLoader classLoader = target.getClass().getClassLoader(); // 获取此对象实现的所有接口 Class<?>[] interfaces = target.getClass().getInterfaces(); // 利用DynamicProxyInvocationHandler类来实现InvocationHandler InvocationHandler handler = new DynamicProxyInvocationHandler(target, interceptors); return (T) Proxy.newProxyInstance(classLoader, interfaces, handler); } }
3 楼
cun2001
2008-10-30
写得不错,挺适合java反射、代理以及AOP入门的,代码有点小问题:InterceptorImpl.java每个方法前不能加@Override,道理楼主应该知道,因为InterceptorImpl类是实现Interceptor接口而不是继承,文章有些错别字,不过这些都是小问题,不过楼主精神挺好,赞一个!也不知楼主现在找到中意的东家没,如果还没有,也不用太着急,是金子总会发光的,是人才总不会被埋没的,我看好你,希望你找个好工作!
2 楼
Joo
2008-08-31
1 楼
taupo
2008-08-30
楼主,抛开新旧轮子的考虑,有没有想过反射的效率太低了?
发表评论
-
One of the Best Bits of Programming Advice I ever Got
2011-11-28 20:31 1353from: http://objology.blogspot. ... -
通用职责分配软件模式(GRASP)学习笔记(二)
2009-08-31 09:58 2455多态 Polymorphism Problem: Ho ... -
通用职责分配软件模式(GRASP)学习笔记(一)
2009-08-31 09:52 2533通用职责分配软件模式 General Responsibil ... -
代理模式学习笔记
2009-08-10 13:42 1182Proxy Pattern Intent Pro ... -
讨论一下CQS (命令-查询 分离)原则
2008-12-24 17:50 1559看Craig Larman的书, 里面 ... -
学习设计模式之State
2008-07-08 01:22 2466发现问题: 大家在Coding ...
相关推荐
同时也是提供了一种可以提取action中可重用的部分的方式。 谈到拦截器,还有一个词大家应该知道——拦截器链(Interceptor Chain,在Struts 2中称为拦截器栈Interceptor Stack)。拦截器链就是将拦截器按一定的顺序...
拦截器,在AOP(Aspect-Oriented Programming)中用于在某个方法或字段被访问之前,进行拦截然后在之前或之后加入某些操作。拦截是AOP的一种实现策略。 在Webwork的中文文档的解释为——拦截器是动态拦截Action调用...
Struts 2以WebWork为核心,采用拦截器的机制来处理用户的请求,这样的设计也使得业务逻辑控制器能够与Servlet API完全脱离开,所以Struts 2可以理解为WebWork的更新产品。因为Struts 2和Struts 1有着太大的变化,...
采用XHTML和CSS设计可重用可换肤的WEB站点 asp.net的网址重定向方法的比较:面向搜索引擎友好 也谈 ASP.NET 1.1 中 QueryString 的安全获取写法 ASP.NET运行模式:PageHandlerFactory 利用搜索引擎引用来高亮页面...
13.4.3. 拦截器(HandlerInterceptor) 13.5. 视图与视图解析 13.5.1. 视图解析器(ViewResolver) 13.5.2. 视图解析链 13.5.3. 重定向(Rediret)到另一个视图 13.6. 本地化解析器 13.6.1. ...
13.4.3. 拦截器(HandlerInterceptor) 13.5. 视图与视图解析 13.5.1. 视图解析器(ViewResolver) 13.5.2. 视图解析链 13.5.3. 重定向(Rediret)到另一个视图 13.6. 本地化解析器 13.6.1. ...
4.容器提供了AOP技术,利用它很容易实现如权限拦截,运行期监控等功能 5.容器提供了众多的辅助类,能加快应用的开发 6.spring对于主流的应用框架提供了集成支持,如hibernate,JPA,Struts等 7.spring属于低侵入...
HTTP响应拦截器204 创建securityInterceptor服务205 创建securityRetryQueue服务207 通知安全服务208 76防止导航到安全受限路由208 使用路由resolve函数209 创建授权服务210 77总结212 第8章创建自定义指令...
系统提供在线流程设计器,在线表单设计器,代码生成器,结合BPMX3的基础组件,以实现复杂的流程业务应用。基础组件包括: Spring基础组件库,报表引擎,数据库访问模块,短信模块,后台定时任务调用组件,短信访问...
TCC事务机制相对于传统事务机制(X/Open XA Two-Phase-Commit),其特征在于它不依赖资源管理器(RM)对XA的支持,而是通过对(由业务系统提供的)业务逻辑的调度来实现分布式事务。主要由三步操作,Try: 尝试执行业务...
8.8 拦截器 332 8.9 依赖注入 335 8.9.1 EJB注入 336 8.9.2 资源注入 339 8.10 配置EJB引用 340 8.11 使用计时器进行任务调度 342 8.12 本章小结 345 第9章 消息驱动EJB 346 9.1 JMS和EJB 347 9.1.1 为什么使用MDB ...
1.7 Linux软件开发的可借鉴之处........................:.................. 12 1-8 .................................................................13 第2 章Linux编程环境...................................