新闻详情

新闻详情

首页 / 资讯中心 / 详情

【Spring基础系列】基于注解装配Bean

发布时间:2026/9/28 4:15:34来源:尧图网络
【Spring基础系列】基于注解装配Bean
本文主要讲解Spring通过注解装配Bean的常用方式包括Component、Repository、Service、Controller、Autowired、Resource和Qualifier。前言目前学习java也有一段时间比较不适应的就是java的各种注解因为它里面包含了太多的东西然后使用的姿势也各不相同今天就简单做个总结和记录扫一次盲后后续使用就畅通无阻。什么是注解传统的Spring做法是使用.xml文件来对bean进行注入或者是配置aop、事物这么做有两个缺点如果所有的内容都配置在.xml文件中那么.xml文件将会十分庞大如果按需求分开.xml文件那么.xml文件又会非常多总之这将导致配置文件的可读性与可维护性变得很低。在开发中在.java文件和.xml文件之间不断切换是一件麻烦的事同时这种思维上的不连贯也会降低开发的效率。为了解决这两个问题Spring引入了注解通过XXX的方式让注解与Java Bean紧密结合大大减少了配置文件的体积又增加了Java Bean的可读性与内聚性。常用注解下面直接copy语言中文网的解释Component可以使用此注解描述 Spring 中的 Bean但它是一个泛化的概念仅仅表示一个组件Bean并且可以作用在任何层次。使用时只需将该注解标注在相应类上即可。Repository用于将数据访问层DAO层的类标识为 Spring 中的 Bean其功能与 Component 相同。Service通常作用在业务层Service层用于将业务层的类标识为 Spring 中的 Bean其功能与 Component 相同。Controller通常作用在控制层如 Struts2 的 Action用于将控制层的类标识为 Spring 中的 Bean其功能与 Component 相同。Autowired用于对 Bean 的属性变量、属性的 Set 方法及构造函数进行标注配合对应的注解处理器完成 Bean 的自动配置工作。默认按照 Bean 的类型进行装配。Resource其作用与 Autowired 一样。其区别在于 Autowired 默认按照 Bean 类型装配而 Resource 默认按照 Bean 实例名称进行装配。Qualifier与 Autowired 注解配合使用会将默认的按 Bean 类型装配修改为按 Bean 的实例名称装配Bean 的实例名称由 Qualifier 注解的参数指定。不用注解先看一个不使用注解的Spring示例在这个示例的基础上改成注解版本的这样也能看出使用与不使用注解之间的区别先定义猫和狗ToString public class Cat { private String catName 罗小黑; }ToString public class Dog { private String dogName 旺财; }再定义宠物Data public class Pets { private Cat cat; private Dog dog; public static void main(String args[]) { ApplicationContext context new ClassPathXmlApplicationContext(applicationContext.xml); Pets petscontext.getBean(pets,Pets.class); System.out.println(pets.toString()); } } // 输出 // Pets(catCat(catName罗小黑), dogDog(dogName旺财))注意这里我使用了Data注解主要是使用里面的getxxx()和setxxx()方法因为这个Spring框架在进行注解注入时需要。由于没有使用注解我们需要在xml文件进行如下配置bean idpets classcom.java.annotation.spring.bean.test1.Pets property namecat refcat / property namedog refdog / /bean bean idcat classcom.java.annotation.spring.bean.test1.Cat / bean iddog classcom.java.annotation.spring.bean.test1.Dog /成员变量使用注解这里我们使用Autowired注解当然也可以使用Resource后面再讲他们的区别引入注解可以简化xml配置文件如下bean idpets classcom.java.annotation.spring.bean.tes1.Pets / bean idcat classcom.java.annotation.spring.bean.test1.Cat / bean iddog classcom.java.annotation.spring.bean.test1.Dog /这里我们只对Cat和Dog加上Autowired注解就可以根据变量的类型自动找到相应的类然后进行加载Data public class Pets { Autowired private Cat cat; Autowired private Dog dog; public static void main(String args[]) { // main()省略同上 // 输出Pets(catCat(catName罗小黑), dogDog(dogName旺财)) } }类使用注解我们可以给Dog和Cat类加上Service注解就可以将xml配置简化如下bean idpets classcom.java.annotation.spring.bean.tes1.Pets /下面是给类加Service注解的正确姿势当然你也可以使用Component、Repository、Service、Controller区别不大只是使用不太规范。Data Service public class Cat { private String catName 罗小黑; }Data Service public class Dog { private String dogName 旺财; }然后Pets和上面示例保持不变当然你可以把Pets在xml的配置给去掉只需要在Pets使用Service注解原理同Cat和Dog类似于Data Service public class Pets { // 内部代码省略 }这里有个巨大的坑坑了我一个多小时就是需要在配置文件中配置注解扫描的代码路径否则程序运行时会提示找不到该类的注解。比如我的项目目录是放在com.java.annotation下面所以你需要将该路径配置进去!--使用context命名空间通知spring扫描指定目录进行注解的解析-- context:component-scan base-packagecom.java.annotation/接口注入上面的示例比较简单我们来个稍微复杂一点的我们可以给Dog和Cat抽象一个接口Animal(接口不是我这样使用的我只是给个示例)如下public interface Animal { public String food null; }下面是Cat和DogData Service public class Cat implements Animal { private String catName 罗小黑; }Data Service public class Dog implements Animal { private String dogName 旺财; }这个有个重点需要关注的地方就是通过Service进行注入主要做了2件事情声明Pets.java是一个bean这点很重要因为Pets.java是一个bean其他的类才可以使用Autowired将Pets作为一个成员变量自动注入;Pets.java在bean中的id是pets即类名且首字母小写。用接口名定义变量这里使用姿势其实很多我们的成员变量定义可以使用接口Animal但是变量名必须为dog和cat因为Spring对Dog和Cat的注入名为dog和catData public class Pets { Autowired private Animal dog; Autowired private Animal cat; // main()省略同上 // 输出Pets(catCat(catName罗小黑), dogDog(dogName旺财)) }可能有同学会说“我才不信”这个是我到真实环境跑过如果我将变量名dog改为dog1如下Data public class Pets { Autowired private Animal dog1; // 错误使用会报错 Autowired private Animal cat; }会输入如下错误也就是提示找不到dog1对应注入的类Exception in thread main org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name pets: Unsatisfied dependency expressed through field dog1; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type com.java.annotation.spring.bean.test4.Animal available: expected single matching bean but found 2: cat,dog at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:588) at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88) at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:366) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1264) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:553) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483) at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:761) at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:867) at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:543) at org.springframework.context.support.ClassPathXmlApplicationContext.init(ClassPathXmlApplicationContext.java:139) at org.springframework.context.support.ClassPathXmlApplicationContext.init(ClassPathXmlApplicationContext.java:83) at com.java.annotation.spring.bean.test4.Pets.main(Pets.java:17) Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type com.java.annotation.spring.bean.test4.Animal available: expected single matching bean but found 2: cat,dog at org.springframework.beans.factory.config.DependencyDescriptor.resolveNotUnique(DependencyDescriptor.java:173) at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1116) at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1066) at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:585)不过上述方式不建议使用一方面不容易理解另一方面容易给别人留坑如果一定需要用接口定义变量可以使用Qualifier注解。引入Qualifier注解Qualifier与Autowired注解配合使用会将默认的按Bean类型装配修改为按Bean的实例名称装配Bean的实例名称由Qualifier注解的参数指定。Data public class Pets { Autowired Qualifier(dog) private Animal dog1; Autowired private Animal cat; // main()省略同上 // 输出Pets(catCat(catName罗小黑), dogDog(dogName旺财)) }对于这种方式我感觉用起来也别扭最好的方式可以直接用类名定义变量。用类名定义变量Data public class Pets { Autowired private Dog dog1; Autowired private Cat cat1; // main()省略同上 // 输出Pets(catCat(catName罗小黑), dogDog(dogName旺财)) }这个就很直观了我用Dog指定dog1用Cat指定cat1就不用担心变量名不对是不是很方便。自定义注入名如果你想自己指定注入名那么就需要使用Resource注解只需要在Dog和Cat类作如下修改Data Service(miniCat) public class Cat implements Animal { private String catName 罗小黑; }对于Cat我们的注入名为miniCat所以我们可以指定miniCat如下Data public class Pets { Resource private Dog dog1; Resource(name miniCat) // 只能是miniCat如果为其它名字会报错 //Resource(type Cat.class) // 这种方式也可以 //Resource // 这种方式也可以 private Cat cat1; // main()省略同上 // 输出Pets(catCat(catName罗小黑), dogDog(dogName旺财)) }这块使用的姿势应该还有我就不列举无论如何变化只需要知道Resource的装配顺序以及Resource和Autowired的区别就很好理解了。Resource vs AutowiredResource的装配顺序如下Resource后面没有任何内容默认通过name属性去匹配bean找不到再按type去匹配指定了name或者type则根据指定的类型去匹配bean指定了name和type则根据指定的name和type去匹配bean任何一个不匹配都将报错。然后区分一下Autowired和Resource两个注解的区别Autowired默认按照byType方式进行bean匹配Resource默认按照byName方式进行bean匹配Autowired是Spring的注解Resource是J2EE的注解这个看一下导入注解的时候这两个注解的包名就一清二楚了Spring属于第三方的J2EE是Java自己的东西因此建议使用Resource注解以减少代码和Spring之间的耦合。总结一下Resource根据name和type是先Name后TypeAutowired是Type一般情况下我们最好使用Resource。
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

DataX容器化部署性能优化实战:从JVM到调度全链路调优 2026/9/28 5:30:11

DataX容器化部署性能优化实战:从JVM到调度全链路调优

前几天整理代码仓库,翻出一个命名相当奇怪的项目:[特殊字符]_容器化部署的性能优化实战[20260110163009]。前缀是一串乱码般的特殊字符,后缀跟着一串时间戳,第一眼我还以为是哪次压测脚本的自动备份。点开项目文档才发现&#xff…

阅读更多 →
Java比价网Spider开源源码解析:从抓取到落库的实战指南 2026/9/28 5:30:11

Java比价网Spider开源源码解析:从抓取到落库的实战指南

简介:这是一份面向Java开发者和爬虫学习者的比价网Spider开源项目源码,核心围绕比价网站数据抓取、解析与展示展开,适合希望了解电商比价系统完整实现的中高级开发者参考。压缩包共2000个文件,约122.75MB,主要包含698个…

阅读更多 →
Spring Boot家政保洁预约系统实战:订单状态机与并发冲突处理 2026/9/28 5:30:11

Spring Boot家政保洁预约系统实战:订单状态机与并发冲突处理

去年有个做家政公司的朋友找我吐槽,说公司保洁阿姨四十多人,每天排班全靠微信群和Excel,客户预约、阿姨调配、完工结算全靠人工盯,高峰期一天能接两百多单,光是打电话确认时间就能打到手机发烫。更麻烦的是&#xff0c…

阅读更多 →
VMware虚拟机安装Windows 10全流程:配置、优化与排障指南 2026/9/28 5:30:11

VMware虚拟机安装Windows 10全流程:配置、优化与排障指南

很多人第一次接触 VMware,都是奔着“在不重装系统的情况下,用上另一个系统”这个目的来的。我最早用 VMware 装 Windows 10 虚拟机,是因为要在干净环境里测各种软件,又不想把自己主力电脑搞乱。后来帮同事、朋友装过好几台&#x…

阅读更多 →
互联网网站排名提升5倍实战对比评测 2026/9/28 5:30:11

互联网网站排名提升5倍实战对比评测

互联网网站排名提升5倍实战对比评测 模板网站真的能撑过三个月吗?很多老板觉得模板便宜省事,结果上线半年,页面丑得让人不敢信,功能也跟不上业务变化。更惨的是,搜索引擎压根不待见这种“复制粘贴”的货色。…

阅读更多 →
Nodemailer实战:Node.js邮件通知服务搭建与SMTP配置指南 2026/9/28 5:30:05

Nodemailer实战:Node.js邮件通知服务搭建与SMTP配置指南

前阵子给团队搭内部通知中心,需求很直白:用户注册、密码找回、服务异常告警这些事件发生时,系统要能自动往目标邮箱发信。后端用的是 Node.js,邮件这块我调研了一圈,最后锁定了 Nodemailer。这个库成名早、更新时间长、…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉