先啰嗦两句:
第一次在博客园使用markdown编辑,感觉渲染样式差强人意,还是github的样式比较顺眼。

概述

Spring2.5 引入了注解。
于是,一个问题产生了:使用注解方式注入 JavaBean 是不是一定完爆 xml方式?
未必。正所谓,仁者见仁智者见智。任何事物都有其优缺点,看你如何取舍。来看看注解的优缺点:
优点:大大减少了配置,并且可以使配置更加精细——类,方法,字段都可以用注解去标记。
缺点:使用注解,不可避免产生了侵入式编程,也产生了一些问题。

  • 你需要将注解加入你的源码并编译它;
  • 注解往往比较分散,不易管控。

    注:spring 中,先进行注解注入,然后才是xml注入,因此如果注入的目标相同,后者会覆盖前者。

启动注解

Spring 默认是不启用注解的。如果想使用注解,需要先在xml中启动注解。
启动方式:在xml中加入一个标签,很简单吧。

<context:annotation-config/>

注:<context:annotation-config/> 只会检索定义它的上下文。什么意思呢?就是说,如果你
为DispatcherServlet指定了一个WebApplicationContext,那么它只在controller中查找@Autowired注解,而不会检查其它的路径。

Spring注解

@Required

@Required 注解只能用于修饰bean属性的setter方法。受影响的bean属性必须在配置时被填充在xml配置文件中,否则容器将抛出BeanInitializationException

public class AnnotationRequired {private String name;private String sex;public String getName() {return name;}/*** @Required 注解用于bean属性的setter方法并且它指示,受影响的bean属性必须在配置时被填充在xml配置文件中,*           否则容器将抛出BeanInitializationException。*/@Requiredpublic void setName(String name) {this.name = name;}public String getSex() {return sex;}public void setSex(String sex) {this.sex = sex;}
}

@Autowired

@Autowired注解可用于修饰属性、setter方法、构造方法。

注:@Autowired注解也可用于修饰构造方法,但如果类中只有默认构造方法,则没有必要。如果有多个构造器,至少应该修饰一个,来告诉容器哪一个必须使用。

可以使用JSR330的注解@Inject来替代@Autowired

范例

public class AnnotationAutowired {private static final Logger log = LoggerFactory.getLogger(AnnotationRequired.class);@Autowiredprivate Apple fieldA;private Banana fieldB;private Orange fieldC;public Apple getFieldA() {return fieldA;}public void setFieldA(Apple fieldA) {this.fieldA = fieldA;}public Banana getFieldB() {return fieldB;}@Autowiredpublic void setFieldB(Banana fieldB) {this.fieldB = fieldB;}public Orange getFieldC() {return fieldC;}public void setFieldC(Orange fieldC) {this.fieldC = fieldC;}public AnnotationAutowired() {}@Autowiredpublic AnnotationAutowired(Orange fieldC) {this.fieldC = fieldC;}public static void main(String[] args) throws Exception {AbstractApplicationContext ctx =new ClassPathXmlApplicationContext("spring/spring-annotation.xml");AnnotationAutowired annotationAutowired =(AnnotationAutowired) ctx.getBean("annotationAutowired");log.debug("fieldA: {}, fieldB:{}, fieldC:{}", annotationAutowired.getFieldA().getName(),annotationAutowired.getFieldB().getName(),annotationAutowired.getFieldC().getName());ctx.close();}
}

xml中的配置

<!-- 测试@Autowired -->
<bean id="apple" class="org.zp.notes.spring.beans.annotation.sample.Apple"/>
<bean id="potato" class="org.zp.notes.spring.beans.annotation.sample.Banana"/>
<bean id="tomato" class="org.zp.notes.spring.beans.annotation.sample.Orange"/>
<bean id="annotationAutowired" class="org.zp.notes.spring.beans.annotation.sample.AnnotationAutowired"/>

@Qualifier

@Autowired注解中,提到了如果发现有多个候选的bean都符合修饰类型,Spring就会抓瞎了。

那么,如何解决这个问题。

可以通过@Qualifier指定bean名称来锁定真正需要的那个bean。

范例

public class AnnotationQualifier {private static final Logger log = LoggerFactory.getLogger(AnnotationQualifier.class);@Autowired@Qualifier("dog") /** 去除这行,会报异常 */Animal dog;Animal cat;public Animal getDog() {return dog;}public void setDog(Animal dog) {this.dog = dog;}public Animal getCat() {return cat;}@Autowiredpublic void setCat(@Qualifier("cat") Animal cat) {this.cat = cat;}public static void main(String[] args) throws Exception {AbstractApplicationContext ctx =new ClassPathXmlApplicationContext("spring/spring-annotation.xml");AnnotationQualifier annotationQualifier =(AnnotationQualifier) ctx.getBean("annotationQualifier");log.debug("Dog name: {}", annotationQualifier.getDog().getName());log.debug("Cat name: {}", annotationQualifier.getCat().getName());ctx.close();}
}abstract class Animal {public String getName() {return null;}
}class Dog extends Animal {public String getName() {return "狗";}
}class Cat extends Animal {public String getName() {return "猫";}
}

xml中的配置

<!-- 测试@Qualifier -->
<bean id="dog" class="org.zp.notes.spring.beans.annotation.sample.Dog"/>
<bean id="cat" class="org.zp.notes.spring.beans.annotation.sample.Cat"/>
<bean id="annotationQualifier" class="org.zp.notes.spring.beans.annotation.sample.AnnotationQualifier"/>

JSR 250注解

@Resource

Spring支持 JSP250规定的注解@Resource。这个注解根据指定的名称来注入bean。

如果没有为@Resource指定名称,它会像@Autowired一样按照类型去寻找匹配。

在Spring中,由CommonAnnotationBeanPostProcessor来处理@Resource注解。

范例

public class AnnotationResource {private static final Logger log = LoggerFactory.getLogger(AnnotationResource.class);@Resource(name = "flower")Plant flower;@Resource(name = "tree")Plant tree;public Plant getFlower() {return flower;}public void setFlower(Plant flower) {this.flower = flower;}public Plant getTree() {return tree;}public void setTree(Plant tree) {this.tree = tree;}public static void main(String[] args) throws Exception {AbstractApplicationContext ctx =new ClassPathXmlApplicationContext("spring/spring-annotation.xml");AnnotationResource annotationResource =(AnnotationResource) ctx.getBean("annotationResource");log.debug("type: {}, name: {}", annotationResource.getFlower().getClass(), annotationResource.getFlower().getName());log.debug("type: {}, name: {}", annotationResource.getTree().getClass(), annotationResource.getTree().getName());ctx.close();}
}

xml的配置

<!-- 测试@Resource -->
<bean id="flower" class="org.zp.notes.spring.beans.annotation.sample.Flower"/>
<bean id="tree" class="org.zp.notes.spring.beans.annotation.sample.Tree"/>
<bean id="annotationResource" class="org.zp.notes.spring.beans.annotation.sample.AnnotationResource"/>

@PostConstruct和@PreDestroy

@PostConstruct@PreDestroy是JSR 250规定的用于生命周期的注解。

从其名号就可以看出,一个是在构造之后调用的方法,一个是销毁之前调用的方法。

public class AnnotationPostConstructAndPreDestroy {private static final Logger log = LoggerFactory.getLogger(AnnotationPostConstructAndPreDestroy.class);@PostConstructpublic void init() {log.debug("call @PostConstruct method");}@PreDestroypublic void destroy() {log.debug("call @PreDestroy method");}
}

JSR 330注解

从Spring3.0开始,Spring支持JSR 330标准注解(依赖注入)。

注:如果要使用JSR 330注解,需要使用外部jar包。

若你使用maven管理jar包,只需要添加依赖到pom.xml即可:

<dependency><groupId>javax.inject</groupId><artifactId>javax.inject</artifactId><version>1</version>
</dependency>

@Inject

@Inject@Autowired一样,可以修饰属性、setter方法、构造方法。

范例

public class AnnotationInject {private static final Logger log = LoggerFactory.getLogger(AnnotationInject.class);@InjectApple fieldA;Banana fieldB;Orange fieldC;public Apple getFieldA() {return fieldA;}public void setFieldA(Apple fieldA) {this.fieldA = fieldA;}public Banana getFieldB() {return fieldB;}@Injectpublic void setFieldB(Banana fieldB) {this.fieldB = fieldB;}public Orange getFieldC() {return fieldC;}public AnnotationInject() {}@Injectpublic AnnotationInject(Orange fieldC) {this.fieldC = fieldC;}public static void main(String[] args) throws Exception {AbstractApplicationContext ctx =new ClassPathXmlApplicationContext("spring/spring-annotation.xml");AnnotationInject annotationInject = (AnnotationInject) ctx.getBean("annotationInject");log.debug("type: {}, name: {}", annotationInject.getFieldA().getClass(),annotationInject.getFieldA().getName());log.debug("type: {}, name: {}", annotationInject.getFieldB().getClass(),annotationInject.getFieldB().getName());log.debug("type: {}, name: {}", annotationInject.getFieldC().getClass(),annotationInject.getFieldC().getName());ctx.close();}
}

[Spring]IoC容器之进击的注解相关推荐

  1. 【小家Spring】Spring注解驱动开发---向Spring Ioc容器中注册Bean的7种方式

    每篇一句 比你有钱的人一定会比你努力,而比你努力的人终有一天会比你有钱 前言 Spring是一个非常强大的反转控制(IOC)框架,以帮助分离项目组件之间的依赖关系.因此可以说Spring容器对Bean ...

  2. 头条一面:Spring IOC容器中只存放单例Bean吗?

    最近,很多小伙伴出去面试,感觉自己面的不是很理想,回来后,不少小伙伴把面试题做了记录发给我,让我给大家解析下,然后发出来.当我看到这些面试题时,快速在脑海中构建起了整个知识体系,从基础到框架.从分布式 ...

  3. Spring点滴一:Spring Ioc 容器

    Spring 容器: Spring 容器是Spring框架的核心.Spring容器将创建Bean对象实例,把它们联系在一起,配置它们,并管理它们整个生命周期从创建到销毁.Spring 容器通过依赖注入 ...

  4. Spring IOC 容器源码分析 - 填充属性到 bean 原始对象

    1. 简介 本篇文章,我们来一起了解一下 Spring 是如何将配置文件中的属性值填充到 bean 对象中的.我在前面几篇文章中介绍过 Spring 创建 bean 的流程,即 Spring 先通过反 ...

  5. Spring IOC 容器源码分析 - 创建原始 bean 对象

    1. 简介 本篇文章是上一篇文章(创建单例 bean 的过程)的延续.在上一篇文章中,我们从战略层面上领略了doCreateBean方法的全过程.本篇文章,我们就从战术的层面上,详细分析doCreat ...

  6. Spring IOC 容器源码分析 - 创建单例 bean 的过程

    1. 简介 在上一篇文章中,我比较详细的分析了获取 bean 的方法,也就是getBean(String)的实现逻辑.对于已实例化好的单例 bean,getBean(String) 方法并不会再一次去 ...

  7. Spring IOC 容器源码分析 - 获取单例 bean

    1. 简介 为了写 Spring IOC 容器源码分析系列的文章,我特地写了一篇 Spring IOC 容器的导读文章.在导读一文中,我介绍了 Spring 的一些特性以及阅读 Spring 源码的一 ...

  8. spring注入普通java类_普通java类如何取得注入spring Ioc容器的对象

    [除了使用XML配置外,还可以选择使用基于注解(annotation)的配置方式,其依赖于字节码来织入组件.注解注入在XML注入之前完成,因此在XML配置中可以重载注解注入的属性. 一.建一个Spri ...

  9. Spring —— IoC 容器详解

    引言 本篇博客总结自官网的<The IoC Container>,其中会结合王富强老师的<Spring揭秘>融入自己的语言和理解,争取通过这一篇文章彻底扫除spring IOC ...

最新文章

  1. react学习笔记(二)编写第一个react组件
  2. aop对请求后端的参数修改_Spring Boot AOP之对请求的参数入参与返回结果进行拦截处理...
  3. Andlinux 使用记录(转)
  4. PHP面试题:合并两个数组有几种方式,试比较它们的异同
  5. 《Effective Java》读书笔记 Item 1:考虑静态工厂方法,而不是构造器
  6. 才博教育:AI口语学习平台上云
  7. kotlin教程(1)
  8. fiddler抓包工具-- 本地资源替换线上文件
  9. reactrouter4路由钩子_react router @4 和 vue路由 详解(八)vue路由守卫
  10. opencv 轮廓检测
  11. 新年计算机等级的决定的英语,新年决定英语对话及译文
  12. [转载] python元组特点_python元组的优势有哪些
  13. 数据结构上机实践第四周项目6- 循环双链表应用
  14. python中访问lmdb
  15. android view 画文字,【Android自定义View】绘图之文字篇(三)
  16. php vld扩展,Linux安装php-vld扩展
  17. 轴承选型选不好,可别再说轴承质量差劲啦!
  18. 聊聊H5浏览器实现扫一扫
  19. 智遥工作流软件,转下一步时数据保存解析
  20. 常见计算机蓝屏代码,码住!常见电脑蓝屏代码和解决方法

热门文章

  1. linux设置双屏拼接_双屏办公,用起来到底有多爽
  2. c++读取.dat文件_MySQL 数据文件类型
  3. linux常用网络诊断命令,linux网络常用诊断工具
  4. springboot设置运行内存_docker run容器 设置 jvm 运行springboot 程序
  5. 项目代码从GitHub上克隆到本地
  6. 【直播】回放与PPT下载!深度学习如何用于摄影图像的处理?
  7. 【AI产品】一键去除杂物,Photo Eraser助你拍出美丽照片
  8. 【AI白身境】学深度学习你不得不知的爬虫基础​​​​​​​
  9. 产销对接行动倡议书-万祥军:长效机制谋定丰收节交易会
  10. 【NOIP2002】【codevs1098】均分纸牌