Spring 杂记

警告
本文最后更新于 2021-11-01,文中内容可能已过时。

9.1 Spring框架设计

9.2 AOP 详解

9.3 Bean 核心原理

9.4 XML 配置原理

10.1 Spring Boot 核心原理

10.2 ORM-Hibernate/MyBatis

10.3 Spring 集成 ORM/JPA


容器接口与实现

BeanFactory

Spring 的核心容器,实际上控制反转、基本的依赖注入、直至 Bean 的生命周期的各种功能,都由它的实现类提供。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
@SpringBootApplication
public class DemoApplication {
    public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
        ConfigurableApplicationContext context = SpringApplication.run(DemoApplication.class, args);
        // 单例存储在 singletonObjects
        Field singletonObjects = DefaultSingletonBeanRegistry.class.getDeclaredField("singletonObjects");
        singletonObjects.setAccessible(true);
        ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
        Map<String, Object> map = (Map<String, Object>) singletonObjects.get(beanFactory);
        map.forEach((k, v) -> {
            System.out.println("beanName:" + k + ",bean:" + v);
        });
    }
}

将常用后处理器添加到beanFactory

AnnotationConfigUtils.registerAnnotationConfigProcessors(beanFactory);

  1. beanFactory 后处理器
  • org.springframework.context.annotation.internalConfigurationAnnotationProcessor:解析@Configuration、@Bean

    • ConfigurationClassPostProcessor.class 可以解析 @ComponentScan @Bean @Import @ImportResource
    • MapperScannnerConfigurer.class 可以解析 @MapperScanner
1
2
3
beanFactory.getBeansOfType(BeanFactoryPostProcessor.class).values().forEach(beanFactoryPostProcessor -> {
            beanFactoryPostProcessor.postProcessBeanFactory(beanFactory);
        });
  1. bean 后处理器
  • org.springframework.context.annotation.internalAutowiredAnnotationProcessor:在依赖注入阶段,解析@Autowired

    • 如果是 GenericApplicationContext,还需要 context.getDefaultListableBeanFactory().setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver()) 才能解析 @Value
  • org.springframework.context.annotation.internalCommonAnnotationProcessor:解析@Resource(依赖注入阶段)、@PostConstruct(实例化后,即初始化前)、@PreDestroy(销毁前)

  • org.springframework.context.event.internalEventListenerProcessor

  • org.springframework.context.event.internalEventListenerFactory

beanFactory.getBeansOfType(BeanPostProcessor.class).values().forEach(beanFactory::addBeanPostProcessor);

  • 另外,ConfigurationPropertiesBindingPostProcessor 用于解析 @ConfigurationProperties

单例对象默认在使用时才初始化,若要预先初始化单例对象:

beanFactory.preInstantiateSingletons();

综上,beanFactory不会主动做以下事情:

  1. 不会主动调用 BeanFactory 后处理器

  2. 不会主动添加 Bean 后处理器

  3. 不会主动初始化单例

  4. 不会解析 beanFactory、${}、#{}

    注:beanFactory.addEmbeddedValueResolver(new StandardEnvironment()::resolvePlaceholders) 是 ${} 的解析器

Q:同时添加 @Autowired 和@Resource注解?

Autowired默认按照类型匹配(通过beanFactory.doResolveDependency(…)方法),

有相同类型时再按照名称匹配,Resource默认按照名称匹配。

internalAutowiredAnnotationProcessor默认优先级更高,所以Autowired生效,可以通过比较器来改变优先级(order越小优先级越高)。

ApplicationContext

继承了 BeanFactory,进行了扩展。

  • MessageSource:国际化
  • ResourcePatternResolver:资源通配符
  • ApplicationEventPublisher:事件发布器(用于解耦)
  • EnvironmentCapable:环境变量、配置信息

DispatcherServlet 称为前控制器,所有请求都先通过它。

Aware 接口

是 spring 的内置功能

bean初始化优先级:

  1. @PostConstruct
  2. Aware
  3. implements InitializingBean 重写方法
  4. @Bean(initMethod = “”)

bean销毁优先级:

  1. @PreDestroy
  2. Aware
  3. implements DisposableBean 重写方法
  4. @Bean(destroyMethod = “”)

Scope

  1. singleton 单例:Q:单例中注入多例,多例都是同一个对象,需要推迟其他 scope bean 的获取(2种代理,2种非代理)

    1. 在注入目标前面加 @Lazy 生成代理对象(推荐)
    2. 在被注入类上添加 @Scope(value=“prototype”,proxyMode = ScopedProxyMode.TARGET_CLASS) 生成代理对象
    3. 声明 ObjectFactory<>,通过getObject() 来实现
    4. 注入 ApplicationContext,通过 context.getBean(Xxx.class)
  2. prototype 原型

  3. request 请求

  4. session 会话:不同浏览器,不同会话

  5. application 应用程序

Q:jdk>=9时,反射调用 jdk 中方法报 IllegalAccessException?

A1:重写toString()方法,不让它调用 jdk 中的方法

A2:添加参数–add-opens java.base/java.lang=ALL-UNNAMED

0%