1 工程目录

2 pom
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
<configuration>
<path>/</path>
<port>8080</port>
</configuration>
</plugin>
</plugins>
</build>
3 web.xml
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
<display-name>Rosh Created Web Application</display-name>
<servlet>
<servlet-name>roshmvc</servlet-name>
<servlet-class>com.rosh.mvcframework.servlet.RoshDispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>application.properties</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>roshmvc</servlet-name>
<url-pattern>/*</url-pattern> </servlet-mapping> </web-app>
4 application.properties
scanPackage=com.rosh.demo
5 注解
@Target({ ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RoshService {
String value() default "";
}
@Target({ ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RoshRequestParam {
String value() default "";
}
@Target({ ElementType.TYPE,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RoshRequestMapping {
String value() default "";
}
@Target({ ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RoshController {
String value() default "";
}
@Target({ ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RoshAutowired {
String value() default "";
}
6 RoshDispatcherServlet
package com.rosh.mvcframework.servlet;
import com.rosh.mvcframework.annotation.RoshAutowired;
import com.rosh.mvcframework.annotation.RoshController;
import com.rosh.mvcframework.annotation.RoshRequestMapping;
import com.rosh.mvcframework.annotation.RoshService;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.net.URL;
import java.util.*;
public class RoshDispatcherServlet extends HttpServlet {
private Properties contextConfig = new Properties();
private List<String> classNames = new ArrayList<>();
private Map<String, Object> ioc = new HashMap<>();
private Map<String, Method> handlerMapping = new HashMap<>();
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//调用
try {
doDispatch(req, resp);
} catch (Exception e) {
e.printStackTrace();
}
}
private void doDispatch(HttpServletRequest req, HttpServletResponse resp) throws Exception {
//绝对路径
String url = req.getRequestURI();
//相对路径
String contextPath = req.getContextPath();
url = url.replaceAll(contextPath, "").replaceAll("/+", "/");
if (this.handlerMapping.containsKey(url)) {
Method method = this.handlerMapping.get(url);
//beanname
String beanName = toLowerFirstCase(method.getDeclaringClass().getSimpleName());
//参数
Map<String, String[]> parameterMap = req.getParameterMap();
method.invoke(ioc.get(beanName), new Object[]{ req, resp, parameterMap.get("name")[0]});
} else {
resp.getWriter().write("404 Not Found!!!!");
}
}
@Override
public void init(ServletConfig config) throws ServletException {
//1 加载配置文件
doLoadConfig(config.getInitParameter("contextConfigLocation"));
//2 扫描相关类
doScanner(contextConfig.getProperty("scanPackage"));
//3 初始化扫描到的类,并且将他们放入到IOC容器中
doInstance();
//4 完成依赖注入
doAutowired();
//5 初始化HandlerMapping
initHandlerMapping();
System.out.println("Rosh Spring framework is init.");
}
/** * 映射 */
private void initHandlerMapping() {
if (!ioc.isEmpty()) {
for (Map.Entry<String, Object> entry : ioc.entrySet()) {
Class<?> clazz = entry.getValue().getClass();
if (clazz.isAnnotationPresent(RoshController.class)) {
String baseUrl = "";
if (clazz.isAnnotationPresent(RoshRequestMapping.class)) {
RoshRequestMapping requestMapping = clazz.getAnnotation(RoshRequestMapping.class);
baseUrl = requestMapping.value();
}
//获取所有public 方法
Method[] methods = clazz.getMethods();
for (Method method : methods) {
if (method.isAnnotationPresent(RoshRequestMapping.class)) {
RoshRequestMapping requestMapping = method.getAnnotation(RoshRequestMapping.class);
String url = (baseUrl + "/" + requestMapping.value()).replaceAll("/+", "/");
handlerMapping.put(url, method);
}
}
}
}
}
}
/** * 自动注入 */
private void doAutowired() {
if (!ioc.isEmpty()) {
for (Map.Entry<String, Object> entry : ioc.entrySet()) {
//所有字段
Field[] fields = entry.getValue().getClass().getDeclaredFields();
for (Field field : fields) {
if (field.isAnnotationPresent(RoshAutowired.class)) {
RoshAutowired autowired = field.getAnnotation(RoshAutowired.class);
String beanName = autowired.value();
if ("".endsWith(beanName)) {
beanName = field.getType().getName();
}
field.setAccessible(true);
try {
//反射机制,动态赋值
field.set(entry.getValue(), ioc.get(beanName));
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
}
}
}
/** * 初始化 */
private void doInstance() {
if (classNames.isEmpty()) {
return;
}
try {
for (String className : classNames) {
Class<?> clazz = Class.forName(className);
//判断注解
if (clazz.isAnnotationPresent(RoshController.class)) {
Object o = clazz.newInstance();
String beanName = toLowerFirstCase(clazz.getSimpleName());
ioc.put(beanName, o);
} else if (clazz.isAnnotationPresent(RoshService.class)) {
//1 默认beanName
String beanName = toLowerFirstCase(clazz.getSimpleName());
//2 自定义beanName
RoshService roshService = clazz.getAnnotation(RoshService.class);
if (!"".endsWith(roshService.value())) {
beanName = roshService.value();
}
Object o = clazz.newInstance();
ioc.put(beanName, o);
//3 根据类型自动赋值
for (Class<?> i : clazz.getInterfaces()) {
if (!ioc.containsKey(i.getName())) {
ioc.put(i.getName(), o);
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
private String toLowerFirstCase(String simpleName) {
char[] chars = simpleName.toCharArray();
chars[0] += 32;
return String.valueOf(chars);
}
/** * 扫描出相关的类 */
private void doScanner(String scanPackage) {
//获取类文件url
URL url = this.getClass().getClassLoader().getResource(scanPackage.replaceAll("\\.", "/"));
//读取当前类文件
File rootFile = new File(url.getFile());
//遍历
for (File file : rootFile.listFiles()) {
if (file.isDirectory()) {
doScanner(scanPackage + "." + file.getName());
} else {
if (!file.getName().endsWith(".class")) {
continue;
}
//获取类名
String className = scanPackage + "." + file.getName().replace(".class", "");
classNames.add(className);
}
}
}
/** * 加载配置文件 */
private void doLoadConfig(String contextConfigLocation) {
InputStream is = this.getClass().getClassLoader().getResourceAsStream(contextConfigLocation);
try {
contextConfig.load(is);
} catch (IOException e) {
e.printStackTrace();
} finally {
if (is != null) {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
7 业务类
@RoshController
@RoshRequestMapping("/student")
public class StudentController {
@RoshAutowired
private StudentService studentService;
@RoshRequestMapping("/query")
public void query(HttpServletRequest req, HttpServletResponse resp,
@RoshRequestParam("name") String name) {
String result = "<h1>My name is " + name + "</h1>";
try {
resp.getWriter().write(result);
} catch (IOException e) {
e.printStackTrace();
}
}
}
public interface StudentService {
}
@RoshService
public class StudentServiceImpl implements StudentService {
}
8 测试

还没有评论,来说两句吧...