亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

注解學習(模仿springMvc的注解注入方式)

2019-11-14 15:39:44
字體:
來源:轉載
供稿:網友

最近在看sPRingMvc的源碼,看到了該框架的注入注解的部分覺的有點吃力,可能還是對注解的方面的知識還認識的不夠深刻,所以特意去學習注解方面的知識。由于本人也是抱著學習的態度來閱讀源碼,若文章在表述和代碼方面如有不妥之處,歡迎批評指正。留下你的腳印,歡迎評論!希望能互相學習。

1,首先定義三個常用的注解Service,Autowired,Contrller;(主要的解釋都在代碼中有,在這里就不多陳述)

Service:

package com.lishun.Annotation;import java.lang.annotation.Documented;import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;/*Description: * @Target:指定注解的使用范圍(指的是,在哪些類型可以使用該注解:Service注解只能在類,接口(包括注解類型)或enum等使用) * 可選值: * 可選的值在枚舉類 ElemenetType 中,包括:           ElemenetType.CONSTRUCTOR 構造器聲明           ElemenetType.FIELD 域聲明(包括 enum 實例)           ElemenetType.LOCAL_VARIABLE 局部變量聲明          ElemenetType.ANNOTATION_TYPE 作用于注解量聲明          ElemenetType.METHOD 方法聲明          ElemenetType.PACKAGE 包聲明           ElemenetType.PARAMETER 參數聲明           ElemenetType.TYPE 類,接口(包括注解類型)或enum聲明  * */@Target(ElementType.TYPE)/*Description: * @Retention :表示在什么級別保存該注解信息 * 可選的參數值在枚舉類型 RetentionPolicy 中,包括:           RetentionPolicy.SOURCE 注解將被編譯器丟棄           RetentionPolicy.CLASS 注解在class文件中可用,但會被VM丟棄           RetentionPolicy.RUNTIME VM將在運行期也保留注釋,因此可以通過反射機制讀取注解的信息。  * */@Retention(RetentionPolicy.RUNTIME)/*@Documented 將此注解包含在 javadoc 中 ,它代表著此注解會被javadoc工具提取成文檔。 * 在doc文檔中的內容會因為此注解的信息內容不同而不同。相當與@see,@param 等。 * */@Documentedpublic @interface Service {    /* @interface用來聲明一個注解,其中的每一個方法實際上是聲明了一個配置參數。     * 方法的名稱就是參數的名稱,返回值類型就是參數的類型(返回值類型只能是基本類型、Class、String、enum)。     * 可以通過default來聲明參數的默認值。    */    String value() default "this is service annotation";}

 

Autowired:

package com.lishun.Annotation;import java.lang.annotation.Documented;import java.lang.annotation.ElementType;import java.lang.annotation.Inherited;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;@Target({ElementType.METHOD,ElementType.FIELD})  @Retention(RetentionPolicy.RUNTIME)  public @interface Autowired {      public String value() default "no description";  }

Contrller:

package com.lishun.Annotation;import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)public @interface Contrller {    String value() default "this is contrller annotation";}

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

2:javaBean數據池-BeanFactory:主要存放含有注解的類;

package com.lishun.factory;import java.util.HashMap;import java.util.Map;/** * Description:存放所有bean的數據池  * @author lishun * @since 2015-09-10 */public class BeanFactory {    private static Map<String, Object> map = new HashMap<String, Object>();    public static void addBean(String beanName, Object bean) {        map.put(beanName, bean);    }    public static Object getBean(String beanName) throws Exception {        Object o = map.get(beanName);        if (o != null) {            return o;        } else {            throw new Exception("未注入的類型:" + beanName);        }    }    public static Boolean containsBean(String beanName){        return map.containsKey(beanName);    }}

 

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

3:編寫處理注解的核心代碼(這里涉及的主要知識是反射,如果反射知識不夠熟練的話建議先學習反射方面的知識),主要涉及的兩個類是注解驅動(AnnotationDriven)和注解掃描類(PackUtils-這個類主要的是掃描包名下所有的類(如com.lishun,就是掃描該包下所有的類),代碼主要是來自網絡)

AnnotationDriven:

package com.lishun.utils;import java.lang.annotation.Annotation;import java.lang.reflect.Field;import java.util.List;import com.lishun.Annotation.Autowired;import com.lishun.Annotation.Contrller;import com.lishun.Annotation.Service;import com.lishun.factory.BeanFactory;/** * Description:注入驅動類,所有的注解注入都在這里實現(這里只實現了通過類型來注入值,其他方式沒實現,其實代碼都是差不多了,有興趣的可以自行腦補) * @author lishun * */public class AnnotationDriven {    public static void annotationDriven(String packName) throws Exception {        //注入Service和Contrller        List<Class<?>> classSaveServicePaths = PackUtils                .getClassListByAnnotation(packName, Service.class);        List<Class<?>> classSaveContrllerPaths = PackUtils                .getClassListByAnnotation(packName, Contrller.class);        saveBean(classSaveServicePaths);        saveBean(classSaveContrllerPaths);        //注入Autowired        List<Class<?>> classInjectPaths = PackUtils.getClassListByAnnotation(                packName, Autowired.class);        inject(classInjectPaths);    }    private static void saveBean(List<Class<?>> classSavePaths)            throws InstantiationException, IllegalaccessException {        for (Class<?> classPath : classSavePaths) {            try {                Class c = Class.forName(classPath.getName());                Object o = c.newInstance();                //掃描的到的含有注解的類實例化后保存在池中                BeanFactory.addBean(classPath.getName(), o);            } catch (ClassNotFoundException e) {                e.printStackTrace();            }        }    }    private static void inject(List<Class<?>> classInjectPaths) throws Exception {        Object o = null;        for (Class<?> classInjectPath : classInjectPaths) {            Class c = Class.forName(classInjectPath.getName());            //判斷存放bean的池中是否存在該bean            if (BeanFactory.containsBean(classInjectPath.getName())) {                o = BeanFactory.getBean(classInjectPath.getName());            } else {                o = c.newInstance();            }            Field[] fields = c.getDeclaredFields();            for (Field field : fields) {                Annotation[] annotations = field.getAnnotations();                for (Annotation annotation : annotations) {                    // 判斷是否是通過類型注解注入                    if (annotation instanceof Autowired) {                        Class classField = field.getType();                        Object clazz = BeanFactory                                .getBean(classField.getName());                        field.set(o, clazz);                        BeanFactory.addBean(classInjectPath.getName(), o);                    }                }            }        }    }}

PackUtils:

package com.lishun.utils;import java.io.File;import java.io.FileFilter;import java.lang.annotation.Annotation;import java.lang.reflect.Field;import java.net.JarURLConnection;import java.net.URL;import java.util.ArrayList;import java.util.Enumeration;import java.util.List;import java.util.jar.JarEntry;import java.util.jar.JarFile;/** * Description:掃描指定包工具類的注解 * @author lishun * @since 2015-09-10 */public class PackUtils {    public static List<Class<?>> getClassList(String packageName, boolean isRecursive) {        List<Class<?>> classList = new ArrayList<Class<?>>();        try {            Enumeration<URL> urls = Thread.currentThread().getContextClassLoader().getResources(packageName.replaceAll("http://.", "/"));            while (urls.hasMoreElements()) {                URL url = urls.nextElement();                if (url != null) {                    String protocol = url.getProtocol();                    if (protocol.equals("file")) {                        String packagePath = url.getPath();                        addClass(classList, packagePath, packageName, isRecursive);                    } else if (protocol.equals("jar")) {                        JarURLConnection jarURLConnection = (JarURLConnection) url.openConnection();                        JarFile jarFile = jarURLConnection.getJarFile();                        Enumeration<JarEntry> jarEntries = jarFile.entries();                        while (jarEntries.hasMoreElements()) {                            JarEntry jarEntry = jarEntries.nextElement();                            String jarEntryName = jarEntry.getName();                            if (jarEntryName.endsWith(".class")) {                                String className = jarEntryName.substring(0, jarEntryName.lastIndexOf(".")).replaceAll("/", ".");                                if (isRecursive || className.substring(0, className.lastIndexOf(".")).equals(packageName)) {                                    classList.add(Class.forName(className));                                }                            }                        }                    }                }            }        } catch (Exception e) {            e.printStackTrace();        }        return classList;    }    // 獲取指定包名下的所有類(可根據注解進行過濾)    public static List<Class<?>> getClassListByAnnotation(String packageName, Class<? extends Annotation> annotationClass) {        List<Class<?>> classList = new ArrayList<Class<?>>();        try {            Enumeration<URL> urls = Thread.currentThread().getContextClassLoader().getResources(packageName.replaceAll("http://.", "/"));            while (urls.hasMoreElements()) {                URL url = urls.nextElement();                if (url != null) {                    String protocol = url.getProtocol();                    if (protocol.equals("file")) {                        String packagePath = url.getPath();                        addClassByAnnotation(classList, packagePath, packageName, annotationClass);                    } else if (protocol.equals("jar")) {                        JarURLConnection jarURLConnection = (JarURLConnection) url.openConnection();                        JarFile jarFile = jarURLConnection.getJarFile();                        Enumeration<JarEntry> jarEntries = jarFile.entries();                        while (jarEntries.hasMoreElements()) {                            JarEntry jarEntry = jarEntries.nextElement();                            String jarEntryName = jarEntry.getName();                            if (jarEntryName.endsWith(".class")) {                                String className = jarEntryName.substring(0, jarEntryName.lastIndexOf(".")).replaceAll("/", ".");                                Class<?> cls = Class.forName(className);                                if (cls.isAnnotationPresent(annotationClass)) {                                    classList.add(cls);                                }                            }                        }                    }                }            }        } catch (Exception e) {            e.printStackTrace();        }        return classList;    }    private static void addClass(List<Class<?>> classList, String packagePath, String packageName, boolean isRecursive) {        try {            File[] files = getClassFiles(packagePath);            if (files != null) {                for (File file : files) {                    String fileName = file.getName();                    if (file.isFile()) {                        String className = getClassName(packageName, fileName);                        classList.add(Class.forName(className));                    } else {                        if (isRecursive) {                            String subPackagePath = getSubPackagePath(packagePath, fileName);                            String subPackageName = getSubPackageName(packageName, fileName);                            addClass(classList, subPackagePath, subPackageName, isRecursive);                        }                    }                }            }        } catch (Exception e) {            e.printStackTrace();        }    }    private static File[] getClassFiles(String packagePath) {        return new File(packagePath).listFiles(new FileFilter() {            @Override            public boolean accept(File file) {                return (file.isFile() && file.getName().endsWith(".class")) || file.isDirectory();            }        });    }    private static String getClassName(String packageName, String fileName) {        String className = fileName.substring(0, fileName.lastIndexOf("."));        if (!packageName.equals("")) {            className = packageName + "." + className;        }        return className;    }    private static String getSubPackagePath(String packagePath, String filePath) {        String subPackagePath = filePath;        if (!packagePath.equals("")) {            subPackagePath = packagePath + "/" + subPackagePath;        }        return subPackagePath;    }    private static String getSubPackageName(String packageName, String filePath) {        String subPackageName = filePath;        if (!packageName.equals("")) {            subPackageName = packageName + "." + subPackageName;        }        return subPackageName;    }    private static void addClassByAnnotation(List<Class<?>> classList, String packagePath, String packageName, Class<? extends Annotation> annotationClass) {        try {            File[] files = getClassFiles(packagePath);            if (files != null) {                for (File file : files) {                    String fileName = file.getName();                    if (file.isFile()) {                        String className = getClassName(packageName, fileName);                        Class<?> cls = Class.forName(className);                        if (cls.isAnnotationPresent(annotationClass)) {                            classList.add(cls);                        }                        Field[] fields=cls.getFields();                        for (Field field : fields) {                            if(field.isAnnotationPresent(annotationClass)){                                 classList.add(cls);                            }                        }                    } else {                        String subPackagePath = getSubPackagePath(packagePath, fileName);                        String subPackageName = getSubPackageName(packageName, fileName);                        addClassByAnnotation(classList, subPackagePath, subPackageName, annotationClass);                    }                }            }        } catch (Exception e) {            e.printStackTrace();        }    }}

 

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

4 最后編寫平時使用的設計模式來測試注解(Dao,Service,Contrller)【這里主要是為測試注解的注入,所以沒有使用實際的使用數據庫數據,側重點不在這里】

Dao

package com.lishun.Dao;import com.lishun.Annotation.Service;@Servicepublic class UserDao {    public void run(){        System.out.println("測試成功");    }}

Service:

package com.lishun.Service;import com.lishun.Annotation.Autowired;import com.lishun.Annotation.Service;import com.lishun.Dao.UserDao;@Servicepublic class UserService {    @Autowired    public UserDao userDao;    public void run(){         userDao.run();    }}

Controller:

package com.lishun.controller;import com.lishun.Annotation.Autowired;import com.lishun.Annotation.Contrller;import com.lishun.Service.UserService;@Contrllerpublic class UserContrller {    @Autowired    public  UserService userService;    public void login(){        userService.run();    }}

測試入口

package com.lishun.t;import java.lang.annotation.Annotation;import java.lang.reflect.Field;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;import java.util.Arrays;import java.util.List;import org.junit.Test;import com.lishun.Annotation.Autowired;import com.lishun.Annotation.Contrller;import com.lishun.Annotation.Service;import com.lishun.Dao.UserDao;import com.lishun.Service.UserService;import com.lishun.controller.UserContrller;import com.lishun.factory.BeanFactory;import com.lishun.utils.AnnotationDriven;import com.lishun.utils.PackUtils;public class test {    @Test    public void main() throws Exception {        //啟動時根據需要掃描的包名,來注入含有注解的類的字段值        AnnotationDriven.annotationDriven("com.lishun");        //這里相當于web的訪問一次controller的一次請求        UserContrller user = (UserContrller) BeanFactory                .getBean("com.lishun.controller.UserContrller");        user.login();    }}

最后運行,

控制臺輸出:測試成功

由于本人水平有限,若文章在表述和代碼方面如有不妥之處,歡迎批評指正。留下你的腳印,歡迎評論!希望能互相學習。需要源碼的留下郵箱

 


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
亚洲国产欧美一区二区丝袜黑人| 国产精品久久久久久久久借妻| 亚洲女成人图区| 亚洲激情视频在线播放| 欧美老女人性视频| 国产成人精品网站| 日韩av黄色在线观看| 亚洲电影免费观看高清完整版在线观看| 亚洲美女在线观看| 精品久久香蕉国产线看观看亚洲| 亚洲电影免费观看高清完整版在线| 97视频免费在线观看| 午夜精品www| 欧美在线精品免播放器视频| 日韩免费看的电影电视剧大全| 欧美午夜无遮挡| 欧美另类精品xxxx孕妇| 欧美福利小视频| 亚洲一区精品电影| 国产剧情久久久久久| 日韩中文字幕在线视频播放| 欧美老女人在线视频| 欧美激情一区二区三区久久久| 日韩精品极品在线观看播放免费视频| 亚洲a级在线播放观看| 成人在线一区二区| 欧美精品少妇videofree| 国产脚交av在线一区二区| 日韩黄色av网站| 超在线视频97| 7777kkkk成人观看| 亚洲色图狂野欧美| 国产精品情侣自拍| 久久在精品线影院精品国产| 精品国产老师黑色丝袜高跟鞋| 欧美疯狂做受xxxx高潮| 宅男66日本亚洲欧美视频| 日韩av电影中文字幕| 国产成人精品久久久| 国产欧美日韩中文字幕| 日韩精品在线播放| 91精品国产色综合久久不卡98口| 亚洲小视频在线观看| 日本精品视频在线播放| 国产91网红主播在线观看| 亚洲国产精品成人一区二区| 欧美大秀在线观看| 成人午夜高潮视频| 日韩一区二区欧美| 亚洲欧美一区二区三区四区| 欧美大片在线看免费观看| 主播福利视频一区| 91亚洲精品视频| 美女啪啪无遮挡免费久久网站| 日韩av资源在线播放| 亚洲色图五月天| 欧美激情一区二区三区在线视频观看| 4438全国亚洲精品在线观看视频| 国产福利视频一区二区| 国产精品福利观看| 亚洲黄在线观看| 午夜精品久久久久久99热| 国产成人精品一区二区在线| 77777亚洲午夜久久多人| 美女少妇精品视频| 中文字幕亚洲色图| 国产成人亚洲综合青青| 最新69国产成人精品视频免费| 亚洲欧美综合区自拍另类| 国产一区二区视频在线观看| 日韩精品亚洲精品| 亚洲国产精品国自产拍av秋霞| 5252色成人免费视频| 国产91精品黑色丝袜高跟鞋| 成人h视频在线观看播放| 亚洲性av在线| 久久在线免费观看视频| 成人黄色av网| 日韩精品高清在线| 中国日韩欧美久久久久久久久| 国产一区二区免费| 欧美性猛交xxxxx水多| 国产一区二区在线免费视频| 亚洲成人av在线播放| 国产精品视频一区二区高潮| 最近2019免费中文字幕视频三| 久久夜色精品国产亚洲aⅴ| 国产成人精品久久二区二区| 欧美黑人又粗大| 亚洲成人网久久久| 最近中文字幕mv在线一区二区三区四区| 午夜精品免费视频| 奇米成人av国产一区二区三区| 国产欧美日韩丝袜精品一区| 亚洲第一免费网站| 久久久噜久噜久久综合| 97视频人免费观看| 欧美成人性色生活仑片| 久久精视频免费在线久久完整在线看| 国产伊人精品在线| 久久精品国产久精国产一老狼| 成人亲热视频网站| 国产精品白丝jk喷水视频一区| 欧美精品在线免费观看| 日韩在线国产精品| 亚洲日韩中文字幕在线播放| 国产成人在线播放| 日韩欧美一区二区在线| 精品视频久久久久久久| 美女扒开尿口让男人操亚洲视频网站| 日本欧美一二三区| 中文日韩电影网站| 中文字幕少妇一区二区三区| 国产精品久久一| 久久久国产一区二区三区| 久久久免费精品| 久久人人爽人人爽人人片av高请| 91综合免费在线| 精品国产一区二区三区四区在线观看| 在线激情影院一区| 97精品国产97久久久久久免费| 97人人爽人人喊人人模波多| 日韩精品在线观看网站| 国产精品久久久久久久久| 成人免费观看网址| 中国china体内裑精亚洲片| 主播福利视频一区| 国产成人综合亚洲| 色婷婷亚洲mv天堂mv在影片| 亚洲精品动漫100p| 成人中心免费视频| 成人午夜在线视频一区| 色妞欧美日韩在线| 欧美日韩亚洲一区二区| 欧美一级淫片丝袜脚交| 国产91免费看片| 97涩涩爰在线观看亚洲| 91国内产香蕉| 国产剧情日韩欧美| 亚洲色图第一页| 久久全国免费视频| 中文字幕成人精品久久不卡| 久久免费少妇高潮久久精品99| 欧美wwwwww| 97成人超碰免| 欧美中文在线免费| 欧美成人午夜影院| 欧美性生交大片免网| 久久国产精品99国产精| 中文字幕亚洲综合久久| 在线电影av不卡网址| 久久久久久久久久婷婷| 欧美一级片在线播放| 国产美女高潮久久白浆| 国产精品日韩在线| 久久成年人视频| 91网站在线看| 国产精品久久久久久av福利软件| 国产日韩欧美一二三区| 一二美女精品欧洲| 91po在线观看91精品国产性色| 国产乱人伦真实精品视频| 久久久黄色av| 日韩视频精品在线|