我的编程空间,编程开发者的网络收藏夹
学习永远不晚

关于@Bean的使用方式

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

关于@Bean的使用方式

@Bean是一个方法级别上的注解,主要用在@Configuration注解的类里,也可以用在@Component注解的类里。

目的是创建一个类。当spring需要创建指定的一个类时会调用这个注解(@Bean)的方法。

一个对象

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Info {
    String name;
    int age;
}

就如同在在xml配置中添加一个类的配置。这样spring在自动创建这个类时会调用配置的方法。

<bean id="info" class="zhong.test.springbootdemo.usultestdemo.demo.Info">
    <property name="name" value="sjl"/>
    <property name="age" value="18"/>
</bean>

SprignBoot中 @Bean 完美的替换了了上面的这种在xml中配置的方法。使用以下方法就能让spring在需要自动创建Info对象时,自动调用这个方法。

@Configuration
public class BeanInit {
    
    @Bean(name = "info")
    public Info getInfo(){
        return new Info("gfagduis", 2343);
    }
    @Bean(name = "info1")
    public Info getInfo1(){
        return new Info("gfagdufasfdfdais", 2343);
    }
}

获取这个类的方法

1、AnnotationConfigApplicationContext 类获取

@Component
public class BeanTest implements CommandLineRunner {
    private void getBean(){
        ApplicationContext ctx = new AnnotationConfigApplicationContext(BeanInit.class);
        Info info1= ctx.getBean("info",Info.class);
        System.out.println(info1);
    }
    @Override
    public void run(String... args) throws Exception {
        System.out.println(">>>>>>>>>>>>>>>服务启动执行,执行加载数据等操作<<<<<<<<<<<<<");
        getBean();
    }
}

2、在spring自动创建的类中

在构造方法中设置这个值,这样spring就会调用该类的创建方法来获取这个初始化的类。

@Component
public class BeanTest implements CommandLineRunner {
    private Info info;
    
    public BeanTest (Info info1){
        this.info = info1;
    }
    
   private void getBean2(){
        System.out.println(info);
    }
    @Override
    public void run(String... args) throws Exception {
        System.out.println(">>>>>>>>>>>>>>>服务启动执行,执行加载数据等操作<<<<<<<<<<<<<");
        getBean2();
    }
}

在构造函数中 BeanTest (Info info1) 参数的名称是info1.所以就调用 @Bean(name = “info1”) 的方法来获取初始化对象。

结果如下:

                          >>>>>>>>>>>>>>>服务启动执行,执行加载数据等操作<<<<<<<<<<<<<
                         Info(name=gfagdufasfdfdais, age=2343)

同时也是支持多别名配置的 例如:

    @Bean(name = { "info12", "info3", "info3" })
    public Info getInfo2(){
        return new Info("gfa4361783ais", 2343);
    }

测试一下

@Component
public class BeanTest implements CommandLineRunner {
    private Info info;
    private Info info1;
    private Info info2;
    
    public BeanTest (Info info1, Info info2, Info info3){
        this.info = info1;
        this.info1 = info2;
        this.info2 = info3;
    }
    
   private void getBean2(){
        System.out.println(info);
        System.out.println(info1);
        System.out.println(info2);
    }
    @Override
    public void run(String... args) throws Exception {
        System.out.println(">>>>>>>>>>>>>>>服务启动执行,执行加载数据等操作<<<<<<<<<<<<<");
        getBean2();
    }
}

结果如下

>>>>>>>>>>>>>>>服务启动执行,执行加载数据等操作<<<<<<<<<<<<<
Info(name=gfagdufasfdfdais, age=2343)
Info(name=gfa4361783ais, age=2343)
Info(name=gfa4361783ais, age=2343)

当然也可以使用 Qualifier(“xxx”) 来指定 @Bean(name = “xxx”) 中的xxx就可以调用对应的方法。

3、使用 @Autowired 注解获取变量

如果有多个初始化方法,则会根据变量名称来获取。

在初始化类中建立以下多个初始方法

 @Configuration
public class BeanInit {
    
    @Bean
    public Info getInfo(){
        System.out.println("进入方法");
        Info info = new Info("gfagduis", 2343);
        System.out.println("结束方法");
        return info;
    }
    @Bean(name = "info1")
    public Info getInfo1(){
        return new Info("gfagdufasfdfdais", 2343);
    }
    @Bean(name = { "info2", "info3", "info3" })
    public Info getInfo2(){
        return new Info("gfa4361783ais", 2343);
    }
    @Bean
    public Info info(){
        return new Info("gfsdfadsfad4361783ais", 23143);
    }

然后在测试方法中分别用 @Autowired注释Info类来获取对应的对象

@Component
public class BeanTest implements CommandLineRunner {
    //private Info info;
    @Autowired
    private Info getInfo;
    @Autowired
    private Info info1;
    @Autowired
    private Info info3;
    @Autowired
    private Info info;
    
    private void getBean(){
        
        System.out.println(getInfo);
        System.out.println(info1);
        System.out.println(info3);
        System.out.println(info);
    }
    @Override
    public void run(String... args) throws Exception {
        System.out.println(">>>>>>>>>>>>>>>服务启动执行,执行加载数据等操作<<<<<<<<<<<<<");
        getBean();
    }
}

测试结果如下:

>>>>>>>>>>>>>>>服务启动执行,执行加载数据等操作<<<<<<<<<<<<<
Info(name=gfagduis, age=2343)
Info(name=gfagdufasfdfdais, age=2343)
Info(name=gfa4361783ais, age=2343)
Info(name=gfsdfadsfad4361783ais, age=23143)

在使用 @Autowired 注解时,也可以与 @Qualifier(“xxx”) 指定使用哪个方法来获取对象。

@Bean 注解的属性解析

value 和 name

name 和 value 两个属性是相同的含义的, 在代码中定义了别名。 为 bean 起一个名字,如果默认没有写该属性,那么就使用方法的名称为该 bean 的名称

autowire

装配方式 有三个选项

  • Autowire.NO (默认设置)
  • Autowire.BY_NAME
  • Autowire.BY_TYPE

指定 bean 的装配方式, 根据名称 和 根据类型 装配, 一般不设置,采用默认即可。

initMethod

bean 的初始化方法, 直接指定方法名称即可,不用带括号。初始方法要在对应的POHO中,也就是Info类中。

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Info {
    String name;
    int age;
    private void init(){
        System.out.println("进入方法2");
        name = "fhasjdf";
        age = 12;
    }
}
@Configuration
public class BeanInit {
    
    @Bean(name = "info", initMethod = "init")
    public Info getInfo(){
        System.out.println("进入方法");
        Info info = new Info("gfagduis", 2343);
        System.out.println("结束方法");
        return info;
    }

最终结果、:

进入方法
结束方法
进入方法2
2019-09-24 14:57:11.917  INFO 11656 --- [           main] o.s.s.concurrent.ThreadPoolTaskExecutor  : Initializing ExecutorService 'applicationTaskExecutor'
2019-09-24 14:57:12.048  INFO 11656 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8080 (http) with context path ''
2019-09-24 14:57:12.051  INFO 11656 --- [           main] z.t.s.u.start.UsulTestStartApplication   : Started UsulTestStartApplication in 1.74 seconds (JVM running for 2.246)
>>>>>>>>>>>>>>>服务启动执行,执行加载数据等操作<<<<<<<<<<<<<
Info(name=fhasjdf, age=12)

所以最终调用的是init()方法来创建类。

destroyMethod

bean 的销毁方法, 在调用 IoC 容器的 close() 方法时,会执行到该属性指定的方法。不过,只是单实例的 bean 才会调用该方法,如果是多实例的情况下,不会调用该方法。

注意:

由于spring构造的对象都是单例的,所以只要是从spring ioc中获取的对象都是同一个,他们中的属性,即便是私有的非静态属性。都是公用的。

public class MyDisposableBean implements DisposableBean {
    public Map<String, String> map = new HashMap<>();
    int i = 0;
    private void init(){
        System.out.println("MyDisposableBean自定义初始化方法");
    }
    private void destroyMethod(){
        System.out.println("自定义销毁方法,MyDisposableBean对象销毁");
    }
    public void pringt(){
        System.out.println("-------------------------------");
        System.out.println("i=" + i);
        System.out.println("map.size=" + map.size());
        map.entrySet().stream().forEach(item -> System.out.println("map ->   "+ item.getKey() + "---" + item.getValue()));
    }
}
@Configuration
public class BeanConfigurer {
    @Bean(name = "MyDisposableBean", initMethod = "init", destroyMethod = "destroyMethod")
    public MyDisposableBean getMyDisposableBean(){
        System.out.println("MyDisposableBean构造方法");
        return new MyDisposableBean();
    }
}
@Component
public class DisposableBeanTest implements CommandLineRunner {
    @Override
    public void run(String... args) throws Exception {
        MyDisposableBean myDisposableBean = new MyDisposableBean();
        MyDisposableBean myDisposableBean1 = new MyDisposableBean();
        MyDisposableBean myDisposableBean2 = SpringContextUtils.getBean(MyDisposableBean.class);
        myDisposableBean2.pringt();
        myDisposableBean2.map.put("1", "2");
        myDisposableBean2.i = 2;
        MyDisposableBean myDisposableBean3 = SpringContextUtils.getBean(MyDisposableBean.class);
        myDisposableBean3.pringt();
        myDisposableBean1.pringt();
    }
}

测试结果:

MyDisposableBean构造方法
MyDisposableBean自定义初始化方法
-------------------------------
i=0
map.size=0
-------------------------------
i=0
map.size=0
-------------------------------
i=2
map.size=1
map ->   1---2
-------------------------------
i=0
map.size=0

可以看出,如果是我们自己在程序中new的对象(myDisposableBean 和 myDisposableBean1),其私有属性map和i是不变的。不相互影响。

另外两从spring ioc中获取的对象(myDisposableBean2 和 myDisposableBean3 )的map和i两个属性,是公用的。其中一个对象修改值,name另外一个对象的属性也相应的变化

以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程网。

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

关于@Bean的使用方式

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

关于SpringBoot获取bean的3种方式

这篇文章主要介绍了关于SpringBoot获取bean的3种方式,在spring中ApplicationContext这个上下文对象是获取bean的基础,需要的朋友可以参考下
2023-05-17

关于element中el-cascader的使用方式

这篇文章主要介绍了关于element中el-cascader的使用方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
2022-11-13

关于Object.entries()方法的使用和实现方式

这篇文章主要介绍了关于Object.entries()方法的使用和实现方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
2023-02-10

关于@click.native中 .native 的含义与使用方式

这篇文章主要介绍了关于@click.native中 .native 的含义与使用方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
2022-11-13

关于TransparentBlt的使用方法

TransparentBlt是GDI函数之一,用于在Windows平台上绘制透明图像。它可以将源图像的一部分或全部绘制到目标设备上,并将指定的颜色作为透明色进行处理。使用TransparentBlt函数的一般步骤如下:1. 创建源图像和目标
2023-08-08

关于JavaScript的URL.createObjectURL()的使用方法

这篇文章主要介绍了关于URL.createObjectURL()的使用方法,使用createObjectURL可以节省性能并更快速,只不过需要在不使用的情况下手动释放内存,还不清楚的朋友一起来看看吧
2023-05-17

JavaScript中关于数组的调用方式

这篇文章主要介绍了JavaScript中关于数组的调用方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
2023-02-10

Spring创建bean的几种方式及使用场景

本文主要介绍了Spring创建bean的几种方式及使用场景,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
2023-05-18

解读Spring定义Bean的两种方式:<bean>和@Bean

这篇文章主要介绍了Spring定义Bean的两种方式:<bean>和@Bean,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
2023-05-14

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录