关于@Bean的使用方式

目录
  • 一个对象
  • 获取这个类的方法
    • 1、AnnotationConfigApplicationContext 类获取
    • 2、在spring自动创建的类中
    • 3、使用 @Autowired 注解获取变量
  • @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的作用
     */
    @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;
    /**
     *spring创建BeanTest对象时会调用这个构造函数。参数是info1,所以会调用 @Bean(name = "info1") 注释的方法
     *
     */
    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;
    /**
     *spring创建BeanTest对象时会调用这个构造函数。参数是info1,所以会调用 @Bean(name = "info1") 注释的方法
     *
     */
    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的作用
     */
    @Bean/*(initMethod = "init")*/
    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;
    /*public BeanTest (Info info){
        this.info = info;
    }*/
    private void getBean(){
        /*ApplicationContext ctx = new AnnotationConfigApplicationContext(BeanInit.class);
        Info person = ctx.getBean("info",Info.class);
        System.out.println(person);*/
        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的作用
     */
    @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另外一个对象的属性也相应的变化

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

(0)

相关推荐

  • Spring注解@Configuration与@Bean注册组件的使用详解

    目录 原始Spring开发 Person.java pom.xml bean.xml PersonTest.java 注解Spring开发 原始Spring开发 Person.java 准备Person.java类: package com.jektong.spring; public class Person { private String name; private int age; public Person() { super(); } public Person(String nam

  • SpringBoot配置@Configuration注解和@bean注解

    目录 1.@Configuration注解 2.@bean注解 3.单实例 4.配置类也是容器的组件 5.直接调用配置类里面的person1()方法 6.proxyBeanMethods——代理bean的方法 1.@Configuration注解 用法:作用在类上面 作用:告诉SpringBoot这是一个配置类,相当于Spring中的xml配置文件. @Configuration //告诉SpringBoot这是一个配置类 == 配置文件 public class Config { } 2.@b

  • 基于@Bean修饰的方法参数的注入方式

    目录 @Bean修饰的方法参数的注入 Bean的四种注入方式 1.set注入 2.构造器注入 3.静态工厂注入 4.实例工厂注入 @Bean修饰的方法参数的注入 方法参数默认注入方式为Autowired,即先根据类型匹配,若有多个在根据名称进行匹配. 1:复杂类型可以通过@Qualifier(value="XXX")限定 2:对于普通类型使用@Value(XXX)指定 @PropertySource("classpath:db.properties") public

  • @Bean注解和@Configuration、@Component注解组合使用的区别

    目录 一.@Bean的"full"模式和"lite"模式 二.两种模式的差异 1."full"模式下@Bean方法互相调用 2."lite"模式下@Bean方法互相调用 三.总结 一.@Bean的"full"模式和"lite"模式 在一般常见情况下,@Bean注解在@Configuration类中声明,称之为"full"模式:当@Bean注解和@Component注解

  • Spring @bean和@component注解区别

    目录 Spring 中的一些注解 2. Autowire 和 @Resource 的区别 3. 将一个类声明为 Spring 的 bean 的注解有哪些? 4. @Configuration :配置类注解 5. @ControllerAdvice :处理全局异常利器 6. @Component, @Repository, @Service 的区别 总结 本文打算介绍几个不太容易说出其区别,或者用途的 Spring 注解,比如 @Component 与 @Bean 的比较,@ControllerA

  • @Autowired自动装配,@Bean注入@Primary,@Qualifier优先级讲解

    目录 Autowired自动装配 第一种情况 第二种情况 第三种情况 第四种情况 总结 @Autowired 取值 app.getBean() @Primary 优先 Autowired自动装配 spring利用依赖注入(DI),完成对IOC容器中的各个组件的依赖关系赋值 对同一个Dao类,既有 @Bean 注解声明,又有Autowired 自动装配,分析一下几种情况: 第一种情况 1.如果Dao类中声明了@Repository,且@ComponentScan 添加了dao扫描,则默认会创建一个

  • Spring中Bean的命名方式代码详解

    本文主要描述的是关于spring中bean的命名方式,通过简单实例向大家介绍了六种方式,具体如下. 一般情况下,在配置一个Bean时需要为其指定一个id属性作为bean的名称.id在IoC容器中必须是唯一的,此外id的命名需要满足xml对id的命名规范. 在实际情况中,id命名约束并不会给我们带来影响.但是如果用户确实希望用到一些特殊字符来对bean进行命名,那么可以使用bean的name属性来进行命名,name属性没有字符上的限制,几乎可以使用任何字符. 每个Bean可以有一个或多个id,我们

  • 详解Spring Bean的配置方式与实例化

    目录 一. Spring Bean 配置方式 配置文件开发 注解开发 二.Spring Bean实例化 环境准备 构造方法实例化Bean 静态工厂实例化Bean 实例工厂实例化Bean FactoryBean 一. Spring Bean 配置方式 由 Spring IoC 容器管理的对象称为 Bean,Bean 配置方式有两种:配置文件开发和注解开发 配置文件开发 Spring 配置文件支持两种格式:xml和properties,此教程以xml配置文件讲解. XML 配置文件的根元素是 <be

  • 关于@Bean的使用方式

    目录 一个对象 获取这个类的方法 1.AnnotationConfigApplicationContext 类获取 2.在spring自动创建的类中 3.使用 @Autowired 注解获取变量 @Bean 注解的属性解析 @Bean是一个方法级别上的注解,主要用在@Configuration注解的类里,也可以用在@Component注解的类里. 目的是创建一个类.当spring需要创建指定的一个类时会调用这个注解(@Bean)的方法. 一个对象 @Data @AllArgsConstructo

  • Spring注入Bean的一些方式总结

    通过注解注入Bean 背景 我们谈到Spring的时候一定会提到IOC容器.DI依赖注入,Spring通过将一个个类标注为Bean的方法注入到IOC容器中,达到了控制反转的效果.那么我们刚开始接触Bean的时候,一定是使用xml文件,一个一个的注入,就例如下面这样. <bean id="bean" class="beandemo.Bean" /> 我们的项目一般很大的话,就需要成千上百个Bean去使用,这样写起来就很繁琐.那么Spring就帮我们实现了一

  • Spring Bean管理注解方式代码实例

    1.使用注解的方式需要配置applicationContext.xml: <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context=&qu

  • 使用Jackson实现Map与Bean互转方式

    Jackson Map与Bean互转 在使用 java 开发中,通常需要把 Map 转成 Bean,或把 Bean 转成 Map,这就用的工具类,在此推荐使用import com.fasterxml.jackson.databind.ObjectMapper;包下的ObjectMapper类,比 JsonObject 效率高 下面就列举了几种使用方法 1.pom.xml <dependency> <groupId>com.fasterxml.jackson.core</gro

  • Spring中实例化bean的四种方式详解

    前言 在介绍Bean的实例化的方式之前,我们首先需要介绍一下什么是Bean,以及Bean的配置方式. 如果把Spring看作一个大型工厂,那么Spring容器中的Bean就是该工厂的产品.要想使用Spring工厂生产和管理Bean,就需要在配置文件中指明需要哪些Bean,以及需要使用何种方式将这些Bean装配到一起. Spring容器支持两种格式的配置文件,分别为Properties文件格式和xml文件格式,而在实际的开发当中,最常使用的额是xml文件格式,因此在如下的讲解中,我们以xml文件格

  • Spring创建Bean的6种方式详解

    前言 本文讲解了在Spring 应用中创建Bean的多种方式,包括自动创建,以及手动创建注入方式,实际开发中可以根据业务场景选择合适的方案. 方式1: 使用Spring XML方式配置,该方式用于在纯Spring 应用中,适用于简单的小应用,当应用变得复杂,将会导致XMl配置文件膨胀 ,不利于对象管理. <bean id="xxxx" class="xxxx.xxxx"/> 方式2: 使用@Component,@Service,@Controler,@R

  • 详解Spring中bean的几种注入方式

    首先,要学习Spring中的Bean的注入方式,就要先了解什么是依赖注入.依赖注入是指:让调用类对某一接口的实现类的实现类的依赖关系由第三方注入,以此来消除调用类对某一接口实现类的依赖. Spring容器中支持的依赖注入方式主要有属性注入.构造函数注入.工厂方法注入.接下来将为大家详细介绍这三种依赖注入的方式以及它们的具体配置方法. 1.属性注入 属性注入即通过setXXX( )方法注入bean的属性值或依赖对象.由于属性注入方式具有可选择性和灵活性高的特点,因此它也是实际开发中最常用的注入方式

  • spring装配bean的3种方式总结

    前言 这段时间在学习Spring,依赖注入DI和面向切面编程AOP是Spring框架最核心的部分.这次主要是总结依赖注入的bean的装配方式. 什么是依赖注入呢?也可以称为控制反转,简单的来说,一般完成稍微复杂的业务逻辑,可能需要多个类,会出现有些类要引用其他类的实例,也可以称为依赖其他类.传统的方法就是直接引用那个类对象作为自己的一个属性,但如果我们每次创建这个类的对象时,都会创建依赖的类的对象,还有如果那个类将来可能不用了,还需要到这个类去删除这个对象,那破坏了代码的复用性和导致高度耦合!

随机推荐