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 | 通过继承来实现 | 通过继承来实现 |
作用域
- 如果是 web 应用,作用域增加三个:request、session、application
- 如果是 web 应用,singleton 和 application 就没区别了
- 如果 bean 作用域是 request
- 创建 IOC 容器时不会创建这个 bean,有请求来才开始创建,请求结束就销毁
- 在同一个请求中,获取的 bean 是同一个。也就是在 controller 和 service 中获取的 bean 是同一个
- Spring 通过 RequestContextHolder 和 ThreadLocal 来判断请求是否是同一个
- 如果 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
注解时,通过给方法标注PostConstruct
和PreDestroy
实现当 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 注解时,通过指定
initMethod
和destroyMethod
属性实现// 配置类 @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>
接口
-
工厂模式创建 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" />
-
工厂模式创建 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();
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具