日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

Spring容器初始化实现V2 版本

發布時間:2024/4/13 javascript 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Spring容器初始化实现V2 版本 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

在V1 版本上進了優化,采用了常用的設計模式(工廠模式、單例模式、委派模式、策略模式),將init()方法中的代碼進行封裝。按照之前的實現思路,先搭基礎框架,再填肉注血,具體代碼如下:

//初始化階段 @Override public void init(ServletConfig config) throws ServletException {//1、加載配置文件doLoadConfig(config.getInitParameter("contextConfigLocation"));//2、掃描相關的類doScanner(contextConfig.getProperty("scanPackage"));//3、初始化掃描到的類,并且將它們放入到ICO容器之中doInstance();//4、完成依賴注入doAutowired();//5、初始化HandlerMappinginitHandlerMapping();System.out.println("GP Spring framework is init.");}

聲明全局的成員變量,其中IOC 容器就是注冊時單例的具體案例:

//保存application.properties配置文件中的內容 private Properties contextConfig = new Properties();//保存掃描的所有的類名 private List<String> classNames = new ArrayList<String>();//傳說中的IOC容器,我們來揭開它的神秘面紗 //為了簡化程序,暫時不考慮ConcurrentHashMap // 主要還是關注設計思想和原理 private Map<String,Object> ioc = new HashMap<String,Object>();//保存url和Method的對應關系 private Map<String,Method> handlerMapping = new HashMap<String,Method>();

實現doLoadConfig()方法:

//加載配置文件 private void doLoadConfig(String contextConfigLocation) {//直接從類路徑下找到Spring主配置文件所在的路徑//并且將其讀取出來放到Properties對象中//相對于scanPackage=com.gupaoedu.demo 從文件中保存到了內存中InputStream fis = this.getClass().getClassLoader().getResourceAsStream(contextConfigLocation);try {contextConfig.load(fis);} catch (IOException e) {e.printStackTrace();}finally {if(null != fis){try {fis.close();} catch (IOException e) {e.printStackTrace();}}} }

實現doScanner()方法:

//掃描出相關的類 private void doScanner(String scanPackage) {//scanPackage = com.gupaoedu.demo ,存儲的是包路徑//轉換為文件路徑,實際上就是把.替換為/就OK了//classpathURL url = this.getClass().getClassLoader().getResource("/" + scanPackage.replaceAll("\\.","/"));File classPath = new File(url.getFile());for (File file : classPath.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);}} }

實現doInstance()方法,doInstance()方法就是工廠模式的具體實現:

private void doInstance() {//初始化,為DI做準備if(classNames.isEmpty()){return;}try {for (String className : classNames) {Class<?> clazz = Class.forName(className);//什么樣的類才需要初始化呢?//加了注解的類,才初始化,怎么判斷?//為了簡化代碼邏輯,主要體會設計思想,只舉例 @Controller和@Service,// @Componment...就一一舉例了if(clazz.isAnnotationPresent(GPController.class)){Object instance = clazz.newInstance();//Spring默認類名首字母小寫String beanName = toLowerFirstCase(clazz.getSimpleName());ioc.put(beanName,instance);}else if(clazz.isAnnotationPresent(GPService.class)){//1、自定義的beanNameGPService service = clazz.getAnnotation(GPService.class);String beanName = service.value();//2、默認類名首字母小寫if("".equals(beanName.trim())){beanName = toLowerFirstCase(clazz.getSimpleName());}Object instance = clazz.newInstance();ioc.put(beanName,instance);//3、根據類型自動賦值,投機取巧的方式for (Class<?> i : clazz.getInterfaces()) {if(ioc.containsKey(i.getName())){throw new Exception("The “" + i.getName() + "” is exists!!");}//把接口的類型直接當成key了ioc.put(i.getName(),instance);}}else {continue;}}}catch (Exception e){e.printStackTrace();}}

為了處理方便,自己實現了toLowerFirstCase 方法,來實現類名首字母小寫,具體代碼如下:

//如果類名本身是小寫字母,確實會出問題 //但是我要說明的是:這個方法是我自己用,private的 //傳值也是自己傳,類也都遵循了駝峰命名法 //默認傳入的值,存在首字母小寫的情況,也不可能出現非字母的情況//為了簡化程序邏輯,就不做其他判斷了,大家了解就OK //其實用寫注釋的時間都能夠把邏輯寫完了 private String toLowerFirstCase(String simpleName) {char [] chars = simpleName.toCharArray();//之所以加,是因為大小寫字母的ASCII碼相差32,// 而且大寫字母的ASCII碼要小于小寫字母的ASCII碼//在Java中,對char做算學運算,實際上就是對ASCII碼做算學運算chars[0] += 32;return String.valueOf(chars); }

實現doAutowired()方法:

//自動依賴注入 private void doAutowired() {if(ioc.isEmpty()){return;}for (Map.Entry<String, Object> entry : ioc.entrySet()) {//Declared 所有的,特定的 字段,包括private/protected/default//正常來說,普通的OOP編程只能拿到public的屬性Field[] fields = entry.getValue().getClass().getDeclaredFields();for (Field field : fields) {if(!field.isAnnotationPresent(GPAutowired.class)){continue;}GPAutowired autowired = field.getAnnotation(GPAutowired.class);//如果用戶沒有自定義beanName,默認就根據類型注入//這個地方省去了對類名首字母小寫的情況的判斷,這個作為課后作業//小伙伴們自己去完善String beanName = autowired.value().trim();if("".equals(beanName)){//獲得接口的類型,作為key待會拿這個key到ioc容器中去取值beanName = field.getType().getName();}//如果是public以外的修飾符,只要加了@Autowired注解,都要強制賦值//反射中叫做暴力訪問, 強吻field.setAccessible(true);try {//用反射機制,動態給字段賦值field.set(entry.getValue(),ioc.get(beanName));} catch (IllegalAccessException e) {e.printStackTrace();}}}}

實現initHandlerMapping()方法,handlerMapping 就是策略模式的應用案例:

//初始化url和Method的一對一對應關系 private void initHandlerMapping() {if(ioc.isEmpty()){ return; }for (Map.Entry<String, Object> entry : ioc.entrySet()) {Class<?> clazz = entry.getValue().getClass();if(!clazz.isAnnotationPresent(GPController.class)){continue;}//保存寫在類上面的@GPRequestMapping("/demo")String baseUrl = "";if(clazz.isAnnotationPresent(GPRequestMapping.class)){GPRequestMapping requestMapping = clazz.getAnnotation(GPRequestMapping.class);baseUrl = requestMapping.value();}//默認獲取所有的public方法for (Method method : clazz.getMethods()) {if(!method.isAnnotationPresent(GPRequestMapping.class)){continue;}GPRequestMapping requestMapping = method.getAnnotation(GPRequestMapping.class);//優化// //demo///queryString url = ("/" + baseUrl + "/" + requestMapping.value()).replaceAll("/+","/");handlerMapping.put(url,method);System.out.println("Mapped :" + url + "," + method);}}}

到這里位置初始化階段就已經完成,接下實現運行階段的邏輯,來看doPost/doGet 的代碼:

@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 {//6、調用,運行階段try {doDispatch(req,resp);} catch (Exception e) {e.printStackTrace();resp.getWriter().write("500 Exection,Detail : " + Arrays.toString(e.getStackTrace()));}}

doPost()方法中,用了委派模式,委派模式的具體邏輯在doDispatch()方法中:

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)){resp.getWriter().write("404 Not Found!!!");return;}Method method = this.handlerMapping.get(url);//從reqest中拿到url傳過來的參數Map<String,String[]> params = req.getParameterMap();//獲取方法的形參列表Class<?> [] parameterTypes = method.getParameterTypes();Object [] paramValues = new Object[parameterTypes.length];for (int i = 0; i < parameterTypes.length; i ++) {Class parameterType = parameterTypes[i];//不能用instanceof,parameterType它不是實參,而是形參if(parameterType == HttpServletRequest.class){paramValues[i] = req;continue;}else if(parameterType == HttpServletResponse.class){paramValues[i] = resp;continue;}else if(parameterType == String.class){GPRequestParam requestParam = (GPRequestParam)parameterType.getAnnotation(GPRequestParam.class);if(params.containsKey(requestParam.value())) {for (Map.Entry<String,String[]> param : params.entrySet()){String value = Arrays.toString(param.getValue()).replaceAll("\\[|\\]","").replaceAll("\\s",",");paramValues[i] = value;}}}}//投機取巧的方式//通過反射拿到method所在class,拿到class之后還是拿到class的名稱//再調用toLowerFirstCase獲得beanNameString beanName = toLowerFirstCase(method.getDeclaringClass().getSimpleName());method.invoke(ioc.get(beanName),paramValues); }

?

總結

以上是生活随笔為你收集整理的Spring容器初始化实现V2 版本的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 国产人成一区二区三区影院 | 国产精品无码久久久久高潮 | 成人在线观看18 | 国产一级精品毛片 | 激情文学欧美 | 性一交一乱一伧国产女士spa | 日韩在线观看视频一区二区 | 日韩免费视频一区 | 一区二区视频免费 | 亚洲一区 视频 | 中文字幕999 | 国产污污视频 | 成人精品久久久 | 免费一区二区三区 | 精品国产av无码 | 精品国产一区在线 | 亚洲一区中文字幕在线观看 | av三级在线观看 | 草草在线视频 | 大肉大捧一进一出好爽mba | 免费在线观看的黄色网址 | 中文字幕av一区二区三区 | 久久国产夫妻 | 美女擦边视频 | 免费国产黄色 | 久久久久久久久久久久91 | 日韩精品在线观看视频 | 免费毛片网站 | 国产天天骚 | 懂色a v| 91久久精品日日躁夜夜躁欧美 | 黄色在线观看av | av一级网站 | 中文无码精品一区二区三区 | 青青国产精品视频 | 99综合久久 | 免费成人深夜夜 | 国产黑丝91 | 在线一区二区三区四区五区 | 精品国产免费人成在线观看 | 视频在线不卡 | 亚洲欧美日本另类 | 女同在线视频 | 在线观看黄网 | 秋霞久久精品 | 麻豆91网站 | 亚洲成人黄色在线观看 | 婷婷亚洲综合五月天小说 | 性淫bbwbbwbbw| 四虎影视成人永久免费观看亚洲欧美 | 日本黄色三级视频 | 1515hh成人免费看 | 超碰牛牛 | 91制服诱惑 | 91久久综合| 99国产精品久久久久久久 | 狼人av在线| 漂亮人妻被中出中文字幕 | 亚洲一级特黄毛片 | 亚洲AV无码片久久精品 | 日剧大尺度床戏做爰 | 福利综合网| 国产调教视频 | www伊人 | 内地级a艳片高清免费播放 91在线精品一区二区 | 在线看免费| 精品久久久噜噜噜久久久 | 亚洲欧美日韩在线一区二区 | 亚洲一区二区日韩 | 无码日韩精品一区二区 | 日本特黄一级 | 国内毛片毛片毛片毛片 | 久久久久成人精品无码 | 国产精品视频一区二区在线观看 | 国产www性| 日韩欧美大片在线观看 | 免费成人福利视频 | 黄色变态网站 | 麻豆一区二区99久久久久 | 97热久久| 台湾佬成人中文网222vvv | 欧美少妇一区二区三区 | 国产视频手机在线 | 黄色应用在线观看 | 免费激情网址 | 在线中文字幕观看 | 日韩性大片 | 欧美精选一区二区 | 久久艹在线观看 | 亚洲午夜精品久久久 | 国产三级a | 亚洲快播 | 欧美黄色一区 | 国产精品自拍在线观看 | 国产资源在线观看 | 欧美一级二级三级视频 | 嫩草视频在线观看 | 久久久久www | 黄色片网站免费在线观看 |