溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

spring中注解處理框架解析以及源代碼實現(xiàn)是怎樣的

發(fā)布時間:2021-10-14 14:40:29 來源:億速云 閱讀:144 作者:柒染 欄目:編程語言

這期內(nèi)容當中小編將會給大家?guī)碛嘘Pspring中注解處理框架解析以及源代碼實現(xiàn)是怎樣的,文章內(nèi)容豐富且以專業(yè)的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。

@Autowired和@Resource的區(qū)別:

在Java中使用@Autowired和@Resource注解進行裝配,這兩個注解分別是:
1、@Autowired按照默認類型(類名稱)裝配依賴對象,默認情況下它要求依賴對象必須存在,如果允許為null,可以設置它的required屬性為false
如果我們按名稱裝配,可以結合@Qualifie注解一起使用。
如:
@Autowired @qualifie("personDaoBean")
private PersonDaoBean personDaoBean;

@Resource默認按照名稱(name="test")進行裝配,名稱可以通過@resource的name屬性設定,當找不到與名稱匹配的bean才會按類型裝配

注意:如果沒有指定name屬性,并且安裝默認的名稱依然找不到依賴對象時,@Resource會回退到按類型裝配。但一旦指定了name屬性,就只能按名稱裝配了。

下面的示例來簡單的講述spring注解原理:

實現(xiàn)了在set方法上和在字段屬性上注解的處理解析。

1、定義注解

Java代碼  

  1. package com.yt.annotation;  


  2. import java.lang.annotation.ElementType;  

  3. import java.lang.annotation.Retention;  

  4. import java.lang.annotation.RetentionPolicy;  

  5. import java.lang.annotation.Target;  


  6. /**

  7.  * @Description:定義注解

  8.  * @ClassName: ZxfResource

  9.  * @Project: spring-aop

  10.  * @Author: zxf

  11.  * @Date: 2011-6-7

  12.  */

  13. // 在運行時執(zhí)行

  14. @Retention(RetentionPolicy.RUNTIME)  

  15. // 注解適用地方(字段和方法)

  16. @Target({ ElementType.FIELD, ElementType.METHOD })  

  17. public @interface ZxfResource {  


  18.     //注解的name屬性

  19.     public String name() default "";  

  20. }  

 2、帶有注解的服務類

Java代碼  spring中注解處理框架解析以及源代碼實現(xiàn)是怎樣的

  1. package com.yt.annotation;  


  2. /**

  3.  * @Description: 帶有注解的服務

  4.  * @ClassName: UserDaoImpl

  5.  * @Project: spring-aop

  6.  * @Author: zxf

  7.  * @Date: 2011-6-7

  8.  */

  9. public class UserServiceImpl {  


  10.     public UserDaoImpl userDao;  

  11.     public User1DaoImpl user1Dao;  


  12.     // 字段上的注解,可以配置name屬性

  13.     @ZxfResource

  14.     public User2DaoImpl user2Dao;  


  15.     // set方法上的注解,帶有name屬性

  16.     @ZxfResource(name = "userDao")  

  17.     public void setUserDao(UserDaoImpl userDao) {  

  18.         this.userDao = userDao;  

  19.     }  


  20.     // set方法上的注解,沒有配置name屬性

  21.     @ZxfResource

  22.     public void setUser1Dao(User1DaoImpl user1Dao) {  

  23.         this.user1Dao = user1Dao;  

  24.     }  


  25.     public void show() {  

  26.         userDao.show();  

  27.         user1Dao.show1();  

  28.         user2Dao.show2();  

  29.         System.out.println("這里是Service方法........");  

  30.     }  

  31. }  

 3、要注入的DAO

Java代碼  spring中注解處理框架解析以及源代碼實現(xiàn)是怎樣的

  1. package com.yt.annotation;  


  2. /**

  3.  * @Description: 要注入的DAo類

  4.  * @ClassName: UserDaoImpl

  5.  * @Project: spring-aop

  6.  * @Author: zxf

  7.  * @Date: 2011-6-7

  8.  */

  9. public class UserDaoImpl {  


  10.     String name ;  


  11.     public void show(){  

  12.         System.out.println("這里是dao方法........");  

  13.     }  

  14. }  

Xml代碼  spring中注解處理框架解析以及源代碼實現(xiàn)是怎樣的

  1. <?xml version="1.0" encoding="UTF-8"?>

  2. <beans>

  3.     <bean id = "userDao" class="com.yt.annotation.UserDaoImpl" />

  4.     <bean id = "user1Dao" class="com.yt.annotation.User1DaoImpl" />

  5.     <bean id = "user2Dao" class="com.yt.annotation.User2DaoImpl" />

  6.     <bean id = "userService" class = "com.yt.annotation.UserServiceImpl" />

  7. </beans>

 4、注解處理器

Java代碼  spring中注解處理框架解析以及源代碼實現(xiàn)是怎樣的

  1. package com.yt.annotation;  


  2. import java.beans.Introspector;  

  3. import java.beans.PropertyDescriptor;  

  4. import java.lang.reflect.Field;  

  5. import java.lang.reflect.Method;  

  6. import java.util.ArrayList;  

  7. import java.util.HashMap;  

  8. import java.util.Iterator;  

  9. import java.util.List;  

  10. import java.util.Map;  

  11. import org.apache.log4j.Logger;  

  12. import org.dom4j.Document;  

  13. import org.dom4j.DocumentException;  

  14. import org.dom4j.Element;  

  15. import org.dom4j.io.SAXReader;  


  16. /**

  17.  * @Description: spring中的注解原理

  18.  * @ClassName: ClassPathXMLApplicationContext

  19.  * @Project: spring-aop

  20.  * @Author: zxf

  21.  * @Date: 2011-6-3

  22.  */

  23. public class ClassPathXMLApplicationContext {  


  24.     Logger log = Logger.getLogger(ClassPathXMLApplicationContext.class);  


  25.     List<BeanDefine> beanList = new ArrayList<BeanDefine>();  

  26.     Map<String, Object> sigletions = new HashMap<String, Object>();  


  27.     public ClassPathXMLApplicationContext(String fileName) {  

  28.         //讀取配置文件中管理的bean

  29.         this.readXML(fileName);  

  30.         //實例化bean

  31.         this.instancesBean();  

  32.         //注解處理器

  33.         this.annotationInject();  

  34.     }  


  35.     /**

  36.      * 讀取Bean配置文件

  37.      * @param fileName

  38.      * @return

  39.      */

  40.     @SuppressWarnings("unchecked")  

  41.     public void readXML(String fileName) {  

  42.         Document document = null;  

  43.         SAXReader saxReader = new SAXReader();  

  44.         try {  

  45.             ClassLoader classLoader =   

  46.                 Thread.currentThread().getContextClassLoader();  

  47.             document = saxReader.read(classLoader.getResourceAsStream(fileName));  

  48.             Element beans = document.getRootElement();  

  49.             for (Iterator<Element> beansList = beans.elementIterator();   

  50.                 beansList.hasNext();) {  

  51.                 Element element = beansList.next();  

  52.                 BeanDefine bean = new BeanDefine(  

  53.                         element.attributeValue("id"),  

  54.                         element.attributeValue("class"));  

  55.                 beanList.add(bean);  

  56.             }  

  57.         } catch (DocumentException e) {  

  58.             log.info("讀取配置文件出錯....");  

  59.         }  

  60.     }  


  61.     /**

  62.      * 實例化Bean

  63.      */

  64.     public void instancesBean() {  

  65.         for (BeanDefine bean : beanList) {  

  66.             try {  

  67.                 sigletions.put(bean.getId(),   

  68.                         Class.forName(bean.getClassName()).newInstance());  

  69.             } catch (Exception e) {  

  70.                 log.info("實例化Bean出錯...");  

  71.             }  

  72.         }  

  73.     }  


  74.     /**

  75.      * 注解處理器

  76.      * 如果注解ZxfResource配置了name屬性,則根據(jù)name所指定的名稱獲取要注入的實例引用,

  77.      * 如果注解ZxfResource;沒有配置name屬性,則根據(jù)屬性所屬類型來掃描配置文件獲取要

  78.      * 注入的實例引用

  79.      * 

  80.      */

  81.     public void annotationInject(){  

  82.         for(String beanName:sigletions.keySet()){  

  83.             Object bean = sigletions.get(beanName);  

  84.             if(bean!=null){  

  85.                 this.propertyAnnotation(bean);  

  86.                 this.fieldAnnotation(bean);  

  87.             }  

  88.         }  

  89.     }  


  90.     /**

  91.      * 處理在set方法加入的注解

  92.      * @param bean 處理的bean

  93.      */

  94.     public void propertyAnnotation(Object bean){  

  95.         try {  

  96.             //獲取其屬性的描述

  97.             PropertyDescriptor[] ps =   

  98.                 Introspector.getBeanInfo(bean.getClass()).getPropertyDescriptors();  

  99.             for(PropertyDescriptor proderdesc : ps){  

  100.                 //獲取所有set方法

  101.                 Method setter = proderdesc.getWriteMethod();  

  102.                 //判斷set方法是否定義了注解

  103.                 if(setter!=null && setter.isAnnotationPresent(ZxfResource.class)){  

  104.                     //獲取當前注解,并判斷name屬性是否為空

  105.                     ZxfResource resource = setter.getAnnotation(ZxfResource.class);  

  106.                     String name ="";  

  107.                     Object value = null;  

  108.                     if(resource.name()!=null&&!"".equals(resource.name())){  

  109.                         //獲取注解的name屬性的內(nèi)容

  110.                         name = resource.name();  

  111.                         value = sigletions.get(name);  

  112.                     }else//如果當前注解沒有指定name屬性,則根據(jù)類型進行匹配

  113.                         for(String key : sigletions.keySet()){  

  114.                             //判斷當前屬性所屬的類型是否在配置文件中存在

  115.                             if(proderdesc.getPropertyType().isAssignableFrom(sigletions.get(key).getClass())){  

  116.                                 //獲取類型匹配的實例對象

  117.                                 value = sigletions.get(key);  

  118.                                 break;  

  119.                             }  

  120.                         }  

  121.                     }  

  122.                     //允許訪問private方法

  123.                     setter.setAccessible(true);  

  124.                     //把引用對象注入屬性

  125.                     setter.invoke(bean, value);   

  126.                 }  

  127.             }  

  128.         } catch (Exception e) {  

  129.             log.info("set方法注解解析異常..........");  

  130.         }  

  131.     }  


  132.     /**

  133.      * 處理在字段上的注解

  134.      * @param bean 處理的bean

  135.      */

  136.     public void fieldAnnotation(Object bean){  

  137.         try {  

  138.             //獲取其全部的字段描述

  139.             Field[] fields = bean.getClass().getFields();  

  140.             for(Field f : fields){  

  141.                 if(f!=null && f.isAnnotationPresent(ZxfResource.class)){  

  142.                     ZxfResource resource = f.getAnnotation(ZxfResource.class);  

  143.                     String name ="";  

  144.                     Object value = null;  

  145.                     if(resource.name()!=null&&!"".equals(resource.name())){  

  146.                         name = resource.name();  

  147.                         value = sigletions.get(name);  

  148.                     }else{  

  149.                         for(String key : sigletions.keySet()){  

  150.                             //判斷當前屬性所屬的類型是否在配置文件中存在

  151.                             if(f.getType().isAssignableFrom(sigletions.get(key).getClass())){  

  152.                                 //獲取類型匹配的實例對象

  153.                                 value = sigletions.get(key);  

  154.                                 break;  

  155.                             }  

  156.                         }  

  157.                     }  

  158.                     //允許訪問private字段

  159.                     f.setAccessible(true);  

  160.                     //把引用對象注入屬性

  161.                     f.set(bean, value);  

  162.                 }  

  163.             }  

  164.         } catch (Exception e) {  

  165.             log.info("字段注解解析異常..........");  

  166.         }  

  167.     }  


  168.     /**

  169.      * 獲取Map中的對應的bean實例

  170.      * @param beanId

  171.      * @return

  172.      */

  173.     public Object getBean(String beanId) {  

  174.         return sigletions.get(beanId);  

  175.     }  



  176.     public static void main(String[] args) {  

  177.         ClassPathXMLApplicationContext path = new ClassPathXMLApplicationContext(  

  178.                 "configAnnotation.xml");  

  179.         UserServiceImpl userService =(UserServiceImpl)path.getBean("userService");  

  180.         userService.show();  

  181.     }  

  182. }  

上述就是小編為大家分享的spring中注解處理框架解析以及源代碼實現(xiàn)是怎樣的了,如果剛好有類似的疑惑,不妨參照上述分析進行理解。如果想知道更多相關知識,歡迎關注億速云行業(yè)資訊頻道。

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內(nèi)容。

AI