- 浏览: 415891 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (158)
- SpringBoot (10)
- vue.js (4)
- 2017基础知识 (2)
- jquery (4)
- extjs (8)
- spring (13)
- Java基础 (24)
- ibatis (2)
- oracle (18)
- 服务器配置 (8)
- maven (7)
- web应用开发 (14)
- 数据库 (9)
- 第三方依赖 (3)
- 百味人生 (7)
- svn (1)
- 问题一堆 (2)
- 测试驱动开发 (1)
- webServices (2)
- 网络编程 (2)
- 其它 (4)
- hibernate (2)
- ec标签序号列 (1)
- javascript (1)
- ActiveMQ (2)
- linux (5)
- UI (1)
- 问题汇集 (1)
- redis (1)
最新评论
-
jackson200:
讲解的狠不错!谢谢!
spring注入原理 -
阳光泛滥的日子:
讲的很透彻,受教了 。
spring中注解的实现原理 -
liudechao9:
最近在研究这方面,很不错,但是多线程并发的时候可能会出问题,而 ...
spring中注解的实现原理 -
小帅1127:
厉害啊 我的哥
spring中注解的实现原理 -
phoenixpaul:
...
Oracle存储过程和程序包
@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、定义注解
package com.yt.annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * @Description:定义注解 * @ClassName: ZxfResource * @Project: spring-aop * @Author: zxf * @Date: 2011-6-7 */ // 在运行时执行 @Retention(RetentionPolicy.RUNTIME) // 注解适用地方(字段和方法) @Target({ ElementType.FIELD, ElementType.METHOD }) public @interface ZxfResource { //注解的name属性 public String name() default ""; }
2、带有注解的服务类
package com.yt.annotation; /** * @Description: 带有注解的服务 * @ClassName: UserDaoImpl * @Project: spring-aop * @Author: zxf * @Date: 2011-6-7 */ public class UserServiceImpl { public UserDaoImpl userDao; public User1DaoImpl user1Dao; // 字段上的注解,可以配置name属性 @ZxfResource public User2DaoImpl user2Dao; // set方法上的注解,带有name属性 @ZxfResource(name = "userDao") public void setUserDao(UserDaoImpl userDao) { this.userDao = userDao; } // set方法上的注解,没有配置name属性 @ZxfResource public void setUser1Dao(User1DaoImpl user1Dao) { this.user1Dao = user1Dao; } public void show() { userDao.show(); user1Dao.show1(); user2Dao.show2(); System.out.println("这里是Service方法........"); } }
3、要注入的DAO
package com.yt.annotation; /** * @Description: 要注入的DAo类 * @ClassName: UserDaoImpl * @Project: spring-aop * @Author: zxf * @Date: 2011-6-7 */ public class UserDaoImpl { String name ; public void show(){ System.out.println("这里是dao方法........"); } }
<?xml version="1.0" encoding="UTF-8"?> <beans> <bean id = "userDao" class="com.yt.annotation.UserDaoImpl" /> <bean id = "user1Dao" class="com.yt.annotation.User1DaoImpl" /> <bean id = "user2Dao" class="com.yt.annotation.User2DaoImpl" /> <bean id = "userService" class = "com.yt.annotation.UserServiceImpl" /> </beans>
4、注解处理器
package com.yt.annotation; import java.beans.Introspector; import java.beans.PropertyDescriptor; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import org.apache.log4j.Logger; import org.dom4j.Document; import org.dom4j.DocumentException; import org.dom4j.Element; import org.dom4j.io.SAXReader; /** * @Description: spring中的注解原理 * @ClassName: ClassPathXMLApplicationContext * @Project: spring-aop * @Author: zxf * @Date: 2011-6-3 */ public class ClassPathXMLApplicationContext { Logger log = Logger.getLogger(ClassPathXMLApplicationContext.class); List<BeanDefine> beanList = new ArrayList<BeanDefine>(); Map<String, Object> sigletions = new HashMap<String, Object>(); public ClassPathXMLApplicationContext(String fileName) { //读取配置文件中管理的bean this.readXML(fileName); //实例化bean this.instancesBean(); //注解处理器 this.annotationInject(); } /** * 读取Bean配置文件 * @param fileName * @return */ @SuppressWarnings("unchecked") public void readXML(String fileName) { Document document = null; SAXReader saxReader = new SAXReader(); try { ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); document = saxReader.read(classLoader.getResourceAsStream(fileName)); Element beans = document.getRootElement(); for (Iterator<Element> beansList = beans.elementIterator(); beansList.hasNext();) { Element element = beansList.next(); BeanDefine bean = new BeanDefine( element.attributeValue("id"), element.attributeValue("class")); beanList.add(bean); } } catch (DocumentException e) { log.info("读取配置文件出错...."); } } /** * 实例化Bean */ public void instancesBean() { for (BeanDefine bean : beanList) { try { sigletions.put(bean.getId(), Class.forName(bean.getClassName()).newInstance()); } catch (Exception e) { log.info("实例化Bean出错..."); } } } /** * 注解处理器 * 如果注解ZxfResource配置了name属性,则根据name所指定的名称获取要注入的实例引用, * 如果注解ZxfResource;没有配置name属性,则根据属性所属类型来扫描配置文件获取要 * 注入的实例引用 * */ public void annotationInject(){ for(String beanName:sigletions.keySet()){ Object bean = sigletions.get(beanName); if(bean!=null){ this.propertyAnnotation(bean); this.fieldAnnotation(bean); } } } /** * 处理在set方法加入的注解 * @param bean 处理的bean */ public void propertyAnnotation(Object bean){ try { //获取其属性的描述 PropertyDescriptor[] ps = Introspector.getBeanInfo(bean.getClass()).getPropertyDescriptors(); for(PropertyDescriptor proderdesc : ps){ //获取所有set方法 Method setter = proderdesc.getWriteMethod(); //判断set方法是否定义了注解 if(setter!=null && setter.isAnnotationPresent(ZxfResource.class)){ //获取当前注解,并判断name属性是否为空 ZxfResource resource = setter.getAnnotation(ZxfResource.class); String name =""; Object value = null; if(resource.name()!=null&&!"".equals(resource.name())){ //获取注解的name属性的内容 name = resource.name(); value = sigletions.get(name); }else{ //如果当前注解没有指定name属性,则根据类型进行匹配 for(String key : sigletions.keySet()){ //判断当前属性所属的类型是否在配置文件中存在 if(proderdesc.getPropertyType().isAssignableFrom(sigletions.get(key).getClass())){ //获取类型匹配的实例对象 value = sigletions.get(key); break; } } } //允许访问private方法 setter.setAccessible(true); //把引用对象注入属性 setter.invoke(bean, value); } } } catch (Exception e) { log.info("set方法注解解析异常.........."); } } /** * 处理在字段上的注解 * @param bean 处理的bean */ public void fieldAnnotation(Object bean){ try { //获取其全部的字段描述 Field[] fields = bean.getClass().getFields(); for(Field f : fields){ if(f!=null && f.isAnnotationPresent(ZxfResource.class)){ ZxfResource resource = f.getAnnotation(ZxfResource.class); String name =""; Object value = null; if(resource.name()!=null&&!"".equals(resource.name())){ name = resource.name(); value = sigletions.get(name); }else{ for(String key : sigletions.keySet()){ //判断当前属性所属的类型是否在配置文件中存在 if(f.getType().isAssignableFrom(sigletions.get(key).getClass())){ //获取类型匹配的实例对象 value = sigletions.get(key); break; } } } //允许访问private字段 f.setAccessible(true); //把引用对象注入属性 f.set(bean, value); } } } catch (Exception e) { log.info("字段注解解析异常.........."); } } /** * 获取Map中的对应的bean实例 * @param beanId * @return */ public Object getBean(String beanId) { return sigletions.get(beanId); } public static void main(String[] args) { ClassPathXMLApplicationContext path = new ClassPathXMLApplicationContext( "configAnnotation.xml"); UserServiceImpl userService =(UserServiceImpl)path.getBean("userService"); userService.show(); } }
- annotation.rar (4.2 KB)
- 下载次数: 321
评论
7 楼
阳光泛滥的日子
2017-02-23
讲的很透彻,受教了 。
6 楼
liudechao9
2017-01-11
最近在研究这方面,很不错,但是多线程并发的时候可能会出问题,而且每new 一次ClassPathXMLApplicationContext 都会重新加载,建议加入到配置文件加载完成后执行,其他的还行,挺不错!
5 楼
小帅1127
2016-11-16
厉害啊 我的哥
4 楼
liyc98
2015-08-24
想请教下,像spring那种,没有set方法是如何注入的
3 楼
fairyhawk
2014-07-19
学习了不错。
在变量注释时fieldAnnotation()方法中注释没写name时是不默认用变量的名字??
不知道代码中写的这个for循环isAssignableFrom方法比较好用吗。我测试好像不可以。
在变量注释时fieldAnnotation()方法中注释没写name时是不默认用变量的名字??
if (resource.name() != null && !"".equals(resource.name())) { name = resource.name(); value = sigletions.get(name); } else { name=f.getName();//使用变量的默认名字 value = sigletions.get(name); }
不知道代码中写的这个for循环isAssignableFrom方法比较好用吗。我测试好像不可以。
for (String key : sigletions.keySet()) { // 判断当前属性所属的类型是否在配置文件中存在 if (f.getType().isAssignableFrom(sigletions.get(key).getClass())) { // 获取类型匹配的实例对象 value = sigletions.get(key); break; } }
2 楼
seraphim0930
2014-05-23
T[img][/img]his is the most beautiful article from now on !
1 楼
wujianjun12315
2011-07-21
不错。。。。 学习了。。。
发表评论
-
SpringMVC @ResponseBody和@RequestBody使用
2018-02-08 09:54 901@ResponseBody用法 作用: 该注解用 ... -
http请求中的header和body应用
2016-11-12 16:42 12745/** * 获取httpBody中的请求数据处理后并 ... -
spring管理bean原理
2011-06-03 15:24 20181、读取config.xml文件的bean标签放入数组,读取内 ... -
Spring AOP基础
2011-05-24 09:44 4812一、AOP是Aspect Oriented Programin ... -
spring注入原理
2011-05-19 14:05 20294IOC(Inverse of Control)可翻 ... -
spring+ibatis
2011-05-06 17:10 1375applicationContext.xml <!-- ... -
springMVC上传文件
2011-01-18 10:52 1618(1)、加入jar包: jxl-2.6.jar com ... -
spring 的工作机制和配置文件
2010-12-06 11:17 1114spring工作机制及为什么 ... -
spring中的事务管理
2010-11-04 14:35 11761、spring中声明式事务有两种配置方法:注解配置和xml形 ... -
Spring Web 相关工具类
2010-11-03 17:16 1073Web 相关工具类 您几乎总是使用 Spring ... -
spring 中的jdbc
2010-11-02 09:17 1742package org.spring.service; ... -
extjs3+springMVC上传文件
2010-04-02 09:46 67881.Ext代码 //formPanel表单的属性加入 fi ...
相关推荐
本文将深入探讨Spring注解的基本原理,包括它们如何被解析、处理以及如何影响应用程序的生命周期。 首先,我们需要了解注解在Java语言中的本质。注解是一种元数据,允许程序员在源代码中嵌入信息,这些信息可以被...
**Spring Ioc 实现原理详解** Spring Ioc(Inversion of Control,控制反转)是Spring框架的核心特性之一,它改变了传统应用程序中对象的创建和管理方式。在传统的软件设计中,对象的创建和依赖关系的维护通常由...
Java注解机制之Spring自动装配...Java注解机制之Spring自动装配实现原理详解是指Spring框架中使用Java注解机制来实现自动装配功能的机制,该机制可以根据注解信息来自动将Bean对象关联起来,从而实现了自动装配功能。
本文将深入探讨Spring中的自动检测注解及其工作原理。 首先,`@Autowired`是Spring框架提供的一种依赖注入(DI,Dependency Injection)方式,用于自动装配bean的依赖。当我们在类的属性或方法上使用这个注解时,...
这个"手写Spring IOC注解实现版本"项目旨在帮助我们深入理解Spring框架的工作原理,通过实际动手实现来增强对IoC容器和注解驱动编程的理解。 在Spring中,IOC意味着应用程序不再直接创建对象,而是将对象的创建和...
4、想看spring aop 注解实现记录系统日志并入库等 二、能学到什么 1、收获可用源码 2、能够清楚的知道如何用spring aop实现自定义注解以及注解的逻辑实现 (需要知道原理的请看spring aop源码,此处不做赘述) 3、...
总结来说,"spring使用注解依赖jar"涵盖了Spring框架通过注解实现依赖注入的原理和实践,以及如何在项目中管理和引入Spring的相关jar包。理解并熟练掌握这些知识点,将有助于提升你的Java和Spring开发能力。
本文将深入探讨Spring AOP的实现原理,以及如何使用反射来实现动态代理模式。 首先,我们需要了解AOP的基本概念。AOP的核心思想是切面,它包含两个主要部分:切点(Pointcut)和通知(Advice)。切点定义了在程序...
Spring的组合注解和元注解原理与用法详解 Spring 框架中的组合注解和元注解是两个重要的概念,它们在 Spring 框架中发挥着至关重要的作用。下面我们将详细介绍 Spring 的组合注解和元注解的原理与用法。 一、组合...
本篇文章将深入探讨Spring依赖注入的实现原理,以及如何通过源码理解和使用这一特性。 一、依赖注入简介 依赖注入的基本思想是,对象不应该负责创建或查找它所依赖的对象,而应该由外部容器(如Spring框架)来负责...
虽然现在的最佳实践倾向于使用注解和Spring Boot,但理解非注解方式有助于深入学习这些框架的工作原理,对提升开发技能有长远的帮助。在实践中,你可能会遇到如何处理异常、如何进行事务管理、如何优化查询性能等...
在Spring中,容器使用Java的反射机制来实现DI。反射允许程序在运行时检查类、接口、字段和方法的信息,并能动态地创建和操作对象。例如,Spring通过反射读取类的定义,查找标注了@Autowired的字段或方法,然后自动...
本文将深入探讨Spring框架中的一些常用注解,并通过实例来解析它们的工作原理。 1. `@Component`: 这是Spring中的基础组件注解,它标记一个类为Spring容器管理的bean。当你在类上使用`@Component`时,Spring会自动...
"Spring AOP + 注解实现统一注解功能" 本文我们通过Spring AOP和Java的自定义注解来实现日志的插入功能,该方案对原有业务入侵较低,实现较灵活。下面我们将详细介绍该功能的实现原理和相关知识点。 1. 概述 在...
### Spring注解知识点详解 #### 1. Spring注解基础 在Spring框架中,注解是一种轻量级的依赖注入方式,能够简化配置并提高开发效率。在本节中,我们主要介绍几个Spring中常用的注解,它们分别是@Component、@...
在Spring框架中,自定义标签和注解解析是两个关键的特性,它们使得代码与配置的集成更加紧密,简化了应用程序的开发。本篇文章将深入探讨Spring如何处理这两种类型的元数据。 首先,让我们来理解Spring如何解析...
本文将深入探讨Spring中的基于注解的事务管理及其工作原理。 ### 1. Spring事务管理概述 Spring事务管理分为编程式和声明式两种。编程式事务管理通过编程的方式(如使用`TransactionTemplate`或直接调用`...
Spring注解是Spring框架中的一大特色,它极大地简化了配置过程,让代码更加简洁易读。注解如`@Component`、`@Service`、`@Repository`和`@Controller`用于标记不同层次的Bean,而`@Autowired`则负责自动装配Bean之间...