bean 注册细节

bean 名称

@Component(value = "person") // 指定名称为 person,默认也是类名第一个字母小写
public class Person implements H {}

// @Bean 方式配置还可以指定 name。name 是别名,value 才是名称
@Bean(name = "xx", value = "yy")
public User user() {
    return new User();
}

名称是全局唯一的,如果名称重复,不会覆盖前面创建的,而是舍弃后面的,只保留前面创建的

指定顺序

创建顺序:两种方式 @AutoConfigureAfter 用于底层自动配置,一般会配合 @Condition 使用

// 如果指定的 bean 不存在,启动时会报错
@Configuration
@DependsOn("person") // 让 person 先创建,指定 bean 的名称
public class User implements  H{
    public User() {
        System.out.println("User");
    }
}

// 如果指定的 bean 不存在,启动时不会报错
@AutoConfigureAfter(User.class) // 让 User 类型的 bean 先创建,指定的是类型
@Configuration
public class Person implements H {
    public Person() {
        System.out.println("Person");
    }
}

使用顺序:当某种类型的 bean 有多个,要自动注入这一批 bean 时,可以确定注入的顺序(不是创建顺序

@Component
@Order(1)
public class Person implements H { }

@Component
@Order(90)
public class User implements  H{ }

@Resource
private List<H> h; // 第一个是 Person,然后是 User

都可以配合 @Component@Configuration@Bean 等使用

懒加载

默认情况下 Spring 创建容器时会创建所有的 Bean,如果配置 Bean 为懒加载,不会再创建容器时创建 Bean,而是等用到这个 Bean 的时候再创建

@Autowired
private Person person; // 自动注入的时候,才创建 bean

User user = ioc.getBean("user", User.class); // 手动通过容器获取 bean 时,才创建 bean

单个 bean 配置为懒加载:使用 @Lazy 实现

@Component
@Lazy // 使用这个注解就行了
public class Person implements H { }

配置所有的 bean 为懒加载:通过配置文件实现

spring.main.lazy-initialization = true

作用域

通过 @Scope 指定,候选项如下:

singleton:每次从容器种获取 Bean 时返回同一个实例。默认行为

prototype:每次从容器获取 Bean 时返回一个新的实例

request:在 web 应用中,每个 HTTP 请求返回一个新的实例(通过 RequestContextHolder 和 ThreadLocal 来判断)

session:在 web 应用中,每个 HTTP 会话返回一个新的实例(根据 HttpServletRequest 内部的 Session 来判断,会使用 JSESSIONID)

application:在 web 应用中,整个应用上下文中共享一个 Bean 实例(如果 web 环境下 applicationsingleton 是一样了)

@Configuration
public class AppConfig {
 
    // 默认是 Singleton 作用域
    @Bean
    public MySingletonBean mySingletonBean() {
        return new MySingletonBean();
    }
 
    // Prototype 作用域
    @Bean
    @Scope("prototype")
    public MyPrototypeBean myPrototypeBean() {
        return new MyPrototypeBean();
    }
 
    // Request 作用域,仅在 web 应用中有效
    @Bean
    @Scope("request")  // 等同于注解 @RequestScope
    public MyRequestBean myRequestBean() {
        return new MyRequestBean();
    }
 
    // Session 作用域,仅在 web 应用中有效
    @Bean
    @Scope("session")  // 等同于注解 @SessionScope
    public MySessionBean mySessionBean() {
        return new MySessionBean();
    }
}

// @Component 等注解也可以使用
@Component
@Scope("request")  // 等同于 @RequestScope
public class MyRequestScopedBean {
	...
}

感知 profile

# 激活 dev 环境
spring.profiles.active=dev

对应不同环境创建 bean

@Configuration
public class AppConfig {
    
    @Bean
    @Profile("dev") // 这个 bean 会创建
    public MyService devMyService() {
        return new MyServiceImplDev();
    }
 
    @Bean
    @Profile("prod") // 这个 bean 不会创建
    public MyService prodMyService() {
        return new MyServiceImplProd();
    }
}

生命周期

初始化、销毁、bean前置后置处理器、bean工厂前置后置处理器,看这里 Spring 声明周期

posted @ 2024-06-29 18:05  CyrusHuang  阅读(58)  评论(0)    收藏  举报