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>
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) ;
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 {
doLoadConfig ( config. getInitParameter ( "contextConfigLocation" ) ) ;
doScanner ( contextConfig. getProperty ( "scanPackage" ) ) ;
doInstance ( ) ;
doAutowired ( ) ;
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 ( ) ;
}
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 ) ) {
String beanName = toLowerFirstCase ( clazz. getSimpleName ( ) ) ;
RoshService roshService = clazz. getAnnotation ( RoshService. class ) ;
if ( ! "" . endsWith ( roshService. value ( ) ) ) {
beanName = roshService. value ( ) ;
}
Object o = clazz. newInstance ( ) ;
ioc. put ( beanName, o) ;
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 = 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 测试