SpringBean学习总结

SpringBean

概述

SpringBean学习总结_第1张图片

BeanDefinition:主要用来描述Bean的定义

BeanDefinitionRegistry:提供了向IOC容器手动注册BeanDefinition的方法

BeanFactory:Spring框架最核心的接口

  • 提供IOC的配置机制
  • 包含Bean的各种定义,便于实例化Bean
  • 建立Bean之间的依赖关系
  • Bean生命周期的控制

BeanFactory与ApplicationContext的比较

  • BeanFactory是Spring框架的基础设施,面向Spring
  • ApplicationContext面向使用Spring框架的开发者

ApplicationContext的功能(继承多个接口)

  • BeanFactory:能够管理、装配Bean
  • ResourcePatternResolver:能够加载资源文件
  • MessageSource:能够实现国际化等功能
  • ApplicationEvenPublisher:能够注册监听器、实现监听机制

装配Bean
1、通过@Configuration+@Bean,生成单独的配置类来对Bean进行配置,注入到容器
2、通过@Component和@Value来对实体类进行配置,直接注入
之后可以通过ApplicationContext的getBean方法加载Bean

配置了@Component的类可以通过@Autowired实现依赖注入

refresh

getBean方法的代码逻辑

  • 转换beanName
  • 从缓存中加载实例
  • 实例化Bean
  • 检测parentBeanFactory
  • 初始化以来的Bean
  • 创建Bean

Spring Bean的作用域

  • singleton:Spring的默认作用域,容器里拥有唯一的Bean实例
  • prototype:针对每个getBean请求,容器都会创建一个Bean实例
  • request:会为每个Http请求创建一个Bean实例
  • session:会为每个session创建一个Bean实例
  • globalSession:会为每个全局Http Session创建一个Bean实例,该作用域进队Portlet有效

Spring bean的生命周期

  • SpringBean学习总结_第2张图片
  • Bean 容器找到配置文件中 Spring Bean 的定义。
  • Bean 容器利用 Java Reflection API 创建一个Bean的实例。
  • 如果涉及到一些属性值 利用 set()方法设置一些属性值。
  • 如果 Bean 实现了 BeanNameAware 接口,调用 setBeanName()方法,传入Bean的名字。
  • 如果 Bean 实现了 BeanClassLoaderAware 接口,调用 setBeanClassLoader()方法,传入 ClassLoader对象的实例。
  • 与上面的类似,如果实现了其他 *.Aware接口,就调用相应的方法。
  • 如果有和加载这个 Bean 的 Spring 容器相关的 BeanPostProcessor 对象,执行postProcessBeforeInitialization() 方法
  • 如果Bean实现了InitializingBean接口,执行afterPropertiesSet()方法。
  • 如果 Bean 在配置文件中的定义包含 init-method 属性,执行指定的方法。
  • 当要销毁 Bean 的时候,如果 Bean 实现了 DisposableBean 接口,执行 destroy() 方法。
  • 当要销毁 Bean 的时候,如果 Bean 在配置文件中的定义包含 destroy-method 属性,执行指定的方法。

Spring 中的单例 bean 的线程安全问题了解吗?

大部分时候我们并没有在系统中使用多线程,所以很少有人会关注这个问题。单例 bean 存在线程问题,主要是因为当多个线程操作同一个对象的时候,对这个对象的非静态成员变量的写操作会存在线程安全问题。

常见的有两种解决办法:

在Bean对象中尽量避免定义可变的成员变量(不太现实)。

在类中定义一个ThreadLocal成员变量,将需要的可变成员变量保存在 ThreadLocal 中(推荐的一种方式)。

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

  1. 作用对象不同: @Component 注解作用于类,而@Bean注解作用于方法。
  2. @Component通常是通过类路径扫描来自动侦测以及自动装配到Spring容器中(我们可以使用 @ComponentScan 注解定义要扫描的路径从中找出标识了需要装配的类自动装配到 Spring 的 bean 容器中)。@Bean 注解通常是我们在标有该注解的方法中定义产生这个 bean,@Bean告诉了Spring这是某个类的示例,当我需要用它的时候还给我。
  3. @Bean 注解比 Component 注解的自定义性更强,而且很多地方我们只能通过 @Bean 注解来注册bean。比如当我们引用第三方库中的类需要装配到 Spring容器时,则只能通过 @Bean来实现。

@Bean注解使用示例:

@Configuration
public class AppConfig {
    @Bean
    public TransferService transferService() {
        return new TransferServiceImpl();
    }

}

上面的代码相当于下面的 xml 配置

<beans>
    <bean id="transferService" class="com.acme.TransferServiceImpl"/>
beans>

下面这个例子是通过 @Component 无法实现的。

@Bean
public OneService getService(status) {
    case (status)  {
        when 1:
                return new serviceImpl1();
        when 2:
                return new serviceImpl2();
        when 3:
                return new serviceImpl3();
    }
}

将一个类声明为Spring的 bean 的注解有哪些?

我们一般使用 @Autowired 注解自动装配 bean,要想把类标识成可用于 @Autowired 注解自动装配的 bean 的类,采用以下注解可实现:

  • @Component :通用的注解,可标注任意类为 Spring 组件。如果一个Bean不知道属于哪个层,可以使用@Component 注解标注。
  • @Repository : 对应持久层即 Dao 层,主要用于数据库相关操作。
  • @Service : 对应服务层,主要涉及一些复杂的逻辑,需要用到 Dao层。
  • @Controller : 对应 Spring MVC 控制层,主要用户接受用户请求并调用 Service 层返回数据给前端页面。

你可能感兴趣的:(Java学习,spring,java)