注解只是一种特殊的标记,要使它具备特殊的含义或者是特殊的执行效果就需要配合 反射 来用
注解分为元注解和自定义注解
元注解就是用来注解其他的注解 如:
1、Target 用来注解对象类型--当前对象是用在类,方法,字段---用到枚举 ElementType
2、Retention 用来注解对象的保留时间-SOURCE(编译时),CLASS(字节码),RUNTIME(运行时)等
自定义注解
规范
1、类的声明
public @interface Controller{}
2、变量声明
String value();
注解分为元注解和自定义注解
元注解就是用来注解其他的注解 如:
1、Target 用来注解对象类型--当前对象是用在类,方法,字段---用到枚举 ElementType
2、Retention 用来注解对象的保留时间-SOURCE(编译时),CLASS(字节码),RUNTIME(运行时)等
自定义注解
规范
1、类的声明
public @interface Controller{}
2、变量声明
String value();
String[] values();
注解实例
模拟spring注解中的@RequestMapping和@Controller
/**
* 定义RequestMapping注解
* @author Administrator
*
*/
@Target({ElementType.TYPE,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface RequestMapping {
String value();
}
/**
* 定义Controller注解
* @author Administrator
*
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Controller {
}
/**
* 继承HttpServlet,配合反射
* Servlet implementation class DispachterServlet
*/
@WebServlet("/")
public class DispachterServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
//存储controller类-类名对应类
Map<String,Object> controllers = new HashMap<String,Object>();
//存储方法--注解对应方法
Map<String,Method> methods = new HashMap<String,Method>();
/**
* @see HttpServlet#HttpServlet()
*/
public DispachterServlet() {
super();
}
/**
* 初始化
*/
@Override
public void init(){//模拟spring Mvc
System.out.println("开始初始化");
//1扫描基础包,通过file对象 使用io读取文件名-文件名与类名一致
//简易实现
String[] className = {"com.yd.test.IndexController","com.yd.test.TestController"};
try {
for (String cn: className) {
Class<?> clazz = Class.forName(cn);
//将类名和实例装进map中
controllers.put(clazz.getName(), clazz.newInstance());
Method[] ms = clazz.getMethods();
//获取当前类的注解
RequestMapping classAnnotation = clazz.getAnnotation(RequestMapping.class);
String requestpath = "";
for (Method method : ms) {
RequestMapping methodAnnotation = method.getAnnotation(RequestMapping.class);
if(methodAnnotation==null){
continue;
}
//java类中的注解与方法注解进行合并,拼成完整路径
if(classAnnotation!=null){
requestpath = classAnnotation.value()+methodAnnotation.value();
}else{
requestpath = methodAnnotation.value();
}
//存入map中
methods.put(requestpath, method);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* @see HttpServlet#service(HttpServletRequest request, HttpServletResponse response)
*/
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("进入doGet");
//在此步骤中要获取访问路径
try { //调用管理请求转向方法
manageRequest(request,response);
} catch (Exception e) {
e.printStackTrace();
}
}
public void manageRequest(HttpServletRequest request, HttpServletResponse response) throws Exception{
//项目路径
String contextPath = request.getContextPath();
//完整的请求路径
String requestURI = request.getRequestURI();
//获取requestMapping的请求路径--注解名称
String requestMappingPath = requestURI.substring(requestURI.indexOf(contextPath)+contextPath.length(),requestURI.length());
Method method = methods.get(requestMappingPath);
String className = method.getDeclaringClass().getName();
Object controller = controllers.get(className);
try {
String result = (String) method.invoke(controller);
//跳转页面
System.out.println(contextPath+"/"+result);
request.setCharacterEncoding("UTF-8");
request.getRequestDispatcher("/"+result).forward(request, response);
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
e.printStackTrace();
}
}
}
/**
* 测试类
* @author Administrator
*
*/
@Controller
@RequestMapping("/ic")
public class IndexController {
@RequestMapping("/index")
public String index(){
return "index.jsp";
}
}
配置web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
version="3.0">
<welcome-file-list>
<welcome-file>/</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>DispachterServlet</servlet-name>
<servlet-class>com.yd.reflect.DispachterServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>DispachterServlet</servlet-name>
<url-pattern>/DispachterServlet</url-pattern>
</servlet-mapping>
</web-app>