千家信息网

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

发表于:2025-02-13 作者:千家信息网编辑
千家信息网最后更新 2025年02月13日,这期内容当中小编将会给大家带来有关spring中注解处理框架解析以及源代码实现是怎样的,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。@Autowired和@Reso
千家信息网最后更新 2025年02月13日spring中注解处理框架解析以及源代码实现是怎样的

这期内容当中小编将会给大家带来有关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代码

  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代码

  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代码

  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代码

  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 beanList = new ArrayList();

  26. Map sigletions = new HashMap();


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

0