挖一挖@Bean这个东西
有Bean得治
任何一个正常程序的访问都会在内存中创建非常多的对象,对象与对象之间还会出现很多依赖关系(一个处理业务逻辑的类中几乎都会使用到别的类的实例),一般的做法都是使用new关键字来创建对象,对于多次重复使用的对象会采用单例模式来设计。
但在Spring中却不是这样,Spring框架使用了一个容器对这些对象进行管理,每一个需要被管理的对象被称为Bean,而管理这些Bean的容器,被称为IoC容器。
控制反转(IoC)在是一种通过描述来生成或者获取对象的技术,在Spring Boot中,我们经常是通过注解来创建对象,这里只谈注解,无视XML。
Spring Boot在启动的过程中,会去扫描需要被管理的Bean,将Bean装载到IoC容器中,根据依赖关系进行实例化对象,最后进行依赖注入。也就是说,在项目启动完成后,所有的Bean都已经实例化完成,并已在相应的地方注入完成,访问程序使用到的这些对象都只是在直接调用对象实例,并不会出现一个new的过程,因为这些对象在项目启动的时候就已经都被new出来了。
Bean的创建方式有很多种,最常用的是@Component,@Service,@Repository等等直接放在类头上的注解,都是一些标记,用于被收集后反射再实例化最终赋值达到注入的目的,可了解的应该就是其中的一些附带规则:条件装配,就是如果存在某个Bean时(也可以判断不存在时)再装配当前这个Bean,不过条件装配我觉得应用场景并不常见。
这里主要是要挖一挖@Bean这个注解的使用。
用@Bean创建Bean
@Bean注解是只能用在方法上,标志该方法需要创建一个Bean,方法返回的对象就是创建Bean的目标对象。
建一个User实体类:
public class User {
private int id = 2;
private String name = "我是User类的小光";
private String sex = "我是难的";
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
", sex='" + sex + '\'' +
'}';
}
}
示例:
@Configuration
public class Config {
@Bean
public String aaa(){
return "你大爷";
} @Bean
public User bbb(){
return new User();
}
}
这个Config类,创建了两个Bean,创建的对象一个是String对象一个是User对象,可以是任何对象,我这里为了更加直白的表达“Bean”是什么东西,特意使用了String来做例子。
当然了 bean的名字是可以定的 以下三种定义方式都可以:
@Bean(name = "aaa")
@Bean("aaa")
@Bean
第三种方式没有指定名字,那么框架会将方法名作为bean的名字,注意:是方法原名,不会是小驼峰,只有应用在类上的注解创建的bean才会是小驼峰,@Bean是方法上的注解。
你的脑补绝对有用
此时,你可以脑补一下框架是怎么创建Bean的:
HashMap map = new HashMap();
map.put("aaa",new String("你大爷"));
map.put("bbb",new User());
所谓IoC容器,就是一个集合,装了很多对象,你要用哪个对象,Spring就会从集合里取给你。
----->当然了,虽然你的脑补不一定完全正确,但是你的脑补绝对有用。
@Bean注解受不受@ComponentScan的影响?
@ComponentScan注解定义扫描路径,也就是说,Spring Boot只会扫描指定路径之内的类,遇到特殊注解就会开始进行Bean的收集工作。
在Spring Boot的启动类main方法上有@SpringBootApplication注解,点进去之后可以看到它里面包含的有@ComponentScan,所以尽管我们没有手动指定扫描范围,但是默认是以启动类所在的包作为一个扫描范围。
但这里要说明的是,@ComponentScan这个注解,它是用来约束@Configuration,@Controller,@Service,@Repository,@Component等作用在类上注解,但是它管不了@Bean注解,只要项目中有@Bean注解,即使身处启动类的外层,不在@ComponentScan的扫描范围之内,该Bean也会存在,只是没有被扫描装配,也就是可以获取,但无法注入。
是否一定要和@Configuration一起用?
我的答案是:是的!
如果你没有加@Configuration注解,那么Spring将不会扫描这个类,但是你后期获取该Bean的时候,Spring可以找到它,也就是说,如果没有加@Configuration注解,那么项目启动后是没有该Bean的,只有当你获取该Bean的时候,才会进行实例化。
获取你的Bean
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Config.class);
Object aaa = context.getBean("aaa");
System.out.println(aaa.toString()); Object bbb = context.getBean("bb");
System.out.println(bbb.toString());
该示例代码获取的是Config类中的aaa和bbb两个Bean。
注意,它并不是获取容器中的Bean,它是根据你提供的class和Bean名称跑去执行了一下方法,新new了一个对象给你,再有,这个Bean名称必须用原名,大小写不打折的。
小提示:无论类的头上有没有@Configuration注解,该方式都可以成功,当然,如果类的头上有@Configuration注解,那么该Bean的返回对象可以直接在别处进行注入。
如果你要获取类上的Bean,可以采用下面这个工具类来获取:
@Component
public class SpringUtil implements ApplicationContextAware { private static ApplicationContext applicationContext = null; @Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
if (null == SpringUtil.applicationContext) {
SpringUtil.applicationContext = applicationContext;
}
} // 获取applicationContext
public static ApplicationContext getApplicationContext() {
return applicationContext;
} // 通过name获取 Bean.
public static Object getBean(String name) {
return getApplicationContext().getBean(name);
} // 通过class获取Bean.
public static <T> T getBean(Class<T> clazz) {
return getApplicationContext().getBean(clazz);
} // 通过name,以及Clazz返回指定的Bean
public static <T> T getBean(String name, Class<T> clazz) {
return getApplicationContext().getBean(name, clazz);
}
}
挖一挖@Bean这个东西的更多相关文章
- 挖一挖C#中那些我们不常用的东西之系列(3)——StackTrace,Trim
时间太快了,三月又要过去了,告别一下...继续期待生死未卜的四月,今天我们继续挖一挖. 一: Environment.StackTrace 可能我们看到最多的就是catch中的e参数,里面会有一个St ...
- 挖一挖不常用到而又很实用的重载-Split
Split这个基本上所有的程序开发人员都用到,一般使用单字符和长字符串拆分字符串的较多,其实还有一个重载非常好用,那就是多种组合字符来进行拆分. 例如: "aaaaaaaaaa{@}bbbb ...
- 挖一挖不常用到而又很实用的重载-Trim
这个我想没有那个开发人员说不知道,但是里面有一个重载,这个不知道有多少开发人员知道! 可以看到,我可以去掉字符串前后的指定字符,只要我在char[]中指定即可,而不是仅仅去掉空格,这次为什么要提它,是 ...
- ArcGIS案例学习笔记-批处理擦除挖空挖除相减
ArcGIS案例学习笔记-批处理擦除挖空挖除相减 联系方式:谢老师,135-4855-4328,xiexiaokui#qq.com 目的:批处理擦除.挖空.挖除.相减 数据源:chp13/ex5/pa ...
- ArcGIS案例学习笔记-手动编辑擦除挖空挖除相减
ArcGIS案例学习笔记-手动编辑擦除挖空挖除相减 联系方式:谢老师,135-4855-4328,xiexiaokui#qq.com 目的:手动编辑擦除.挖空.挖除.相减 1. 选中内部要素 2. c ...
- 挖一挖不经常使用到而又非常有用的重载-Split
Split这个基本上全部的程序开发者都用到,一般使用单字符和长字符串拆分字符串的较多.事实上另一个重载很好用.那就是多种组合字符来进行拆分. 比如: "aaaaaaaaaa{@}bbbbbb ...
- 挖一挖C#中那些我们不常用的东西之系列(2)——IsXXX 系列方法
不知道有人做没做过对日外包,如果做过的话,那么对vb.net应该非常熟悉了,当年我刚毕业的时候也做过四个月的外包,那种日子简直 不是人过的,就连大楼下面买珠宝的阿姨都说,这些孩子,只看过他们上班,就没 ...
- 挖一挖C#中那些我们不常用的东西之系列(1)——ToDictionary,ToLookup
这个系列我们看看C#中有哪些我们知道,但是又不知道怎么用,又或者懒得去了解的东西,比如这篇我们要介绍的toDictionary 和ToLookup. 从图中我们看到有四个ToXXX的方法,其中ToAr ...
- 挖一挖C#中那些我们不经常使用的东西之系列(1)——ToDictionary,ToLookup
这个系列我们看看C#中有哪些我们知道.可是又不知道怎么用.又或者懒得去了解的东西,比方这篇我们要介绍的toDictionary 和ToLookup. 从图中我们看到有四个ToXXX的方法,当中ToAr ...
随机推荐
- BZOJ_3170_[Tjoi2013]松鼠聚会_切比雪夫距离+前缀和
BZOJ_3170_[Tjoi2013]松鼠聚会_切比雪夫距离+前缀和 题意:有N个小松鼠,它们的家用一个点x,y表示,两个点的距离定义为:点(x,y)和它周围的8个点即上下左右四个点和对角的四个点, ...
- CLOSE_WAIT问题-TCP
环境简述 要说清楚问题,先要简单说下生产环境的网络拓扑(毕竟是个网络问题对吧) 看,挺简单的对吧,一个OpenResty做SLB承受客户端请求,反响代理到几台应用服务器.由于业务要求,必须要同步调用第 ...
- MYSQL—— 启动MYSQL 57 报错“The service MYSQL57 failed the most recent........等”的问题解决方式!
每天开机之后,启动MYSQL Notifier就报错,第一次出现重启电脑后解决,后面的几天老是出现,重启电脑好几次都没有解决,感觉很烦人,一定要搞定这个问题找到原因,于是有了下文....... 启动M ...
- 二维码神器QRCoder
好久没有写Blog,都是因为不小心坠入了爱河,时间都给我家那位了,都没时间加班了(嗨呀,不小心撒了一下狗粮),不过,还是希望单身的赶紧找到心仪的另一半,实在找不到,那就加班啊(开个玩笑,别认真). 二 ...
- Mac PyCharm激活码(转载CSDN的猪哥66文章)
对于很多刚接触python的新手来说,各种资源都是非常稀缺的.我也是刚接触python不久的新手,有好的资源就分享出来大家共同进步. 这篇文章是教你怎么安装和破解pycharm的教程,我在2019.4 ...
- 链表底层实现Java的Map(上)
链表实现Map public class LinkListMap<K,V> implements Map<K,V> { private class Node { public ...
- .NET Core之微信支付之公众号、H5支付篇
前言 本篇主要记录微信支付中公众号及H5支付全过程. 准备篇 公众号或者服务号(并开通微信支付功能).商户平台中开通JSAPI支付.H5支付. 配置篇 公众号或者服务号中 -------开发----- ...
- rocketMQ安装中遇到的坑
安装步骤是这些: Prerequisite The following softwares are assumed installed: 64bit OS, Linux/Unix/Mac is rec ...
- 【转载】C#工具类:实现文件操作File的工具类
在应用程序的开发中,文件操作的使用基本上是必不可少的,FileStream类.StreamWriter类.Directory类.DirectoryInfo类等都是文件操作中时常涉及到的类,我们可以通过 ...
- fab 菜单实现—圆形、半圆、扇形、直线、射线
前段时间记录一下fab 菜单实现之前传-钟表表盘,今天终于弄正文了. 本文基于上篇文章的布局方式和位置计算,并参考35 Cool Floating Action Button Animations(h ...