IOC - bean 定义

Bean 定义属性

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!-- bean 的所有属性 -->
    <bean id = "" class = "" name = "" scope = "" lazy-init = "" 
    	init-method = "" destroy-method = "" autowire ="" depends-on = "" 
    	factory-bean = "" factory-method = "" primary = "" profile = "" parent = "">

	</bean>
</beans>

属性解释

XML 属性 作用 对应 @Compenent 等注解配置 对应 @Bean 注解配置
id Bean的唯一标识符 value 属性 value 属性
class Bean的实现类 标注 @Component 等注解的类 Class @Bean 返回对象的类 Class
name Bean的别名 name 属性 name 属性
scope Bean的作用域,可选值如下:
singleton:每次从容器种获取 Bean 时返回同一个实例
prototype:每次从容器获取 Bean 时返回一个新的实例
request:在 web 应用中,每个 HTTP 请求返回一个新的实例
session:在 web 应用中,每个 HTTP 会话返回一个新的实例
application:在 web 应用中,整个应用上下文中共享一个 Bean 实例
@Scope 注解 @Scope 注解
lazy-init 是否懒加载
true:应用懒加载,从容器获取 bean 时才创建
false:不应用懒加载,容器创建时就创建 bean
@Lazy 注解 @Lazy 注解
init-method 初始化方法 @PostConstruct 注解 initMethod 属性
destroy-method 销毁方法 @PreDestroy 注解 destroyMethod 属性
autowire 自动装配方式(该 bean 的属性装配方式)
no:不装配
byName:根据名称装配
byType:根据类型装配
多个 @Autowired 注解
默认按照类型匹配
多个 @Autowired 注解
默认按照类型匹配
depends-on 依赖的其他 bean,让依赖的 bean 先加载,然后加载当前 bean @DependsOn 注解 @DependsOn 注解
factory-bean 工厂 bean 的名称
factory-method 工厂 bean 的方法
primary 优先使用的 Bean @Primary 注解 @Primary 注解
profile Bean的使用环境 @Profile 注解
parent 父类 Bean 通过继承来实现 通过继承来实现

作用域

  1. 如果是 web 应用,作用域增加三个:request、session、application
  2. 如果是 web 应用,singleton 和 application 就没区别了
  3. 如果 bean 作用域是 request
    • 创建 IOC 容器时不会创建这个 bean,有请求来才开始创建,请求结束就销毁
    • 在同一个请求中,获取的 bean 是同一个。也就是在 controller 和 service 中获取的 bean 是同一个
    • Spring 通过 RequestContextHolder 和 ThreadLocal 来判断请求是否是同一个
  4. 如果 bean 作用域是 session
    • 创建 IOC 容器时不会创建这个 bean,会话开始才创建,会话结束就销毁
    • 在同一个会话中获取的 bean 是同一个。如果请求后把浏览器的 cookie 清除了或者关闭浏览器,JSESSIONID 也就没了,再次请求会被视为是新的会话,就会创建新的 bean
    • Spring 根据 HttpServletRequest 内部的 Session 来判断是否是同一个会话,内部会根据 JSESSIONID 来判断

@Bean 配置作用域

@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 配置作用域

// 设置作用域为 request
@Component
@Scope("request")  // 等同于 @RequestScope
public class MyRequestScopedBean {
	...
}

懒加载

bean 定义的时候为懒加载(使用 @Lazy 标注):注入 bean 的时候可以使用 @Lazy(false) 让 bean 不懒加载

// bean 定义:bean 配置为懒加载
@Bean("person")
@Lazy
public Person person() {
    Person person = new Person();
    person.setAge(18);
    person.setName("Marry");
    return person;
}

// bean 注入:修改 bean 为不懒加载,是有效的
@Component
public class BeanConfiguration {

    @Autowired
    @Lazy(false) // person 不会懒加载(IOC 容器启动单例池会有 person 这个 bean)
    private Person person;

}

bean 定义的时候为非懒加载(不使用 @Lazy@Lazy(false) 显示指定):注入 bean 的时候不能修改 bean 懒加载行为

// bean 定义:bean 配置不懒加载
@Bean("person")
@Lazy(false) // 或者不使用 @Lazy 注解,默认就是不懒加载
public Person person() {
    Person person = new Person();
    person.setAge(18);
    person.setName("Marry");
    return person;
}

// bean 注入:修改 bean 为懒加载,是无效的
@Component
public class BeanConfiguration {

    @Autowired
    @Lazy // 因为定义的时候配置的是懒加载,这里修改就没效果了
    private Person person;

}

初始化和销毁方法

  • 当使用 @Component 注解时,通过给方法标注 PostConstructPreDestroy 实现

    当 bean 创建好后会调用 @PostConstruct 指定的方法,当 bean 销毁后会调用 @PreDestroy 指定的方法

    import org.springframework.stereotype.Component;
    import javax.annotation.PostConstruct;
    
    @Data
    @Component
    public class MyService {
    
        private String message;
    
        // 初始化方法
        @PostConstruct
        public void init() {
            message = "Hello, World!";
        }
        
        // 销毁方法
        @PreDestroy
        public void init() {
             System.out.println("MyService is destroyed.");
        }
    
    }
    
  • 当使用 @Bean 注解时,通过指定 initMethoddestroyMethod 属性实现

    // 配置类
    @Configuration
    public class AppConfig {
    
        // myBean 创建完成后,调用 init 方法;bean 销毁时调用 destory 方法。方法是 MyBean 定义的
        @Bean(initMethod = "init", destroyMethod = "destory")
        public MyBean myBean() {
            return new MyBean();
        }
    }
    
    // MyBean 类
    public class MyBean {
        
        // 初始化方法
        public void init() {
            System.out.println("MyBean is initialized.");
        }
        
        // 销毁方法
        public void destory() {
            System.out.println("MyBean is destroyed.");
        }
    }
    
    

自动装配

xml 中使用 autowire 配置该 bean 的属性注入方式,比如 a 有个属性是 b,给 a 设置 autowire = "no" b 将会是 null

如果是 java 注解方式,一般属性注入用的多,每个属性上都要标注 @Autowired 注解,默认是根据类型到 IOC 中查找合适的 bean 完成注入

指定 bean 创建顺序

xml 方式

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
                           http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!-- 数据源 bean -->
    <bean id="dataSource" class="com.example.DataSource" />

    <!-- 服务 bean,依赖于 dataSource -->
    <bean id="myService" class="com.example.MyService" depends-on="dataSource" />

</beans>

java 注解方式

// @Component 注解
@Component
@DependsOn({"dataSource", "anotherBean"})
public class MyService {

    @Autowired
    private DataSource dataSource;

    @Autowired
    private AnotherBean anotherBean;

    public MyService() {
        // Constructor logic
    }

}


// @Bean 注解
@Configuration
public class AppConfig {

    @Bean
    public DataSource dataSource() {
        return new DataSource();
    }

    @Bean
    @DependsOn("dataSource")
    public MyService myService() {
        return new MyService();
    }
}

工厂 bean

需要实现 FactoryBean<T> 接口

  1. 工厂模式创建 bean,使用工厂对象的非静态方法创建(因为是非静态方法,所以要先有对象)

    factory-bean 指明是哪个对象,也是一个 bean,bean 工厂

    factory-method 指明是哪个方法,反射调用 bean 工厂的这个方法来创建

    <!-- 工厂 bean -->
    <bean id="myFactoryBean" class="com.cyrus.MyFactoryBean" />
    
    <!-- 反射调用 MyFactoryBean.getBean 创建 bean  -->
    <bean id="myBean" factory-bean="myFactoryBean" factory-method="getBean" />
    
  2. 工厂模式创建 bean,使用工厂对象的静态方法创建(调用静态方法,所以不需要有对象,只需要类和方法就行了)

    class 是工厂对象的类型,不是 bean 的类型

    factory-method

    <bean id="myBean" 
          class="com.cyrus.MyFactoryBean" 
          factory-method="getBean2" />
    

根据环境创建对应 bean

application.yml 配置文件激活 dev 环境

spring.profiles.active=dev

根据不同环境创建对应的 bean

@Configuration
public class AppConfig {

    // 这个 bean 会创建
    @Bean
    @Profile("dev")
    public MyService devMyService() {
        return new MyServiceImplDev();
    }

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

posted @   CyrusHuang  阅读(14)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
点击右上角即可分享
微信分享提示