- 浏览: 741702 次
- 性别:
- 来自: 郑州
文章分类
- 全部博客 (396)
- JAVA (50)
- ORACLE (22)
- HIBERNATE (1)
- SPRING (26)
- STRUTS (4)
- OTHERS (0)
- MYSQL (11)
- Struts2 (16)
- JS (33)
- Tomcat (6)
- DWR (1)
- JQuery (26)
- JBoss (0)
- SQL SERVER (0)
- XML (10)
- 生活 (3)
- JSP (11)
- CSS (5)
- word (1)
- MyEclipse (7)
- JSTL (1)
- JEECMS (2)
- Freemarker (8)
- 页面特效 (1)
- EXT (2)
- Web前端 js库 (2)
- JSON http://www.json.org (3)
- 代码收集 (1)
- 电脑常识 (6)
- MD5加密 (0)
- Axis (0)
- Grails (1)
- 浏览器 (1)
- js调试工具 (1)
- WEB前端 (5)
- JDBC (2)
- PowerDesigner (1)
- OperaMasks (1)
- CMS (1)
- Java开源大全 (2)
- 分页 (28)
- Eclipse插件 (1)
- Proxool (1)
- Jad (1)
- Java反编译 (2)
- 报表 (6)
- JSON (14)
- FCKeditor (9)
- SVN (1)
- ACCESS (1)
- 正则表达式 (3)
- 数据库 (1)
- Flex (3)
- pinyin4j (2)
- IBATIS (3)
- probe (1)
- JSP & Servlet (1)
- 飞信 (0)
- AjaxSwing (0)
- AjaxSwing (0)
- Grid相关 (1)
- HTML (5)
- Guice (4)
- Warp framework (1)
- warp-persist (1)
- 服务器推送 (3)
- eclipse (1)
- JForum (5)
- 工具 (1)
- Python (1)
- Ruby (1)
- SVG (3)
- Joda-Time日期时间工具 (1)
- JDK (3)
- Pushlet (2)
- JSP & Servlet & FTP (1)
- FTP (6)
- 时间与效率 (4)
- 二维码 (1)
- 条码/二维码 (1)
最新评论
-
ctrlc:
你这是从web服务器上传到FTP服务器上的吧,能从用户电脑上上 ...
jsp 往 FTP 上传文件问题 -
annybz:
说的好抽象 为什么代码都有两遍。这个感觉没有第一篇 和第二篇 ...
Spring源代码解析(三):Spring JDBC -
annybz:
...
Spring源代码解析(一):IOC容器 -
jie_20:
你确定你有这样配置做过测试? 请不要转载一些自己没有测试的文档 ...
Spring2.0集成iReport报表技术概述 -
asd51731:
大哥,limit传-1时出错啊,怎么修改啊?
mysql limit 使用方法
前面我们分析了Spring AOP实现中得到Proxy对象的过程,下面我们看看在Spring
AOP中拦截器链是怎样被调用的,也就是Proxy模式是怎样起作用的,或者说Spring是怎样为我们提供AOP功能的;
在
JdkDynamicAopProxy中生成Proxy对象的时候:
return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
这里的this参数对应的是InvocationHandler对象,这里我们的JdkDynamicAopProxy实现了这个接口,也
就是说当Proxy对象的函数被调用的时候,这个InvocationHandler的invoke方法会被作为回调函数调用,下面我们看看这个方法的实
现:
- public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
- MethodInvocation invocation = null ;
- Object oldProxy = null ;
- boolean setProxyContext = false ;
- TargetSource targetSource = this .advised.targetSource;
- Class targetClass = null ;
- Object target = null ;
- try {
- // Try special rules for equals() method and implementation of the
- // Advised AOP configuration interface.
- if (! this .equalsDefined && AopUtils.isEqualsMethod(method)) {
- // What if equals throws exception!?
- // This class implements the equals(Object) method itself.
- return equals(args[ 0 ]) ? Boolean.TRUE : Boolean.FALSE;
- }
- if (! this .hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
- // This class implements the hashCode() method itself.
- return new Integer(hashCode());
- }
- if (Advised. class == method.getDeclaringClass()) {
- // service invocations on ProxyConfig with the proxy config
- return AopUtils.invokeJoinpointUsingReflection( this .advised, method, args);
- }
- Object retVal = null ;
- if ( this .advised.exposeProxy) {
- // make invocation available if necessary
- oldProxy = AopContext.setCurrentProxy(proxy);
- setProxyContext = true ;
- }
- // May be <code>null</code>. Get as late as possible to minimize the time we "own" the target,
- // in case it comes from a pool.
- // 这里是得到目标对象的地方,当然这个目标对象可 能来自于一个实例池或者是一个简单的JAVA对象
- target = targetSource.getTarget();
- if (target != null ) {
- targetClass = target.getClass();
- }
- // get the interception chain for this method
- // 这里获得定义好的拦截器链
- List chain = this .advised.advisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice(
- this .advised, proxy, method, targetClass);
- // Check whether we have any advice. If we don't, we can fallback on direct
- // reflective invocation of the target, and avoid creating a MethodInvocation.
- // 如果没有设定拦截器,那么我们就直接调用目标的 对应方法
- if (chain.isEmpty()) {
- // We can skip creating a MethodInvocation: just invoke the target directly
- // Note that the final invoker must be an InvokerInterceptor so we know it does
- // nothing but a reflective operation on the target, and no hot swapping or fancy proxying
- retVal = AopUtils.invokeJoinpointUsingReflection(target, method, args);
- }
- else {
- // We need to create a method invocation...
- // invocation = advised.getMethodInvocationFactory().getMethodInvocation(
- // proxy, method, targetClass, target, args, chain, advised);
- // 如果有拦截器的设定,那么需要调用拦截 器之后才调用目标对象的相应方法
- // 这里通过构造一个 ReflectiveMethodInvocation来实现,下面我们会看这个ReflectiveMethodInvocation类
- invocation = new ReflectiveMethodInvocation(
- proxy, target, method, args, targetClass, chain);
- // proceed to the joinpoint through the interceptor chain
- // 这里通过 ReflectiveMethodInvocation来调用拦截器链和相应的目标方法
- retVal = invocation.proceed();
- }
- // massage return value if necessary
- if (retVal != null && retVal == target && method.getReturnType().isInstance(proxy)) {
- // Special case: it returned "this" and the return type of the method is type-compatible
- // Note that we can't help if the target sets
- // a reference to itself in another returned object.
- retVal = proxy;
- }
- return retVal;
- }
- finally {
- if (target != null && !targetSource.isStatic()) {
- // must have come from TargetSource
- targetSource.releaseTarget(target);
- }
- if (setProxyContext) {
- // restore old proxy
- AopContext.setCurrentProxy(oldProxy);
- }
- }
- }
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { MethodInvocation invocation = null; Object oldProxy = null; boolean setProxyContext = false; TargetSource targetSource = this.advised.targetSource; Class targetClass = null; Object target = null; try { // Try special rules for equals() method and implementation of the // Advised AOP configuration interface. if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) { // What if equals throws exception!? // This class implements the equals(Object) method itself. return equals(args[0]) ? Boolean.TRUE : Boolean.FALSE; } if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) { // This class implements the hashCode() method itself. return new Integer(hashCode()); } if (Advised.class == method.getDeclaringClass()) { // service invocations on ProxyConfig with the proxy config return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args); } Object retVal = null; if (this.advised.exposeProxy) { // make invocation available if necessary oldProxy = AopContext.setCurrentProxy(proxy); setProxyContext = true; } // May be <code>null</code>. Get as late as possible to minimize the time we "own" the target, // in case it comes from a pool. // 这里是得到目标对象的地方,当然这个目标对象可能来自于一个实例池或者是一个简单的JAVA对象 target = targetSource.getTarget(); if (target != null) { targetClass = target.getClass(); } // get the interception chain for this method // 这里获得定义好的拦截器链 List chain = this.advised.advisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice( this.advised, proxy, method, targetClass); // Check whether we have any advice. If we don't, we can fallback on direct // reflective invocation of the target, and avoid creating a MethodInvocation. // 如果没有设定拦截器,那么我们就直接调用目标的对应方法 if (chain.isEmpty()) { // We can skip creating a MethodInvocation: just invoke the target directly // Note that the final invoker must be an InvokerInterceptor so we know it does // nothing but a reflective operation on the target, and no hot swapping or fancy proxying retVal = AopUtils.invokeJoinpointUsingReflection(target, method, args); } else { // We need to create a method invocation... // invocation = advised.getMethodInvocationFactory().getMethodInvocation( // proxy, method, targetClass, target, args, chain, advised); // 如果有拦截器的设定,那么需要调用拦截器之后才调用目标对象的相应方法 // 这里通过构造一个ReflectiveMethodInvocation来实现,下面我们会看这个ReflectiveMethodInvocation类 invocation = new ReflectiveMethodInvocation( proxy, target, method, args, targetClass, chain); // proceed to the joinpoint through the interceptor chain // 这里通过ReflectiveMethodInvocation来调用拦截器链和相应的目标方法 retVal = invocation.proceed(); } // massage return value if necessary if (retVal != null && retVal == target && method.getReturnType().isInstance(proxy)) { // Special case: it returned "this" and the return type of the method is type-compatible // Note that we can't help if the target sets // a reference to itself in another returned object. retVal = proxy; } return retVal; } finally { if (target != null && !targetSource.isStatic()) { // must have come from TargetSource targetSource.releaseTarget(target); } if (setProxyContext) { // restore old proxy AopContext.setCurrentProxy(oldProxy); } } }
我们先看看目标对象方法的调用,这里是通过AopUtils的方法调用 - 使用反射机制来对目标对象的方法进行调用:
- public static Object invokeJoinpointUsingReflection(Object target, Method method, Object[] args)
- throws Throwable {
- // Use reflection to invoke the method.
- // 利用放射机制得到相应的方法,并且调用invoke
- try {
- if (!Modifier.isPublic(method.getModifiers()) ||
- !Modifier.isPublic(method.getDeclaringClass().getModifiers())) {
- method.setAccessible( true );
- }
- return method.invoke(target, args);
- }
- catch (InvocationTargetException ex) {
- // Invoked method threw a checked exception.
- // We must rethrow it. The client won't see the interceptor.
- throw ex.getTargetException();
- }
- catch (IllegalArgumentException ex) {
- throw new AopInvocationException( "AOP configuration seems to be invalid: tried calling method [" +
- method + "] on target [" + target + "]" , ex);
- }
- catch (IllegalAccessException ex) {
- throw new AopInvocationException( "Couldn't access method: " + method, ex);
- }
- }
public static Object invokeJoinpointUsingReflection(Object target, Method method, Object[] args) throws Throwable { // Use reflection to invoke the method. // 利用放射机制得到相应的方法,并且调用invoke try { if (!Modifier.isPublic(method.getModifiers()) || !Modifier.isPublic(method.getDeclaringClass().getModifiers())) { method.setAccessible(true); } return method.invoke(target, args); } catch (InvocationTargetException ex) { // Invoked method threw a checked exception. // We must rethrow it. The client won't see the interceptor. throw ex.getTargetException(); } catch (IllegalArgumentException ex) { throw new AopInvocationException("AOP configuration seems to be invalid: tried calling method [" + method + "] on target [" + target + "]", ex); } catch (IllegalAccessException ex) { throw new AopInvocationException("Couldn't access method: " + method, ex); } }
对拦截器链的调用处理是在ReflectiveMethodInvocation里实现的:
- public Object proceed() throws Throwable {
- // We start with an index of -1 and increment early.
- // 这里直接调用目标对象的方法,没有拦截器的调用或者拦截 器已经调用完了,这个currentInterceptorIndex的初始值是0
- if ( this .currentInterceptorIndex == this .interceptorsAndDynamicMethodMatchers.size()) {
- return invokeJoinpoint();
- }
- Object interceptorOrInterceptionAdvice =
- this .interceptorsAndDynamicMethodMatchers.get( this .currentInterceptorIndex);
- if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
- // Evaluate dynamic method matcher here: static part will already have
- // been evaluated and found to match.
- // 这里获得相应的拦截器,如果拦截器可以匹配的上 的话,那就调用拦截器的invoke方法
- InterceptorAndDynamicMethodMatcher dm =
- (InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
- if (dm.methodMatcher.matches( this .method, this .targetClass, this .arguments)) {
- return dm.interceptor.invoke(nextInvocation());
- }
- else {
- // Dynamic matching failed.
- // Skip this interceptor and invoke the next in the chain.
- // 如果拦截器匹配不上,那就调用下一个拦 截器,这个时候拦截器链的位置指示后移并迭代调用当前的proceed方法
- this .currentInterceptorIndex++;
- return proceed();
- }
- }
- else {
- // It's an interceptor, so we just invoke it: The pointcut will have
- // been evaluated statically before this object was constructed.
- return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(nextInvocation());
- }
- }
public Object proceed() throws Throwable { // We start with an index of -1 and increment early. // 这里直接调用目标对象的方法,没有拦截器的调用或者拦截器已经调用完了,这个currentInterceptorIndex的初始值是0 if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size()) { return invokeJoinpoint(); } Object interceptorOrInterceptionAdvice = this.interceptorsAndDynamicMethodMatchers.get(this.currentInterceptorIndex); if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) { // Evaluate dynamic method matcher here: static part will already have // been evaluated and found to match. // 这里获得相应的拦截器,如果拦截器可以匹配的上的话,那就调用拦截器的invoke方法 InterceptorAndDynamicMethodMatcher dm = (InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice; if (dm.methodMatcher.matches(this.method, this.targetClass, this.arguments)) { return dm.interceptor.invoke(nextInvocation()); } else { // Dynamic matching failed. // Skip this interceptor and invoke the next in the chain. // 如果拦截器匹配不上,那就调用下一个拦截器,这个时候拦截器链的位置指示后移并迭代调用当前的proceed方法 this.currentInterceptorIndex++; return proceed(); } } else { // It's an interceptor, so we just invoke it: The pointcut will have // been evaluated statically before this object was constructed. return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(nextInvocation()); } }
这里把当前的拦截器链以及在拦截器链的位置标志都clone到一个MethodInvocation对象了,作用是当前的拦截器执行完之
后,会继续沿着得到这个拦截器链执行下面的拦截行为,也就是会迭代的调用上面这个proceed:
- private ReflectiveMethodInvocation nextInvocation() throws CloneNotSupportedException {
- ReflectiveMethodInvocation invocation = (ReflectiveMethodInvocation) clone();
- invocation.currentInterceptorIndex = this .currentInterceptorIndex + 1 ;
- invocation.parent = this ;
- return invocation;
- }
private ReflectiveMethodInvocation nextInvocation() throws CloneNotSupportedException { ReflectiveMethodInvocation invocation = (ReflectiveMethodInvocation) clone(); invocation.currentInterceptorIndex = this.currentInterceptorIndex + 1; invocation.parent = this; return invocation; }
这里的nextInvocation就已经包含了当前的拦截链的基本信息,我们看到在Interceptor中的实现比如
TransactionInterceptor的实现中:
- public Object invoke( final MethodInvocation invocation) throws Throwable {
- ...... //这里是 TransactionInterceptor插入的事务处理代码,我们会在后面分析事务处理实现的时候进行分析
- try {
- //这里是对配置的拦截器链进行迭代处理的调 用
- retVal = invocation.proceed();
- }
- ...... //省略了和事务处理的异常处理代码 ,也是 TransactionInterceptor插入的处理
- else {
- try {
- Object result = ((CallbackPreferringPlatformTransactionManager) getTransactionManager()).execute(txAttr,
- new TransactionCallback() {
- public Object doInTransaction(TransactionStatus status) {
- //这里 是TransactionInterceptor插入对事务处理的代码
- TransactionInfo txInfo = prepareTransactionInfo(txAttr, joinpointIdentification, status);
- //这里是 对配置的拦截器链进行迭代处理的调用,接着顺着拦截器进行处理
- try {
- return invocation.proceed();
- }
- ...... //省略了和事务处理的异常处理代码 ,也是 TransactionInterceptor插入的处理
- }
public Object invoke(final MethodInvocation invocation) throws Throwable { ......//这里是TransactionInterceptor插入的事务处理代码,我们会在后面分析事务处理实现的时候进行分析 try { //这里是对配置的拦截器链进行迭代处理的调用 retVal = invocation.proceed(); } ......//省略了和事务处理的异常处理代码 ,也是TransactionInterceptor插入的处理 else { try { Object result = ((CallbackPreferringPlatformTransactionManager) getTransactionManager()).execute(txAttr, new TransactionCallback() { public Object doInTransaction(TransactionStatus status) { //这里是TransactionInterceptor插入对事务处理的代码 TransactionInfo txInfo = prepareTransactionInfo(txAttr, joinpointIdentification, status); //这里是对配置的拦截器链进行迭代处理的调用,接着顺着拦截器进行处理 try { return invocation.proceed(); } ......//省略了和事务处理的异常处理代码 ,也是TransactionInterceptor插入的处理 }
从上面的分析我们看到了Spring AOP的基本实现,比如Spring怎样得到Proxy,怎样利用JAVA
Proxy以及反射机制对用户定义的拦截器链进行处理。
发表评论
-
Spring--quartz中cronExpression配置说明
2011-12-02 18:28 0quartz中cronExpression配置说明 字段 ... -
使用Spring的jdbcTemplate进一步简化JDBC操作
2011-12-02 09:20 1235先看applicationContext.xml配置文件: ... -
Spring MVC:使用SimpleUrlHandlerMapping的一个简单例子
2011-12-01 11:26 945实现一个控制器ShirdrnCon ... -
最简单的Spring MVC入门示例
2010-05-19 14:29 1496应一位朋友的要求,写一个最简单的spring示例,使用s ... -
Spring源代码解析(十):Spring Acegi框架授权的实现
2010-03-18 12:48 1494我们从FilterSecurityIntercep ... -
Spring源代码解析(九):Spring Acegi框架鉴权的实现
2010-03-18 12:47 1477简单分析一下Spring Acegi的源代码实现: Ser ... -
Spring源代码解析(八):Spring驱动Hibernate的实现
2010-03-18 12:41 1399O/R工具出现之后,简化了许多复杂的信息持久化的开发。Spri ... -
Spring源代码解析(六):Spring声明式事务处理
2010-03-18 12:37 1074我们看看Spring中的事务处理的代码,使用Spring管理事 ... -
Spring源代码解析(五):Spring AOP获取Proxy
2010-03-18 12:36 1298下面我们来看看Spring的AOP的一些相关代码是怎么得到Pr ... -
Spring源代码解析(四):Spring MVC
2010-03-18 12:35 7698下面我们对Spring MVC框架代码进行分析,对于web ... -
Spring源代码解析(三):Spring JDBC
2010-03-18 12:33 1658下面我们看看Spring JDBC相关的实现, 在Spri ... -
Spring源代码解析(二):IoC容器在Web容器中的启动
2010-03-18 12:32 1421上面我们分析了IOC容器本身的实现,下面我们看看在典型的web ... -
Spring源代码解析(一):IOC容器
2010-03-18 12:30 2636在Spring中,IOC容器的重要地位我们就不多说了,对于Sp ... -
使用Spring的JdbcTemplate和BeanPropertyRowMapper完成的JDBC
2010-03-18 12:08 2233先道要加上两个包:Spring2.5下面的: spring. ... -
使用Spring的SimpleJdbcTemplate完成DAO操作
2010-03-18 12:06 1478l SimpleJdbcTemplate内部包含了 ... -
使用Spring的NamedParameterJdbcTemplate完成DAO操作
2010-03-18 12:05 1387NamedParameterJdbcTemplate内部包含了 ... -
Spring in Action 学习笔记—第四章 征服数据库(转)
2010-03-18 12:03 1229Spring2.0正式版(http://www.springf ... -
Spring管理JDBC连接
2010-03-18 11:59 1661在Spring中,JdbcTemplate是经常被使用的类来帮 ... -
Spring JDBC数据库操作类
2010-03-18 09:26 16101.JdbcTemplate 在Spring中, ... -
Spring JdbcTemplate 批量插入或更新操作
2010-03-18 09:19 5228用 JdbcTemplate 进行批量插入或更新操作 ...
相关推荐
Spring源代码解析(七):Spring_AOP中对拦截器调用的实现.doc
Spring源代码解析7:Spring AOP中对拦截器调用的实现 .doc Spring源代码解析8:Spring驱动Hibernate的实现.doc Spring源代码解析9:Spring Acegi框架鉴权的实现.doc Spring源代码解析10:Spring Acegi框架授权的实现...
Spring源代码解析7:Spring AOP中对拦截器调用的实现 Spring源代码解析8:Spring驱动Hibernate的实现;Spring源代码解析9:Spring Acegi框架鉴权的实现 Spring源代码解析10:Spring Acegi框架授权的实现
Spring源代码解析(七):Spring AOP中对拦截器调用的实现 Spring源代码解析(八):Spring驱动Hibernate的实现 Spring源代码解析(九):Spring Acegi框架鉴权的实现 Spring源代码解析(十):Spring Acegi框架授权...
pring源代码解析1:IOC容器;Spring源代码解析2:IoC容器在Web容器中的启动;Spring源代码解析3:... Spring源代码解析7:Spring AOP中对拦截器调用的实现 Spring源代码解析8:Spring驱动Hibernate的实现;Spring源代
Spring源代码解析(七):Spring AOP中对拦截器调用的实现 Spring源代码解析(八):Spring驱动Hibernate的实现 Spring源代码解析(九):Spring Acegi框架鉴权的实现 Spring源代码解析(十):Spring Acegi框架授权...
Spring源代码解析(七):Spring AOP中对拦截器调用的实现 8. Spring源代码解析(八):Spring驱动Hibernate的实现 9.Spring源代码解析(九):Spring Acegi框架鉴权的实现 10. Spring源代码解析(十):Spring ...
Spring源代码解析(七):Spring AOP中对拦截器调用的实现.doc Spring源代码解析(八):Spring驱动Hibernate的实现.doc Spring源代码解析(九):Spring Acegi框架鉴权的实现.doc Spring源代码解析(十):Spring ...
13.4.3. 拦截器(HandlerInterceptor) 13.5. 视图与视图解析 13.5.1. 视图解析器 13.5.2. 视图解析链 13.5.3. 重定向(Rediret)到另一个视图 13.5.3.1. RedirectView 13.5.3.2. redirect:前缀 13.5.3.3. forward:...
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. ...
13.4.3. 拦截器(HandlerInterceptor) 13.5. 视图与视图解析 13.5.1. 视图解析器 13.5.2. 视图解析链 13.5.3. 重定向(Rediret)到另一个视图 13.6. 本地化解析器 13.6.1. AcceptHeaderLocaleResolver 13.6.2....
13.4.3. 拦截器(HandlerInterceptor) 13.5. 视图与视图解析 13.5.1. 视图解析器 13.5.2. 视图解析链 13.5.3. 重定向(Rediret)到另一个视图 13.6. 本地化解析器 13.6.1. AcceptHeaderLocaleResolver 13.6.2....
4.容器提供了AOP技术,利用它很容易实现如权限拦截,运行期监控等功能 5.容器提供了众多的辅助类,能加快应用的开发 6.spring对于主流的应用框架提供了集成支持,如hibernate,JPA,Struts等 7.spring属于低侵入...
11.3.4 使用注释声明拦截器 11.4 小结 第12章 访问企业服务 12.1 从JNDI中获取对象 12.1.1 使用传统的JNDI 12.1.2 注入JNDI对象 12.1.3 在Spring 2中注入JNDI对象 12.2 发送电子邮件 12.2.1 配置邮件发送...
11.3.4 使用注释声明拦截器 11.4 小结 第12章 访问企业服务 12.1 从JNDI中获取对象 12.1.1 使用传统的JNDI 12.1.2 注入JNDI对象 12.1.3 在Spring 2中注入JNDI对象 12.2 发送电子邮件 12.2.1 配置邮件发送...
11.3.4使用注释声明拦截器 11.4小结 第12章访问企业服务 12.1从jndi中获取对象 12.1.1使用传统的jndi 12.1.2注入jndi对象 12.1.3在spring2中注入jndi对象 12.2发送电子邮件 12.2.1配置邮件发送器 12.2.2...
1.4.2. 获得源代码 2. Security命名空间配置 2.1. 介绍 2.1.1. 命名空间的设计 2.2. 开始使用安全命名空间配置 2.2.1. 配置web.xml 2.2.2. 最小 <http> 配置 2.2.2.1. auto-config 包含了什么? 2.2...
25.1 AOP联盟(MethodInvocation)安全拦截器 197 25.1.1显式MethodSecurityInterceptor配置 197 25.2 AspectJ(JoinPoint)安全拦截器 198 26.基于表达式的访问控制 200 26.1概述 200 26.1.1通用内置表达式 201 ...