温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

spring中注解处理框架解析以及源代码实现是怎样的

发布时间:2021-10-14 14:40:29 来源:亿速云 阅读:146 作者:柒染 栏目:编程语言

这期内容当中小编将会给大家带来有关spring中注解处理框架解析以及源代码实现是怎样的,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。

@Autowired和@Resource的区别:

在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注解原理:

实现了在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. // 在运行时执行

  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中注解处理框架解析以及源代码实现是怎样的

  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中注解处理框架解析以及源代码实现是怎样的

  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中注解处理框架解析以及源代码实现是怎样的

  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中注解处理框架解析以及源代码实现是怎样的

  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属性,则根据name所指定的名称获取要注入的实例引用,

  77.      * 如果注解ZxfResource;没有配置name属性,则根据属性所属类型来扫描配置文件获取要

  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属性的内容

  110.                         name = resource.name();  

  111.                         value = sigletions.get(name);  

  112.                     }else//如果当前注解没有指定name属性,则根据类型进行匹配

  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中注解处理框架解析以及源代码实现是怎样的了,如果刚好有类似的疑惑,不妨参照上述分析进行理解。如果想知道更多相关知识,欢迎关注亿速云行业资讯频道。

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI