`

org.springframework.core简单分析

阅读更多
    这个包的类主要用于spring框架的异常处理和一些核心的助手类(与框架具体部分无关的)。
    这个包中主要应用到了简单工厂模式,用于判断jdk版本,根据jdk版本不同提供不同的集合类、当前方法栈信息等。我们来看看是如何判断当前用户的jdk版本的:
<!---->
package org.springframework.core;

public class JdkVersion {
    
    
public static final int JAVA_13 = 0;
    
    
public static final int JAVA_14 = 1;
    
    
public static final int JAVA_15 = 2;

    
private static String javaVersion;

    
private static int majorJavaVersion = JAVA_13;
    
    
static {
        javaVersion 
= System.getProperty("java.version");
        
// should look like "1.4.1_02"
        if (javaVersion.indexOf("1.4."!= -1) {
            majorJavaVersion 
= JAVA_14;
        }
        
else if (javaVersion.indexOf("1.5."!= -1) {
            majorJavaVersion 
= JAVA_15;
        }
        
// else leave as 1.3 default
    }

    
/**
     * Return the full Java version string, as returned by
     * <code>System.getProperty("java.version")</code>.
     
*/
    
public static String getJavaVersion() {
        
return javaVersion;
    }

    
/**
     * Get the major version code. This means we can do things like
     * <code>if (getMajorJavaVersion() < JAVA_14)</code>.
     * 
@return a code comparable to the JAVA_XX codes in this class
     * 
@see #JAVA_13
     * 
@see #JAVA_14
     * 
@see #JAVA_15
     
*/
    
public static int getMajorJavaVersion() {
        
return majorJavaVersion;
    }

}

直接获取系统的java.version属性来进行jdk版本的判断。而CollectionFactory依据这个类来创建不同的集合类型,如果是jdk1.4就优先使用jdk1.4的集合框架,再次选择Commons Collections,最后才不得已就使用jdk1.3的集合框架,这里比较有趣的是判断Commons Collections的方法就是尝试Class.forName一个Commons集合框架中的对象,如果成功,当然证明classpath有commons-collections.jar包:
<!---->static {
        
// Check whether JDK 1.4+ collections and/or
        
// Commons Collections 3.x are available.
        if (JdkVersion.getMajorJavaVersion() >= JdkVersion.JAVA_14) {
            logger.info(
"JDK 1.4+ collections available");
        }
        
try {
            Class.forName(COMMONS_COLLECTIONS_CLASS_NAME);
            commonsCollections3xAvailable 
= true;
            logger.info(
"Commons Collections 3.x available");
        }
        
catch (ClassNotFoundException ex) {
            commonsCollections3xAvailable 
= false;
        }
    }

然后就是一系列的getXXXIfPossible()方法用以获取最优版本的集合类型,比如getLinkedHashMapIfPossible():
<!---->public static Map createLinkedMapIfPossible(int initialCapacity) {
        
if (JdkVersion.getMajorJavaVersion() >= JdkVersion.JAVA_14) {
            logger.debug(
"Creating [java.util.LinkedHashMap]");
            
return Jdk14CollectionFactory.createLinkedHashMap(initialCapacity);
        }
        
else if (commonsCollections3xAvailable) {
            logger.debug(
"Creating [org.apache.commons.collections.map.LinkedMap]");
            
return CommonsCollectionFactory.createLinkedMap(initialCapacity);
        }
        
else {
            logger.debug(
"Falling back to [java.util.HashMap] for linked map");
            
return new HashMap(initialCapacity);
        }
    }
其中的Jdk14CollectionFactory 和CommonsCollectionFactory 也都是工厂类。可以看到,一个优秀的通用框架对于版本的兼容性非常重视。

    这个包中另外一个需要注意的就是用于spring AOP功能实现的辅助类——ControlFlow。ControlFlow按照rod johnson的说法就是用于获取当前调用的方法栈的具体信息。ControlFlow是一个接口,拥有3个方法用于判断当前方法栈的位置:
<!---->public interface ControlFlow {

    
/**
      查找当前方法调用是否则在某类中
     * 
@param clazz the clazz to look for
     
*/
    
boolean under(Class clazz);

    
/**
     * 查找当前方法调用是否则在某类的某个方法中
     * according to the current stack trace.
     * 
@param clazz the clazz to look for
     * 
@param methodName the name of the method to look for
     
*/
    
boolean under(Class clazz, String methodName);

    
/**
     * 当前栈帧是否包含传入的记号
     * 
@param token the token to look for
     
*/
    
boolean underToken(String token);

}

然后根据jdk版本的不同采用不同的方式实现这个接口:Jdk14ControlFlow和Jdk13ControlFlow。这是典型的策略模式的应用。需要注意的是,这两个具体类的是放在工厂类ControlFlowFactory中作为内部类实现的:
<!---->public abstract class ControlFlowFactory {
   
   
static class Jdk13ControlFlow implements ControlFlow {
  
   

    
static class Jdk14ControlFlow implements ControlFlow {
   
}

在这里,我们可以学到的东西就如何去判断当前方法栈的信息?jdk1.4之前只能通过对StackTrace的字符串进行分析,而jdk1.4引入了java.lang.StackTraceElement用于获取当前方法调用所处的栈帧的信息,看看spring的使用方法,相当简单:
<!---->static class Jdk14ControlFlow implements ControlFlow {

        
private StackTraceElement[] stack;

        
public Jdk14ControlFlow() {
            
this.stack = new Throwable().getStackTrace();
        }

        
/**
         * Searches for class name match in a StackTraceElement.
         
*/
        
public boolean under(Class clazz) {
            Assert.notNull(clazz, 
"Class must not be null");
            String className 
= clazz.getName();
            
for (int i = 0; i < stack.length; i++) {
                
if (this.stack[i].getClassName().equals(className)) {
                    
return true;
                }
            }
            
return false;
        }

        
/**
         * Searches for class name match plus method name match
         * in a StackTraceElement.
         
*/
        
public boolean under(Class clazz, String methodName) {
            Assert.notNull(clazz, 
"Class must not be null");
            Assert.notNull(methodName, 
"Method name must not be null");
            String className 
= clazz.getName();
            
for (int i = 0; i < this.stack.length; i++) {
                
if (this.stack[i].getClassName().equals(className) &&
                        
this.stack[i].getMethodName().equals(methodName)) {
                    
return true;
                }
            }
            
return false;
        }

        
/**
         * Leave it up to the caller to decide what matches.
         * Caller must understand stack trace format, so there's less abstraction.
         
*/
        
public boolean underToken(String token) {
            
if (token == null) {
                
return false;
            }
            StringWriter sw 
= new StringWriter();
            
new Throwable().printStackTrace(new PrintWriter(sw));
            String stackTrace 
= sw.toString();
            
return stackTrace.indexOf(token) != -1;
        }
}

获取当前栈帧的信息,对于一般的java开发者没有什么意义,对于AOP的实现和框架开发者可能有比较重要的作用,我还未研读spring的aop部分,不敢妄言,留待以后解答,如果您已经研读过这部分代码,不吝赐教。

这个包另外的一个特点就是将java的反射API演示了一遍,特别是Constant.java(用于提取某个类public static final定义的常量)和ReflectiveVisitorHelper (反射助手类),对于学习java反射技术也有不小的帮助。



dennis 2007-04-10 16:56 发表评论
分享到:
评论

相关推荐

    Spring3.0.2-Source源码

    6. **Spring核心工具类**:`org.springframework.core` 和 `org.springframework.util` 包提供了许多实用工具类,如反射、集合操作、日志记录等。 7. **测试支持**:Spring提供了对JUnit和其他测试框架的集成,使...

    spring3.07

    `org.springframework.jdbc.core.JdbcTemplate` 提供了简单的 SQL 执行操作,而 `org.springframework.orm.hibernate3.HibernateTemplate` 和 `org.springframework.orm.jpa.EntityManagerFactoryBean` 分别为 ...

    整合struts2.2.1+spring3.0.4+hibernate3.6选择jar包

    - **org.springframework.asm-3.0.4.RELEASE.jar**:ASM是一个Java字节码操控和分析框架,被Spring用于动态代理等功能。 - **org.springframework.aspects-3.0.4.RELEASE.jar**:支持Spring AOP功能。 - **org....

    Spring Framework v6.1.4.zip

    Spring Framework 是一个广泛使用的开源Java应用框架,特别适用于企业级应用程序开发。它的最新版本v6.1.4为我们带来了许多新特性和改进,使得开发者能够更高效、更灵活地构建可维护的、高性能的应用程序。这个...

    官方原版源码 spring-5.2.8.RELEASE.zip

    此外,Spring的事务管理(`org.springframework.transaction`包)是其另一大亮点,提供了声明式事务管理,使得开发者无需显式调用begin、commit或rollback,即可实现事务控制。 Spring框架5.2.8.RELEASE的源码不仅...

    mongo spring boot Aggregate 例子

    在Spring Boot中,我们可以利用`org.springframework.data.mongodb.core.MongoTemplate`或`org.springframework.data.mongodb.repository.ReactiveMongoRepository`与MongoDB交互。对于聚合操作,我们需要使用`Mongo...

    官方源码 spring-framework-5.2.15.RELEASE.zip

    Spring Framework 5.2.15.RELEASE由多个模块组成,包括Core Container(核心容器)、Data Access/Integration(数据访问/集成)、Web、AOP(面向切面编程)、Instruments(工具类)等。每个模块都有其特定的职责,...

    SpringFramework5.1.2.RELEASE

    1. **spring-core**: 这是Spring Framework的核心模块,包含了IoC(Inversion of Control)容器的基础组件。IoC容器负责管理对象的生命周期和依赖关系,使得开发者能够将组件间的耦合度降到最低。此外,`spring-core...

    spring-framework-3.0.5.RELEASE-dependencies3

    - `org.springframework`:这是Spring框架的核心模块,包含了IoC(Inversion of Control,控制反转)和AOP(Aspect Oriented Programming,面向切面编程)等核心功能。如`spring-beans`提供了Bean的创建和管理,`...

    SpringBoot集成ActiveMQ代码.zip

    import org.springframework.jms.core.JmsTemplate; import org.springframework.stereotype.Component; @Component public class MessageProducer { @Autowired private JmsTemplate jmsTemplate; public ...

    ElasticJob与SpringBatch的结合使用

    &lt;beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:batch="http://www.springframework.org/schema/batch" xsi:schemaLocation=...

    spring[1]-使用ImportBeanDefinitionRegistrar自定义注册bean(基于源码).zip

    import org.springframework.core.type.AnnotationMetadata; public class CustomRegistrar implements ImportBeanDefinitionRegistrar { @Override public void registerBeanDefinitions(AnnotationMetadata ...

    读properties和事务demo

    在给出的jar文件列表中,我们看到了Spring的核心组件,如`org.springframework.beans`, `org.springframework.context`, `org.springframework.orm`, `org.springframework.jdbc`等,这些都是Spring框架的重要组成...

    Spring Boot项目中使用Logback日志与使用AOP拦截请求日志信息

    import org.springframework.context.annotation.EnableAspectJAutoProxy; @SpringBootApplication @EnableAspectJAutoProxy public class Application { public static void main(String[] args) { ...

    springframework.zip

    7. **模块化设计**:Spring Framework由多个模块组成,如Core Container、Data Access/Integration、Web等,这种模块化的结构使得源码更加清晰,易于理解和扩展。 8. **注解驱动开发**:Spring 4.2进一步加强了注解...

    spring-framework-4.2.1.RELEASE-dist.zip

    在分析源码的过程中,我们可以深入了解Spring如何通过IoC容器管理对象,以及AOP代理是如何工作的。源码阅读有助于理解Spring的底层设计,提升我们的编程技能。 总结来说,Spring Framework 4.2.1.RELEASE是一个强大...

    打印JdbcTemplate执行sql

    DEBUG org.springframework.jdbc.core.JdbcTemplate - Setting SQL parameter value: 1, java.lang.Integer ``` 3. **自定义日志**:如果你需要更细粒度的控制,比如格式化输出或者添加额外的信息,可以自定义`...

    Spring之HelloWorld

    &lt;beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans ...

    springboot 整合 OpeanCv 库的简单调用

    import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.multipart.MultipartFile; import java.io....

    spring-framework-3.0.5.-source

    1. **Core Container**:包括Spring的核心模块,如Bean工厂(BeanFactory)和应用上下文(ApplicationContext)。BeanFactory负责管理对象的生命周期和依赖关系,ApplicationContext则在此基础上增加了国际化、事件...

Global site tag (gtag.js) - Google Analytics