6. }
7. //这里沿着定义好的 interceptorOrInterceptionAdvice链进行处理。
8. Object interceptorOrInterceptionAdvice =
9. this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
10. if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
11. // Evaluate dynamic method matcher here: static part will already have
12. // been evaluated and found to match.
13. //这里对拦截器进行动态匹配的的判断,还记得我们前面分析的pointcut吗?这里是触发进行匹配的地方,如果和定义的pointcut匹配,那么这个advice将会得到执行。
14. InterceptorAndDynamicMethodMatcher dm =
15. (InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
16. if (dm.methodMatcher.matches(this.method, this.targetClass, this.arguments)) {
17. return dm.interceptor.invoke(this); 18. } 19. else {
20. // Dynamic matching failed.
21. // Skip this interceptor and invoke the next in the chain.
22. // //如果不匹配,那么这个proceed会被递归调用,直到所有的拦截器都被运行过为止。 23. return proceed(); 24. }
25. } 26. else {
27. // It's an interceptor, so we just invoke it: The pointcut will have
28. // been evaluated statically before this object was constructed.
29. //如果是一个interceptor,直接调用这个interceptor对应的方法
30. return((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this); 31. } 32.}
在调用拦截器的时候,我们接下去就可以看到对advice的通知的调用。而经过一系列的注册,适配的过程以后,拦截器在拦截的时候,会调用到预置 好的一个通知适配器,设置通知拦截器,这是一系列Spring设计好为通知服务的类的一个,是最终完成通知拦截和实现的地方,非常的关键。比如,对 MethodBeforeAdviceInterceptor的实现是这样的: Java代码
1. public class MethodBeforeAdviceInterceptor implements MethodInterceptor, Serializable { 2.
3. private MethodBeforeAdvice advice; 4. 5. 6. /**
7. * Create a new MethodBeforeAdviceInterceptor for the given advice.
8. * @param advice the MethodBeforeAdvice to wrap 9. */
10. public MethodBeforeAdviceInterceptor(MethodBeforeAdvice advice) {
11. Assert.notNull(advice, \12. this.advice = advice; 13. }
14. //这个invoke方法是拦截器的回调方法,会在代理对象的方法被调用的时候触发回调。
15. public Object invoke(MethodInvocation mi) throws Throwable {
16. this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis() );
17. return mi.proceed(); 18. } 19.}
在代码中,可以看到,就是这里,会调用advice的before方法!这样就成功的完成了before通知的编织!
因为Spring AOP本身并不打算成为一个一统天下的AOP框架,秉持Spring的一贯设计理念,设想中的Spring设计目标应该是,致力于AOP框架与IOC容器 的紧密集成,通过集成AOP技术为JavaEE应用开发中遇到的普遍问题提供解决方案,从而为AOP用户使用AOP技术提供最大的便利,从这个角度上为 Java EE的应用开发人员服务。在没有使用第三方AOP解决方案的时候,Spring通过虚拟机的Proxy特性和CGLIB实现了AOP的基本功能,我想,如 果有了Spring AOP实现原理的知识背景,再加上我们对源代码实现的认真解读,可以为我们了解其他AOP框架与IOC容器的集成原理,也打下了很好的基础,并真正了解一 个AOP
框架是在怎样实现的。
这还真是就是我们喜欢开源软件一个原因,有了源代码,软件就没有什么神秘的面纱了!本立而道生,多读源代码吧,或者找一本从源代码出发讲解软件实现的书来看看,就像以前我们学习操作系统,学习TCP/IP那样!一定会有长进的。
深入解析Spring架构与设计原理(三)数据库的操作实现
最近事情实在是比较多,没有及时更新帖子,还望大家见谅啊。今天,一起讨论讨论Spring JDBC的实现吧。
关于Spring JDBC
还是从Spring JDBC说起吧,虽然现在应用很多都是直接使用Hibernate或者其他的ORM工具。但JDBC毕竟还是很基本的,其中的JdbcTemplate就 是我们经常使用的,比如JDBCTemplate的execute方法,就是一个基本的方法,在这个方法的实现中,可以看到对数据库操作的基本过程。 Java代码
1. //execute方法执行的是输入的sql语句
2. public void execute(final String sql) throws DataAccessException {
3. if (logger.isDebugEnabled()) {
4. logger.debug(\ 5. }
6. class ExecuteStatementCallback implements StatementCallback
7. public Object doInStatement(Statement stmt) throws SQLException {
8. stmt.execute(sql); 9. return null; 10. }
11. public String getSql() { 12. return sql; 13. } 14. }
15. execute(new ExecuteStatementCallback()); 16.}
17.//这是使用java.sql.Statement处理静态SQL语句的方法
18.public
19. Assert.notNull(action, \
20. //这里取得数据库的Connection,这个数据库的Connection已经在Spring的事务管理之下
21. Connection con = DataSourceUtils.getConnection(getDataSource());
22. Statement stmt = null; 23. try {
24. Connection conToUse = con;
25. if (this.nativeJdbcExtractor != null &&
26. this.nativeJdbcExtractor.isNativeConnectionNecessaryForNativeStatements()) {
27. conToUse = this.nativeJdbcExtractor.getNativeConnection(con); 28. }