Spring中Bean对象的存储和获取
目录
- 1. 更简单的将bean存储到spring中
- 1.0 前置工作,在配置文件中设置bean扫描的根路径
- 1.1 通过注解将bean存储到spring中
- 1.1.1 @Controller【控制器】
- 关于类注解的bean的名称规则:
- 1.1.2 @Service【服务】
- 1.1.3@Repository【仓库】
- 1.1.4@Component【组件】
- 1.1.5 @Configuration【配置】
- 1.2 为什么要这么多类注解?
- 1.3.方法注解:@Bean
- 1.3.1 方法注解要配合类注解使用
- 1.3.2 重命名bean
- 2.获取 Bean 对象(对象装配)
- 2.1 属性注入
- 2.2 构造方法注入
- 2.3 Setter 注入
- 2.4 三种注入优缺点分析
- 2.5 @Resource:另一种注入关键字
- 2.6@Autowired 和 @Resource 的区别
- 2.7 同一类型多个 @Bean 报错
- 3.总结
1. 更简单的将bean存储到spring中
1.0 前置工作,在配置文件中设置bean扫描的根路径
1.1 通过注解将bean存储到spring中
想要将对象存储在 Spring 中,有两种注解类型可以实现:
1.类注解:@Controller【控制器】、@Service【服务】、@Repository【仓库】、@Component【组件】、@Configuration【配置】。
2.方法注解:@Bean。
接下来我们分别来看。
1.1.1 @Controller【控制器】
package com.beans;
import org.springframework.stereotype.Controller;
@Controller//将当前对象存储到spring中
public class UserController {public void sayHi(String name){System.out.println("你好,"+name);}
}
使用之前读取对象的方式来读取上面的 UserController 对象:
import com.beans.UserController;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class App {public static void main(String[] args) {// 1.获取 spring 上下文ApplicationContext context =new ClassPathXmlApplicationContext("spring-config.xml");// 2.得到 beanUserController userController = context.getBean(UserController.class);// 3.使用 beanuserController.sayHi("极致千叶");}
}
运行结果:
注意事项1:即使在spring配置文件中配置了bean的扫描路径,但是5大类注解是不能省略的。
注意事项2:即使加了5大类注解,但类没有放在spring配置的bean路径下,那么也是不能将类注入到spring中的。
关于类注解的bean的名称规则:
通常情况下‘是小驼峰(也就是将类名小写)就可以获取到bean对象
UserService userService=context.getBean("userService",UserService.class);
userService.sayHi("慕远笙歌");
如果第一个字母为大写,第二个字母为小写的情况下,那么bean的命名规则就是首字母小写。
如果第一个和第二个字母都是大写的情况下,那么bean命名规则是原类名
1.1.2 @Service【服务】
package com.beans;import org.springframework.stereotype.Service;
@Service//将当前对象存储到spring中
public class UserService {public void sayHi(String name) {System.out.println("你好," + name);}
}
import com.beans.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class App {public static void main(String[] args) {// 1.获取 spring 上下文ApplicationContext context =new ClassPathXmlApplicationContext("spring-config.xml");UserService userService=context.getBean("userService",UserService.class);userService.sayHi("慕远笙歌");}
}
1.1.3@Repository【仓库】
package com.beans;import org.springframework.stereotype.Repository;@Repository//将当前对象存储到spring中
public class UserRepository {public void sayHi(String name) {System.out.println("你好," + name);}
}
import com.beans.UserRepository;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class App {public static void main(String[] args) {// 1.获取 spring 上下文ApplicationContext context =new ClassPathXmlApplicationContext("spring-config.xml");UserRepository userRepository=context.getBean("userRepository", UserRepository.class);userRepository.sayHi("谋长节短");}
}
1.1.4@Component【组件】
package com.beans;import org.springframework.stereotype.Component;@Component//将当前对象存储到spring中
public class UserComponent {public void sayHi(String name) {System.out.println("你好," + name);}
}
import com.beans.UserComponent;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class App {public static void main(String[] args) {// 1.获取 spring 上下文ApplicationContext context =new ClassPathXmlApplicationContext("spring-config.xml");UserComponent userComponent=context.getBean("userComponent",UserComponent.class);userComponent.sayHi("百战百胜");}
}
1.1.5 @Configuration【配置】
package com.beans;import org.springframework.context.annotation.Configuration;@Configuration//将当前对象存储到spring中
public class UserConfiguration {public void sayHi(String name) {System.out.println("你好," + name);}
}
import com.beans.UserConfiguration;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class App {public static void main(String[] args) {// 1.获取 spring 上下文ApplicationContext context =new ClassPathXmlApplicationContext("spring-config.xml");UserConfiguration userConfiguration=context.getBean("userConfiguration",UserConfiguration.class);userConfiguration.sayHi("难知如阴");}
}
1.2 为什么要这么多类注解?
- @Component【组件】是其他四个注解的父类;
@Controller:表示的是业务逻辑层(控制器,和前端打交道【验证前端的有效性】);
@Servie:服务层(组织数据调用相应的接口);
@Repository:持久层(数据持久层【dao/repository】,和数据库直接打交道,执行具体的CRUD操作);
@Configuration:配置层(存放所有的配置信息)。
1.3.方法注解:@Bean
类注解是添加到某个类上的,而方法注解是放到某个方法上的。
1.3.1 方法注解要配合类注解使用
在 Spring 框架的设计中,方法注解 @Bean 要配合类注解才能将对象正常的存储到 Spring 容器中,如下代码所示:
package com.beans;import com.model.User;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Controller;@Controller
public class UserBeans {@Bean//将当前方法返回的对象存储到spring中,默认bean名称为方法名public User user1(){User user=new User();user.setId(1);user.setName("极致千叶");user.setPassword("123");return user;}
}
1.3.2 重命名bean
可以通过设置 name 属性给 Bean 对象进行重命名操作
package com.beans;import com.model.User;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Controller;@Controller
public class UserBeans {//给当前对象起一个别名@Bean(name="user2")//将当前方法返回的对象存储到spring中,默认bean名称为方法名public User user1(){User user=new User();user.setId(1);user.setName("极致千叶");user.setPassword("123");return user;}
}
这个重命名的 name 其实是一个数组,一个 bean 可以有多个名字:
package com.beans;import com.model.User;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Controller;@Controller
public class UserBeans {//给当前对象起一个或多个别名@Bean(name={"user2","user"})//将当前方法返回的对象存储到spring中,默认bean名称为方法名public User user1(){User user=new User();user.setId(1);user.setName("极致千叶");user.setPassword("123");return user;}
}
并且 name={} 可以省略,如下代码所示:
package com.beans;import com.model.User;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Controller;@Controller
public class UserBeans {@Bean({"user2","user"})//将当前方法返回的对象存储到spring中,默认bean名称为方法名public User user1(){User user=new User();user.setId(1);user.setName("极致千叶");user.setPassword("123");return user;}
}
当@Bean
重命名后,使用方法名不能获取到Bean对象!!!如果没有对Bean进行重命名,那么可以使用方法名获取Bean对象
2.获取 Bean 对象(对象装配)
获取 bean 对象也叫做对象装配,是把对象取出来放到某个类中,有时候也叫对象注入。
对象装配(对象注入)的实现方法以下 3 种:
- 属性注入
- 构造方法注入
- Setter 注入
接下来,我们分别来看。
下面我们按照实际开发中的模式,将 Service 类注入到 Controller 类中。
2.1 属性注入
属性注入是使用 @Autowired
实现的,将 Service 类注入到 Controller 类中。
Service 类的实现代码如下:
package com.beans;import com.model.User;
import org.springframework.stereotype.Service;
@Service//将当前对象存储到spring中
public class UserService {/*** 根据id获取用户* @param id* @return*/public User getUserById(int id){//伪代码User user=new User();user.setId(id);user.setName("刑天");user.setPassword("123");return user;}
}
Controller 类的实现代码如下:
package com.beans;import com.model.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;@Controller//将当前对象存储到spring中
public class UserController {//1.属性注入@Autowiredprivate UserService userService;public User getUserById(Integer id){return userService.getUserById(id);}
}
App方法:
import com.beans.*;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;import java.beans.Introspector;public class App {public static void main(String[] args) {// 1.获取 spring 上下文ApplicationContext context =new ClassPathXmlApplicationContext("spring-config.xml");UserController userController=context.getBean(UserController.class);System.out.println(userController.getUserById(10));}
}
2.2 构造方法注入
构造方法注入是在类的构造方法中实现注入,如下代码所示:
package com.beans;import com.model.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;@Controller//将当前对象存储到spring中
public class UserController2 {private UserService userService;//1.构造方法注入@Autowired//如果当前类只有一个构造方法,那么@Autowired可以省略public UserController2(UserService userService){this.userService=userService;}public void sayHi(String name){System.out.println("你好,"+name);}public User getUserById(Integer id){return userService.getUserById(id);}
}
如果当前类只有一个构造方法,那么@Autowired可以省略;但是如果当前方法中存在多个构造方法,那么@Autowired是不能省略的。
2.3 Setter 注入
Setter 注入和属性的 Setter 方法实现类似,只不过在设置 set 方法的时候需要加上 @Autowired 注解,如下代码所示:
package com.beans;import com.model.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;@Controller//将当前对象存储到spring中
public class UserController3 {private UserService userService;//3.Setter 注入@Autowiredpublic void setUserService(UserService userService) {this.userService = userService;}public void sayHi(String name){System.out.println("你好,"+name);}public User getUserById(Integer id){return userService.getUserById(id);}
}
2.4 三种注入优缺点分析
- 属性注入的优点是简洁,使用方便;缺点是不通用,只能用于 IoC 容器,如果是非 IoC 容器不可用,并且只有在使用的时候会出现空指针异常。
- 构造方法注入是 Spring 推荐的注入方式,它的缺点是可能存在多个参数来实现构造方法的初始化,会显得比较臃肿,但出现这种情况你应该考虑一下当前类是否符合程序的单一职责的设计模式了,它的优点是通用性,并且能保证再调用对象之前,此对象一定存在。
- Setter 方式是 Spring 前期版本推荐的注入方式,但通用性不如构造方法,所有 Spring 现版本已经推荐使用构造方法注入的方式来进行类注入了。
2.5 @Resource:另一种注入关键字
在进行类注入时,除了可以使用 @Autowired 关键字之外,我们还可以使用 @Resource 进行注入,如下代码所示:
package com.beans;import com.model.User;
import org.springframework.stereotype.Controller;import javax.annotation.Resource;@Controller//将当前对象存储到spring中
public class UserController5 {@Resourceprivate UserService userService;// @Resourcepublic UserController5(UserService userService){this.userService=userService;}public User getUserById(Integer id){return userService.getUserById(id);}
}
2.6@Autowired 和 @Resource 的区别
出身不同:@Autowired 来自于 Spring,而 @Resource 来自于 JDK 的注解;
使用时设置的参数不同:相比于 @Autowired 来说,@Resource 支持更多的参数设置,例如 name设置,根据名称获取 Bean。
支持的注入类型不同:@Autowired 支持属性注入、构造方法注入 和Setter 注入,@Resource 支持属性注入和 Setter 注入,不支持构造方法注入。
2.7 同一类型多个 @Bean 报错
一个类型被注册到Spring多次时,程序运行就会出现异常。
package com.beans;import com.model.User;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Controller;@Controller
public class UserBeans {// @Bean("user2")//将当前方法返回的对象存储到spring中,默认bean名称为方法名@Bean(name="user1")public User user1(){User user=new User();user.setId(1);user.setName("极致千叶");user.setPassword("123");return user;}@Bean(name="user2")public User user2(){User user=new User();user.setId(2);user.setName("慕远笙歌");user.setPassword("456");return user;}
}
解决异常的办法:
- 使用正确的bean name。
- 设置bean name
- 使用@Autowired+@Qualifier
① 使用 @Resource(name=“XXX”)
package com.beans;import com.model.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;import javax.annotation.Resource;@Controller
public class UserController6 {@Resource(name="user1")private User user;public void saiHi(){System.out.println(user);}
}
② 使用 @Qualifier(" ")
package com.beans;import com.model.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;import javax.annotation.Resource;@Controller
public class UserController6 {@Autowired@Qualifier(value ="user2")private User user;public void saiHi(){System.out.println(user);}
}
3.总结
- 将对象存储在Spring中:
- a.实用类注解:@Controller【控制器】、@Service【服务】、@Repository【仓库】、@Component【组件】、@Configuration【配置】,【它们之间的关系】
- b.使用方法注解:@Bean【注意事项:必须配合类注解一起使用】
- Bean的命名规则:首字母和第二个字母都非大写,首字母小写来获取Bean,如果首字母和第二个字母都是大写,那么直接使用原Bean名来获取Bean。
- 从Spring中获取对象:
- a.属性注入
- b.Setter注入
- c.构造函数注入(推荐)
- 注入的关键字有:
- a.@Autowired
- b.@Resource
- @Autowired和@Resource的区别:出身不同;使用时设置参数不同,@Resource支持更多的参数,比如name。
- 解决同一类型多个Bean的报错:
- a.使用 @Resource(name=“XXX”)
- b. 使用 @Qualifier(" ")
- c.构造函数注入(推荐)
Spring中Bean对象的存储和获取相关推荐
- Spring中bean的scop
在Spring中bean对象的作用范围: 1:在默认情况下,Spring中管理的bean都是singleton的. 2:常用的scop: 1,singleton:单例,第一次创建之后,以后每次都拿这同 ...
- 如果你每次面试前都要去背一篇Spring中Bean的生命周期,请看完这篇文章
前言 当你准备去复习Spring中Bean的生命周期的时候,这个时候你开始上网找资料,很大概率会看到下面这张图: 先不论这张图上是否全面,但是就说这张图吧,你是不是背了又忘,忘了又背? 究其原因在于, ...
- ajax redirectattributes 使用,Spring中RedirectAttributes对象重定向传参
Spring3中的FlashAttribute 为 了防止用户刷新重复提交,save操作之后一般会redirect到另一个页面,同时带点操作成功的提示信息.因为是Redirect,Request里 的 ...
- Spring中bean标签的属性和值:
Spring中bean标签的属性和值: <bean name="user" class="com.pojo.User" init-method=" ...
- Spring 中 Bean 的生命周期
本文作者: 伯乐在线 - yemengying 智商捉鸡?,实在没办法一下子理解Spring IoC和AOP的实现原理,看的闹心也不太懂,所以...决定拆成小的不能在小的一个个问题,一点点啃.今天先来 ...
- 厉害了,Spring中bean的12种定义方法!
前言 在庞大的java体系中,spring有着举足轻重的地位,它给每位开发者带来了极大的便利和惊喜.我们都知道spring是创建和管理bean的工厂,它提供了多种定义bean的方式,能够满足我们日常工 ...
- Spring笔记2——Spring中Bean的装配
1.引言 Spring中,对象无需自己负责查找或创建与其关联的其他对象,而是由容器负责把需要相互协作的对象引用赋予各个对象.创建应用对象之间的协作关系的行为通常称为装配(Wiring),这也是依赖注入 ...
- (十)Spring中Bean的生命周期(下)
Spring官网阅读(十)Spring中Bean的生命周期(下) 在上篇文章中,我们已经对Bean的生命周期做了简单的介绍,主要介绍了整个生命周期中的初始化阶段以及基于容器启动停止时LifeCycle ...
- Spring中bean的初始化和销毁几种实现方式详解
关联博文:Spring中Bean的作用域与生命周期 Bean的生命周期 : 创建bean对象 – 属性赋值 – 初始化方法调用前的操作 – 初始化方法 – 初始化方法调用后的操作 – --- 销毁前操 ...
最新文章
- 使用CSS3的appearance属性改变元素的外观
- oracle record is locked by another user
- QT的QAudioInput类的使用
- 对象的反序列化流_ObjectInputStream
- 用installshield打包的asp.net程序
- Java:反射+泛型:获取类型参数的实例
- python读awx文件_ansible awx用法
- 【Python】Python库之数据可视化
- 文件夹在哪里_在Mac电脑上截图和照片放在哪里?
- 李刚-我的全栈之路导师之一
- cl.exe is unable to create an executable file. C compiler test failed.
- nb-iot信号测试软件,NB-IOT测试仪
- Java下载excel模板
- Hbuilder快捷键教程
- C语言中的函数(重点介绍自定义函数)
- ADB控制安卓WIFI连接(斐讯R1联网指南)
- Android Studio Canvas 实现鼠标贝塞尔曲线拖尾特效(富文本编辑器)
- 7天学习Go语言-尾声+一次险些翻车的任意文件读取漏洞小记
- 三菱无机房电梯故障代码查询_三菱无机房ELENESSA电梯故障代码表
- 自监督学习和计算机视觉
热门文章
- Hibernate Validation校验注解详解
- 计算机专业考中山大学经济学,2020中山大学801经济学考崩经验教训
- 阿里巴巴的邮箱的服务器是什么意思啊,客户端设置中IMAP和POP3有什么不同呢?...
- class--杂项(一)
- sin cos tan cot公式
- PHP项目开发全程实录 第3版pdf
- 还在删减文件?知乎百万人追捧的内存增加术,让你的内存秒翻倍
- 2019年河源市计算机等级考试,2019年河源中考总分是多少 河源中考时间安排
- 整日碎片化学习“凡不凡”,android编程基础班
- 新手小白做自媒体影视剪辑,玩法详细分享,建议收藏起来边看边做