Spring Bean

5.什么是Spring Bean?

Spring Bean就是被Spring IOC容器实例化和管理的对象。

6.配置Bean有哪几种方式?

  1. 通过注解,@Component(@Controller@Service@Repostory)或者JavaConfig提供的@Bean注解。
  2. 通过xml,直接在xml中加上一个Bean节点,指定Bean完整的路径。<bean class="com.tuling.UserService" id="">

8.@Component和@Bean的区别是什么?

@Component底层是通过反射调用构造方法来实例化Bean对象,@Bean是标注在一个方法上面,必须返回一个对象。返回的对象就会成为一个Bean,我们可以自己控制实例化过程。通常结合配置类@Configuration一起使用。

Java反射机制允许在运行时动态获取类的元数据(如属性、方法、构造器),并直接操作对象或调用方法。通过反射,可提前编写通用逻辑(如对象创建、方法执行),以后不论哪个模块都可以直接调用,实现功能复用。例如,Spring框架中@Component注解的Bean管理,正是通过反射解析类信息并调用构造器实例化对象。

9.Spring实例化Bean有几种方式?

主要有三种,第一种是通过反射,第二种是静态工厂,第三种是实例工厂。

  1. 反射,不论是通过xml配置bean节点还是通过注解的方式配置@Component,Spring的底层都会通过反射把class里的完整类路径存放在BeanDefinition.beanClass属性中。Spring在创建Bean的时候,会根据beanClass进行反射,通过反射拿到实例。反射实际上就是调用类的构造函数,从而得到这个实例。
  2. 静态工厂方式就是给当前Bean配置一个factory-method,Spring在实例化的时候就会帮我们调用当前配置bean的factory-mothed所指的的方法,从而帮助我们实例化。
  3. 实例工厂方式就是在factory-method的基础上,再去指定一个factory-bean,Spring底层在实例化的时候就会调用指定的Bean方法。@Bean注解的底层就是采用这种factory-method+factory-bean的方式,不论是factory-method还是factory-bean都会将对应的定义信息读取到BeanDefinition中。

10. Bean的生命周期了解吗?

Bean的生命周期就是从创建到销毁的过程,主要分为四大步:

  1. 实例化
    a. 通过反射推断构造函数进行实例化
    b. 静态工厂和实例工厂进行实例化

  2. 属性赋值
    a. 在属性上添加注解,进行依赖注入,也是通过反射实现的。由于启动时不报错,调用Bean时才报错,所以可能出现循环依赖。

  3. 初始化
    a. 调用XXXAware回调方法(前提Bean是实现了Aware接口),BeanNameAwareBeanClassLoaderAwareBeanFactoryAware
    b. 如果Bean实现了AOP,需要在初始化时实现动态代理。

    动态代理是一种允许运行时创建代理对象的机制,可以在不修改原始类的情况下,为其添加额外的行为。比如日志记录、性能监控等,动态代理的核心是反射技术。

    c. 初始化之后,Bean就可以使用了。

  4. 销毁
    a. 在Spring容器关闭的时候,调用销毁的生命周期回调方法。

11.循环依赖是什么?有什么解决方案?

循环依赖是指两个或多个Bean之间相互依赖,比如在A依赖B,B又依赖A。在创建A的时候,需要先创建B,创建B的时候有需要创建A。

  1. 可以通过三级缓存来解决循环依赖,一级缓存存放完全初始化好的Bean,二级缓存存放的是提前暴露的Bean,三级缓存存放Bean的工厂对象ObjectFactory,它的getObject()方法可以提前生成提前暴露的Bean。
  2. 比如在B创建A的过程中发生了循环依赖,由于A没有初始化完成,所以在一二级缓存中肯定没有A。这是需要去三级缓存中调用getObject()方法,生成一个A的提前暴露Bean。
  3. 然后将这个ObjectFactory从三级缓存中移除,并将提前暴露对象加入到二级缓存中。B就可以将这个提前暴露对象注入到依赖,解决循环依赖的问题。

12.解释Spring支持的几种Bean的作用域?

配置Bean作用域有两种方式,第一种就是在配置文件Bean节点里的scope进行设置,第二种就是通过注解@Scope设置。

Spring框架支持五种Bean的作用域:

  1. singleton,单例Bean,Bean在每个Spring IOC容器中只有一个实例。单例是默认的Bean作用域
  2. prototype,原型Bean,一个Bean的定义可以有多个实例,每次从IOC容器中获取Bean,都会返回一个新的实例对象。
  3. request,每次http请求都会创建一个Bean,必须引入web应用才会有request。
  4. session,每次会话都会创建一个Bean,也需要依赖于web应用。
  5. application,一个全局应用共享一个对象。

13.单例Bean的优势?

单例Bean对象只创建一次,节省了内存空间,同时获取对象也更方便,提升了性能。

14.Bean线程安全吗?

不管是不是在Spring框架里,只要某个Java对象中的状态被多个线程修改,就会有线程安全的问题(和单例还有原型没用任何关系)。解决线程安全的常用手段就是加锁串行化,或者原子操作类CAS串行化,亦或者使用线程安全的集合类。

15.Spring 中的BeanFactory和FactoryBean是什么?

  1. BeanFactory是一个bean工厂类,主要负责生产和管理Bean,是IOC容器最底层的接口。
  2. FactoryBean是一个bean,在IOC容器的基础上给Bean的实现加上了一个简单工厂模式和装饰模式,是一个可以生产对象和装饰对象的工厂Bean。
### Spring Boot 中如何定义和使用 Spring Bean #### 1. 使用 `@Component` 注解定义 Bean 可以通过在类上添加 `@Component` 注解来自动注册该类作为 Spring 容器中的一个 Bean。当启动应用时,Spring 的组件扫描机制会发现并加载带有此注解的类。 ```java import org.springframework.stereotype.Component; @Component public class MyService { public void performTask() { System.out.println("Executing task..."); } } ``` 此类会被自动检测到并实例化为名为 `myService` 的 bean[^2]。 #### 2. 配置类中使用 `@Bean` 方法定义 Bean 另一种常见的方式是在配置类里声明静态工厂方法,并在其上方加上 `@Bean` 注解。这种方式可以更灵活地控制 Bean 的创建过程以及初始化参数等。 ```java import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class AppConfig { @Bean public MyRepository myRepository() { return new InMemoryMyRepository(); } private static class InMemoryMyRepository implements MyRepository { /* ... */ } } ``` 这里定义了一个名为 `myRepository` 的bean,它由 `AppConfig.myRepository()` 方法返回的对象表示. #### 3. 处理同名 Bean 覆盖的情况 如果项目中有多个地方尝试定义相同的 Bean 名称,则默认情况下会导致冲突错误。为了支持这种情况下的覆盖操作,可以在 application.properties 文件中设置属性: ```properties spring.main.allow-bean-definition-overriding=true ``` 这使得后来者能够替换掉之前已经存在的相同名字的 Bean 实例[^1].
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值