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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

自己动手写spring(三) 支持注解方式

發布時間:2025/3/15 编程问答 19 豆豆
生活随笔 收集整理的這篇文章主要介紹了 自己动手写spring(三) 支持注解方式 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前言

本文使用注解方式來讀取bean類,并解決bean之間的依賴。其中Component和Value注解直接copy自Spring,Resource注解來自javax。

掃描包中的所有類

還是以前文提到的beanA和beanB兩個model類為例(省略set和get方法)。

@Component public class BeanA {@Value("studentA")private String title;@Resourceprivate BeanB beanB; }@Component public class BeanB {@Value("studentB")private String title; }

根據前文,我們可以發現,要實現bean工廠功能,首先要將bean信息加載到內存(由配置文件方式轉化為“以類的方式”存儲)。
在本文中,雖然配置文件沒了,但思路是一致的。我們要根據注解,采集bean信息,存儲在map中。注解和配置文件方式的一個不同是:配置文件是配什么bean加載什么,而注解方式,則需要我們掃描目標pacakge中的所有bean。

public class Main {private static Map<String,Class> beanId2Clazz = new HashMap<String,Class>();// 將一個字符串的首字符小寫private static String smallCaseFirstChar(String prop){char ch = (char) (prop.charAt(0) + 32);return prop.replaceFirst(prop.charAt(0) + "", ch + "");}public static void main(String[] args) throws Exception {// 掃描包中包含的類(即掃描目的包所在文件的子文件)String packageName = "org.lqk.lspring.bean";String rootPath = Main3.class.getResource("/").getPath();File file = new File(rootPath + File.separator + packageName.replace(".", File.separator));String[] fileNames = file.list();// 掃描for(String fileName : fileNames){String className = fileName.substring(0,fileName.length() - ".class".length());String fullClassName = packageName + "." + className;Class clazz = Class.forName(fullClassName);Component cop = (Component) clazz.getAnnotation(Component.class);if(null != cop){String beanId = cop.value();if(StringUtils.isEmpty(beanId)){beanId = smallCaseFirstChar(className);}beanId2Clazz.put(beanId, clazz);}}} }

關于掃描一個包中所有的類,有現成的org.reflections包,此處為了減少##讀者的理解曲線,就不提了。

當加載完bean的信息后,整個步驟已經跟前文很像了。

加載beanB類

public class Main {private static Map<String,Class> beanId2Clazz = new HashMap<String,Class>();public static void load() throws ClassNotFoundException {// 即為上述的main類}public static Object getBean(String beanId) throws Exception{Class clazz = beanId2Clazz.get(beanId);if(null == clazz){return null;}Object obj = clazz.newInstance();Field[] fields = clazz.getDeclaredFields();// 處理帶value注解的屬性for(Field field : fields){Value v = field.getAnnotation(Value.class);if(null == v){continue;}String propertyValue = v.value();Method m = clazz.getMethod("set" + bigCaseFirstChar(field.getName()), String.class);m.invoke(obj, propertyValue);}return obj;}public static void main(String[] args) throws Exception {load();BeanB beanB = (BeanB)getBean("beanB");System.out.println(beanB.getTitle());} }

加載beanA類

public class Main2 {private static Map<String,Class> beanId2Clazz = new HashMap<String,Class>();public static void load() throws ClassNotFoundException {// 不再贅述}public static Object getBean(String beanId) throws Exception{Class clazz = beanId2Clazz.get(beanId);if(null == clazz){return null;}Object obj = clazz.newInstance();Field[] fields = clazz.getDeclaredFields();for(Field field : fields){Method m = clazz.getMethod("set" + bigCaseFirstChar(field.getName()), field.getType());Value v = field.getAnnotation(Value.class);// 處理value注解if(null != v){String propertyValue = v.value();m.invoke(obj, propertyValue);}Resource r = field.getAnnotation(Resource.class);// 處理resource注解if(null != r){String propertyBeanId = r.name();if(StringUtils.isEmpty(propertyBeanId)){propertyBeanId = smallCaseFirstChar(field.getType().getSimpleName());}// 遞歸處理Object propertyObj = getBean(propertyBeanId);m.invoke(obj, propertyObj);}}return obj;}public static void main(String[] args) throws Exception {load();BeanA beanA = (BeanA)getBean("beanA");System.out.println(beanA.getBeanB().getTitle());} }

至此,我們已經完全使用注解方式創建了一個bean工廠,下文將會嘗試把注解和配置文件兩種方式整合到一塊兒。

轉載于:https://www.cnblogs.com/qiankunli/p/4943806.html

總結

以上是生活随笔為你收集整理的自己动手写spring(三) 支持注解方式的全部內容,希望文章能夠幫你解決所遇到的問題。

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