续接前文 手写SpringMVC框架(二)结构开发设计 本节我们来开始具体方法的代码实现。
思路:我们需要将contextConfigLocation路径读取过来的配置文件springmvc.properties加载到内存中来。 实现:使用properties及类加载器。 代码如下:
import java.io.InputStream; import java.util.Properties; private Properties properties=new Properties(); //加载配置文件 private void doLoadConfig(String contextConfigLocation) { InputStream resourceAsStream = this.getClass().getClassLoader().getResourceAsStream(contextConfigLocation); try { properties.load(resourceAsStream); } catch (IOException e) { e.printStackTrace(); } }代码如下:
List<String> classNames=new ArrayList<>(); //扫描类 磁盘上的文件夹及文件 private void doScan(String scanPackage) { String scanPackagePath = Thread.currentThread().getContextClassLoader().getResource("").getPath(); File pack=new File(scanPackagePath); File[] files = pack.listFiles(); for (File file : files) { if (file.isDirectory()) { //递归 doScan(scanPackage+"."+file.getName()); //比如com.lagou.controller }else if(file.getName().endsWith(".class")){ String className = scanPackage + "." + file.getName().replaceAll(".class", ""); classNames.add(className); } } }代码如下
// ioc容器 private Map<String,Object> ioc = new HashMap<String,Object>(); // ioc容器 // 基于classNames缓存的类的全限定类名,以及反射技术,完成对象创建和管理 private void doInstance() { if(classNames.size() == 0) return; try{ for (int i = 0; i < classNames.size(); i++) { String className = classNames.get(i); // com.lagou.demo.controller.DemoController // 反射 Class<?> aClass = Class.forName(className); // 区分controller,区分service' if(aClass.isAnnotationPresent(LagouController.class)) { // controller的id此处不做过多处理,不取value了,就拿类的首字母小写作为id,保存到ioc中 String simpleName = aClass.getSimpleName();// DemoController String lowerFirstSimpleName = lowerFirst(simpleName); // demoController Object o = aClass.newInstance(); ioc.put(lowerFirstSimpleName,o); }else if(aClass.isAnnotationPresent(LagouService.class)) { LagouService annotation = aClass.getAnnotation(LagouService.class); //获取注解value值 String beanName = annotation.value(); // 如果指定了id,就以指定的为准 if(!"".equals(beanName.trim())) { ioc.put(beanName,aClass.newInstance()); }else{ // 如果没有指定,就以类名首字母小写 beanName = lowerFirst(aClass.getSimpleName()); ioc.put(beanName,aClass.newInstance()); } // service层往往是有接口的,面向接口开发,此时再以接口名为id,放入一份对象到ioc中,便于后期根据接口类型注入 Class<?>[] interfaces = aClass.getInterfaces(); for (int j = 0; j < interfaces.length; j++) { Class<?> anInterface = interfaces[j]; // 以接口的全限定类名作为id放入 ioc.put(anInterface.getName(),aClass.newInstance()); } }else{ continue; } } }catch (Exception e) { e.printStackTrace(); } } // 首字母小写方法 public String lowerFirst(String str) { char[] chars = str.toCharArray(); if('A' <= chars[0] && chars[0] <= 'Z') { chars[0] += 32; } return String.valueOf(chars); }需要定义编译器的编译细节,为了让编译器编译的时候能够记住形参的名字,而不是args1…等等。
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.lagou.edu</groupId> <artifactId>mvc</artifactId> <version>1.0-SNAPSHOT</version> <packaging>war</packaging> <name>mvc Maven Webapp</name> <!-- FIXME change it to the project's website --> <url>http://www.example.com</url> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>1.7</maven.compiler.source> <maven.compiler.target>1.7</maven.compiler.target> </properties> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> <scope>test</scope> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.1.0</version> <scope>provided</scope> </dependency> <dependency> <groupId>commons-lang</groupId> <artifactId>commons-lang</artifactId> <version>2.5</version> </dependency> </dependencies> <build> <plugins> <!--编译插件定义编译细节--> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.1</version> <configuration> <source>11</source> <target>11</target> <encoding>utf-8</encoding> <!--告诉编译器,编译的时候记录下形参的真实名称--> <compilerArgs> <arg>-parameters</arg> </compilerArgs> </configuration> </plugin> <plugin> <groupId>org.apache.tomcat.maven</groupId> <artifactId>tomcat7-maven-plugin</artifactId> <version>2.2</version> <configuration> <port>8080</port> <path>/</path> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>8</source> <target>8</target> </configuration> </plugin> </plugins> </build> </project>至此,我们手写SpringMVC框架已经基本完成。
微信公众号(程序员资料站):code_data