Spring注入容器-@Component和@Bean

什么是@Bean

@Bean@Component都是将Spring Bean添加到Spring Context 中

@Bean不能注释在类上,只能作用于方法。

@Bean注解告诉 Spring 这个方法将会返回一个对象,这个对象要注册为 Spring 应用上下文中的 bean。意思就是,我要获取这个 bean 的时候,Spring 要按照这种方式去获取这个 bean。

@Bean注解参数:

  • value:定义bean在IOC容器中的id属性。
  • name :定义bean在IOC容器中的id属性。
  • autowire:装配方式
    • Autowire.NO (默认设置)
    • Autowire.BY_NAME
    • Autowire.BY_TYPE
  • initMethod:指定初始化方法 相当于xml文件中 init-method
  • destroyMethod:指定销毁的方法 相当于xml文件中 destroy-method
@Configuration
@ComponentScan(basePackages = {"springIocTest/pojo"})
public class SpringIocConfig {

    @Bean(initMethod = "init", destroyMethod = "destory")
    public UserService getUserService(){
        return new UserService();
    }
}

@Bean一般结合 @Configuration 一起使用,用于配置 spring bean 到 SpringContext 中。

@Component 对比 @Bean

  • 共同点
    • 两者的目的是一样的,都是注册 bean 到 Spring 容器中。
  • 不同点
    • 作用域不同
      • @Component作用于类,@Bean作用于方法
    • 注册方式不同
      • @Component注解表明一个类会作为组件类,并告知 Spring 要为这个类创建 bean。
      • @Bean注解告诉 Spring 这个方法将会返回一个对象,这个对象要注册为 Spring 应用上下文中的 bean。通常方法体中包含了最终产生bean实例的逻辑。
    • 使用方式
      • @Component@Controller@Service@Repository)通常是通过类路径扫描来自动侦测以及自动装配到 Spring 容器中。
      • @Bean一般结合@Configuration一起使用,也可以配置在类的方法中

默认情况下,@Bean注解的方法名默认作为对象的名字,也可以用name属性定义对象的名字

使用方式

与配置类@Configuration一起

@Bean的用途更加灵活,当我们引用第三方库中的类需要装配到 Spring 容器时,则只能通过@Bean来实现。

比如,需要引入configTest.AOP.service模块的类ProductService

package configTest;
import configTest.AOP.service.ProductService;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration  //作为配置类,替代xml配置文件
@ComponentScan(basePackages = {"configTest.pojo"})
public class SpringConfig {
    @Bean
    public ProductService getProductService() {
        return new ProductService();
    }
}

程序调用:

package configTest;
import configTest.AOP.service.ProductService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class Test {
    public static void main(String[] args) {
        ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
        ProductService product = (ProductService) context.getBean("getProductService");
        System.out.println(product);
        product.doSomeService();
    }
}

运行结果:

通过context.getBean(“getProductService”)获取到ProductService类对象。

单独配置在类的方法中

在类 Stu 中配置 @Bean

package configTest.pojo;
import configTest.AOP.service.ProductService;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;

@Component
public class Stu {
    public String name;

    @Override
    public String toString() {
        return "Stu{" + "name='" + name + '\'' + '}';
    }

    @Bean
    public ProductService getProductService2() {
        return new ProductService();
    }
}

程序调用:

package configTest;
import configTest.AOP.service.ProductService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class Test {
    public static void main(String[] args) {
        ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
        ProductService product = (ProductService) context.getBean("getProductService");
        System.out.println(product);
        product.doSomeService();

        ProductService product2 = (ProductService) context.getBean("getProductService2");
        System.out.println(product2);
        product2.doSomeService();
    }
}

运行结果:

也可以配置在类方法中。

通过配置返回不同的对象

该案例只能用@Bean实现。

1、接口IUserDao,实现类UserDaoImpl1、UserDaoImpl2:

IUserDao:
public interface IUserDao {
    public void add();
}

UserDaoImpl1:
@Component
public class UserDaoImpl1 implements IUserDao {

    @Override
    public void add() {
        System.out.println("UserDaoImpl1 add");
    }
}

UserDaoImpl2:
@Component
public class UserDaoImpl2 implements IUserDao {

    @Override
    public void add() {
        System.out.println("UserDaoImpl2 add");
    }
}

2、配置类SpringConfig:

package springIocTest;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;

@Configuration
@ComponentScan(basePackages = {"springIocTest"})
@PropertySource(value = {"classpath:springIocTest/list.properties"}) //该句不起作用,不知道为什么....,只能通过配置文件加载。
public class SpringConfig {
    @Value("${param}")
    public String param;

    @Bean
    public IUserDao getUserDao() {
        System.out.println(param);
        switch (param)  {
            case  "1":
                return new UserDaoImpl1();
            case  "2":
                return new UserDaoImpl2();
        }
        return null;
    }
}

注入属性param,通过配置文件list.properties动态赋值,然后通过@Bean返回不同类型对象。

配置文件list.properties:

param=1

配置文件applicationContext.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
                          http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

    <!--引入外部属性文件-->
    <context:property-placeholder location="classpath:springIocTest/list.properties"/>
    <context:component-scan base-package="springIocTest"/>
</beans>

程序调用:

public class SpringTest {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("springIocTest/applicationContext.xml");

        IUserDao userDao = context.getBean("getUserDao", IUserDao.class);
        userDao.add();
    }
}

运行结果:

如果list.properties中param=2,则打印 2 UserDaoImpl2 add

以上这个例子是无法用@Component以及其具体实现注解(@Controller、@Service、@Repository)来实现的。

总结

@Component@Bean都是用来注册 Bean 并装配到 Spring 容器中,但是@Bean@Component的自定义性更强。可以实现一些@Component实现不了的自定义加载类。

  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不会叫的狼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值