大白话讲Spring之@Bean注解

很多小白包括我自己在学习spring框架的时候都会被眼花缭乱的注解给晕住,所以在这里结合自己的学习及实践来出一期spring注解讲解系列。

这一期我们来讲解@Bean注解,spring框架的核心就是IOC容器,而IOC容器管理的一个对象就称为一个Bean,所以你可以将Bean理解为一件衣服而IOC就是衣橱,一般你会将新买的衣服都存在衣橱中,需要的时候就从衣橱中拿出来,这个放入的过程就是【注册】,取出的过程就是【注入】。

一般来说@Bean是作用在方法中的,这个方法必须有返回值,它是将方法的返回对象注册到IOC容器中,注意这里是返回对象进行注册。

@Bean的使用方式

一般@Bean是在配置类中使用的,如下图:

@Configuration
@ComponentScan({"com.hello","com.service"})
@Import(AppConfig.class)
public class MyConfig {

    @Bean(name = "student")
    public Student Student(){
        Student student = new Student();
        return student;
    }
}

此时如果加载配置类就可以看到这个@Bean注解被注册到IOC容器了,如下图所示,加载MyConfig.class这个配置类。

import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class Test {
    @org.junit.Test
    public void test(){
        //1.将Student的bean注册到Ioc容器
        AnnotationConfigApplicationContext ioc1 = new AnnotationConfigApplicationContext(MyConfig.class);
        //2.获取Ioc的Id
        String id = ioc1.getId();
        System.out.println("IOC的id:"+id);
        //3.从IOC容器中获取所有bean的name
        String[] beanDefinitionNames = ioc1.getBeanDefinitionNames();
        for (String beanName: beanDefinitionNames){
            System.out.println(beanName);
        }
    }
}

结果显示IOC容器中存在student

但是在使用过程中发现这样创建一个student的@bean貌似又麻烦又不方便维护还得专门写一个方法,因此在实际过程中针对pojo这样的实体类我们一般通过@component注解来标识就行,然后在配置类上扫描一下就可以【@ComponentScan】


@Component
public class Student {
}

所以上述方案也可以注入,这样似乎显的@Bean很鸡肋。其实@Bean还有一个更重要的作用就是

引入第三方@Bean这也是@Bean的主要用处,什么意思?

类似@Component , @Repository , @ Controller , @Service 这些注册Bean的注解存在局限性,只能局限作用于自己编写的类,如果是一个jar包第三方库要加入IOC容器的话,这些注解就手无缚鸡之力了。比如JDBC需要数据源Druid,但是我们无法将创建Druid的对象给注入到IOC容器中,我们总不能直接在源码上加入一些@Component吧,所以怎么办?

这时候@Bean发挥它的作用了,我们前面提到了被@Bean修饰的方法是将该方法的返回值对象作为Bean注册到IOC容器中。那么我们如果定义一个方法在方法中对数据源进行配置new DataSource()然后set上url、root、driveName、password等信息然后返回这个对象,当前一定要在方法上加上@Bean注解,那么这个配置好的数据源对象就被注册到IOC容器中了,后续JDBC配置时便可以注入这个对象,具体案例如下:

package config;

import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.*;

import javax.sql.DataSource;
@Configuration
@ComponentScan({"com.hello"})
public class MyConfig {
    @Value("${jdbc.url}")
    String url;
    @Value("${jdbc.driverClassName}")
    String driverClassName;
    @Value("${jdbc.username}")
    String username;
    @Value("${jdbc.password}")
    String password;
    @Bean
    public DataSource dataSource() {
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setUrl("jdbc:mysql://127.0.0.1:3306/lxs");
        dataSource.setDriverClassName("com.mysql.jdbc.Driver");
        dataSource.setUsername("root");
        dataSource.setPassword("123");
        return dataSource;
    }
}

此时将第三方的Bean注入了

@Bean的相关参数

name: 指定Bean的名称。默认情况下,Bean的名称是方法的名称。如果指定了这个参数,Bean将使用指定的名称进行注册。

@Bean(name = "myBean")
public MyBean createBean() {
    return new MyBean();
}

initMethoid方法和destoryMethod方法:

@Component
public class StudentTwo {
   public void init(){
       System.out.println("初始化方法");
   }
   public void destroy(){
       System.out.println("销毁方法");
   }
}

在Bean对象中定义一个init()方法和destory()方法,注册bean时指定初始化方法和销毁方法

@Configuration
public class AppConfig {

    @Bean(initMethod = "init",destroyMethod = "destroy")
    public StudentTwo getStudentTwo(){
        StudentTwo studentTwo = new StudentTwo();
        return studentTwo;
    }

}

当ioc初始化时会执行init()方法,当ioc容器关闭时会执行销毁方法。

public class Test {
    @org.junit.Test
    public void test(){
        //1.将Student的bean注册到Ioc容器
        AnnotationConfigApplicationContext ioc1 = new AnnotationConfigApplicationContext(AppConfig.class);
        //2.获取Ioc的Id
        String id = ioc1.getId();
        System.out.println("IOC的id:"+id);
        //3.从IOC容器中获取所有bean的name
        String[] beanDefinitionNames = ioc1.getBeanDefinitionNames();
        for (String beanName: beanDefinitionNames){
            System.out.println(beanName);
        }
        ioc1.close();
    }
}

运行结果如下:

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值