美好的一天,哈伯。
今天,我决定向您介绍一系列文章的翻译,以准备进行Spring Professional认证 。
这篇翻译只是第一篇文章,如果涉及到读者,我将继续发表翻译。
我为什么要这样做,因为已经有很多专门材料?- 通常,其中的信息不是结构化,未收集或不相关的
- 年轻的开发人员可能不会英语。 此循环不仅可以用于认证,还可以用于材料的自我训练/重复。
- 这些材料可以用来准备面试,因为 它们以问题和答案的形式排列。
- 一个重要的也是最重要的优点是,此QA由正式的Pivotal 研究指南中的问题组成。

我将列出作者从中获取资料的来源清单- 春季5种设计模式
- 春季行动第四版
- Spring Security-第三版
- Ivan Krizsan详细介绍了Core Spring 5认证
- Spring文档和Spring API javadocs
因此,让我们开始吧。
什么是依赖项注入(DI)及其好处?依赖注入是一种特殊的模式,可以减少Spring组件之间的通信。 因此,在应用DI时,您的代码将变得更简洁,更简单,也更易于理解和测试。
根据DI模式,将为依赖项创建的对象转移到工厂或交给第三方。 这意味着我们可以专注于使用这些对象而不是创建它们。
DI的好处- 减少应用程序各部分之间的通信
- 改进测试
- 增强型应用架构
- 减少样板代码
- 标准化应用程序开发
为什么建议使用接口来创建Spring Bean?- 改进了测试。 在测试中,可以用实现Bean接口的特殊对象(模拟或存根)替换Bean。
- 允许您使用JDK中的动态代理机制(例如,通过Spring Data创建存储库时)
- 允许您隐藏实施
什么是应用程序上下文?在Spring框架中, org.springframework.factory.BeanFactory
接口提供了一个org.springframework.factory.BeanFactory
工厂,它同时是一个IoC应用程序容器。 Bean管理基于配置(java或xml)。
org.springframework.context.ApplicationContext
接口是Bean工厂的包装,提供了一些附加功能,例如AOP,事务,安全性,i18n等。
什么是容器,容器的生命周期是什么?Spring Framework的基础是一个容器,我们的对象“活”在该容器中。
容器通常根据其配置创建许多对象,并管理从创建对象到销毁对象的生命周期。
容器是实现ApplicationContext接口的对象。
容器生命周期- 该容器在应用程序启动时创建。
- 容器读取配置数据
- 箱的描述是根据配置数据创建的
- BeanFactoryPostProcessors处理Bean描述
- 容器使用其描述创建bean
- Bean被初始化-属性值和依赖项被嵌入到Bean中
- BeanPostProcessor启动回调方法
- 该应用程序已启动并正在运行
- 初始化应用程序关闭
- 集装箱关闭
- 调用回调方法
如何创建ApplicationContext的实例?Spring提供了几种上下文变化。
ApplicationContext接口有几种基本实现:
- FileSystemXmlApplicationContext
- ClassPathXmlApplicationContext
- AnnotationConfigApplicationContext
- XmlWebApplicationContext
- AnnotationConfigWebApplicationContext
创建上下文的示例:
ApplicationContext ctx = new FileSystemXmlApplicationContext( "c:/bean_properties.xml"); ApplicationContext ctx = new AnnotationConfigApplicationContext( "com.springdemoapp.JavaConfig.class");
您能否描述容器中bean的生命周期?- 加载箱描述,创建一个依赖图(在bean之间)
- 创建并
BeanFactoryPostProcessors
- 创建豆
- Spring将值和依赖项注入到bean属性中
- 如果bean从NameBeanAware接口实现
setBeanName()
方法,则将bean ID传递给该方法。 - 如果bean实现了BeanFactoryAware,则Spring通过
setBeanFactory()
从此接口建立对bean工厂的引用。 - 如果bean实现了ApplicationContextAware接口,则Spring通过
setApplicationContext()
建立对ApplicationContext的引用。 BeanPostProcessor
是一个特殊的接口(在下面有关于它的信息),Spring允许垃圾箱实现此接口。 通过实现postProcessBeforeInitialization()
方法,可以在初始化bean(bean)之前更改bean的实例(设置属性等)。- 如果定义了回调方法,则Spring会调用它们。 例如,这是一个
@PostConstruct
或@Bean
注释中的initMethod
方法注释的方法。 - Bean现在可以使用了。 可以使用
ApplicationContext#getBean()
方法获得它。 - 在关闭上下文(ApplicationContext中的
close()
方法)之后,将销毁该Bean。 - 如果bean具有
@PreDestroy
注释的@PreDestroy
,则此方法将在销毁之前调用。 如果bean实现了DisposibleBean,则Spring将调用destroy()
方法清除资源或杀死应用程序中的进程。 如果destroyMethod
定义了@Bean
方法,则也将调用它。

如何在集成测试中获取ApplicationContext?如果使用的是JUnit 5,则需要指定2个注释:
- @ExtendWith(TestClass.class)-用于指示测试类
- @ContextConfoguration(类= JavaConfig.class)-加载Java / xml配置以在测试中创建上下文
您可以使用@SpringJUnitConfig
批注,该批注将这两个批注结合在一起。
您可以使用@SpringJUnitWebConfig
批注来测试Web层。
如何在应用程序中关闭上下文?如果这不是Web应用程序,则有两种方法:
- 使用
registerShutdownHook()
方法调用注册shutdown-hook,它也在AbstractApplicationContext类中实现。 这是首选方法。 - 您可以从AbstractApplicationContext类调用
close()
方法。
在Spring Boot应用程序中:
什么是Java配置? 如何使用?要创建具有基于Java代码的配置的类,您需要使用注释它
@Configuration
。
此类将包含用于在容器中创建bean的工厂方法。
这些方法应使用@Bean
注释进行注释。
一个例子:
@Configuration public class DSConfig { @Bean public DataSource dataSource() { return DataSourceBuilder .create() .username("") .password("") .url("") .driverClassName("") .build(); } }
此类将DataSource类的实例放置在容器中。 以后可以在访问数据库时使用它。
DI使用注释,类扫描组件扫描-Spring自动检测将在容器中的bean。 这些是带有注释定型的箱。
但是,默认情况下不启用组件扫描。
要启用扫描,请使用注释@ComponentScanning
注释@ Configuration类。 Spring将自动扫描包含此类及其所有子包的包。
您可以指定其他要扫描的包,甚至是类:
自动装配-扫描或将垃圾箱放入容器时,Spring会自动注入依赖项。
依赖注入使用@Autowire
批注。
什么是刻板印象(注释-刻板印象)?刻板印象是表示特殊功能的注释。
所有@Component
型都包含@Component
批注。
bin范围是什么? 他们的默认可见性是什么?范围-范围。 有2个默认范围。
Web应用程序中的4个作用域。
使用@Bean
方法上的@Scope
注释指示范围。
各种作用域和多线程有何关系?原型范围不是线程安全的,因为 它不能保证仅在1个线程中调用同一实例。
另一方面,Singleton Scope是线程安全的。
如何创建豆:立即还是懒惰? 如何改变这种行为?通常在扫描后立即创建单例豆。
原型bean通常仅在请求时创建。
您可以使用@Lazy
批注指示如何初始化。
它放在@Bean方法,@ Configuration类或@Component类上。
根据注释所接受的参数(是或否),初始化将是延迟的或立即进行。 默认情况下(即未指定参数),使用true。
如果将具有一个合并范围的合并箱嵌入另一个具有合并范围的合并箱,会发生什么情况?Singleton bean可以嵌入任何其他bean中。
只有prototype
或singleton
可以嵌入在singleton
。
如果实现原型,则将为每个单例创建一个唯一的原型。
原型可以是任何bean的依赖项。
您只能实现单例或原型。
什么是BeanFactoryPostProcessor?何时使用?BeanFactoryPostProcessor
在创建垃圾箱之前先处理垃圾箱描述或配置元数据。- Spring提供了几个有用的
BeanFactoryPostProcessor
实现,例如,读取属性文件并从中获取BeanFactoryPostProcessor
属性。 - 您可以编写自己的BFPP实现。
为什么需要静态@Bean方法?为了使用自定义BFPP。 您可以覆盖从图元文件获取数据的机制。
@Bean public static PropertySourcesPlaceholderConfigurer pspc() {
描述@Bean批注的属性destroyMethod
指向回调方法。 该方法在垃圾箱中。initMethod
指向回调方法。 该方法在垃圾箱中。name
-Bean的名称。 默认情况下,bean名称是方法名称。value
-名称的别名()
什么是回调方法以及如何使用它们?创建此类方法有3个选项:
@PreDestroy
和@PostConstruct
批注destroyMethod
批注中的 initMethod
和destroyMethod
指向Bean类中的方法InitializingBean#afterPropertiesSet()
和DisposableBean#destroy()
。 要覆盖这些方法,您需要实现相应的接口。

如何使用@Autowire注释,这两种方法有什么区别?以下是可以在您的应用程序中使用的DI的类型:
通过构造函数进行DI被认为是最好的方法,因为 对他来说,不需要使用反射,并且他也没有二传手的直接投资的缺点。
不建议通过字段进行DI,因为 为此,使用反射会降低生产率。
通过构造函数进行DI可能导致循环依赖 。 为了避免这种情况,可以通过设置器使用bean或DI的惰性初始化。
描述@Autowired注解的行为- 容器确定要嵌入的对象的类型。
- 容器在上下文(也就是容器)中搜索与所需类型匹配的bean
- 如果有多个候选者,并且其中一个标记为
@Primary
,则将其实现 - 如果使用
@Autowire
+ Qualifier
批注,则容器将使用@Qualifier
的信息来确定要部署的组件 - 否则,容器将尝试根据其名称或ID注入组件。
- 如果所有方法均无效,则将引发异常
容器使用AutowiredAnnotationBeanPostProcessor处理DI。 在这方面,注释不能在任何BeanFactoryPP或BeanPP中使用。
如果注入的对象是具有泛型的数组,集合或映射,则Spring将在该数组(或其他数据结构)中嵌入所有类型的bean。 对于map,键将是Bean名称。
如何使用@Qualifier补充@Autowired?Spring提供了Qualifier注释来克服DI模糊性问题。
@Bean @Qualifier("SomeClass1") public SomeClass getField() {...}
如果容器具有几个相同类型的容器(SomeClass),则容器将完全实现该容器,在@Bean方法上方有一个合适的限定符。 您也不能在方法上放置限定符,但可以使用Bean名称作为限定符参数。
可以通过Bean批注参数指定Bean名称,默认情况下,这是工厂方法的名称。
Spring可以创建什么代理对象和什么类型的代理对象?代理是一个特殊的对象,它具有与bean相同的公共方法,但是具有附加的功能。
两种类型的代理:
- JDK-proxy-动态代理。 API内置在JDK中。 需要一个接口
- CGLib代理-未内置在JDK中。 当对象的接口不可用时使用。
代理对象的优点:
- 允许添加额外的内容。 逻辑-事务管理,安全性,日志记录
- 将一些代码(记录等)与主逻辑分开
单例bean如何实现?如果容器中没有bean实例,则调用@ Bean方法。 如果有一个bean实例,则返回已经创建的bean。
什么是个人资料? 他们使用的原因是什么?使用Java配置时,可以使用@Profile
批注。
它允许您根据指定的配置文件对Spring使用不同的设置。
可以将其放在@Configuration和Component类以及Bean方法上。
Profile("!test")
@Bean("dataSource") @Profile("production") public DataSource jndiDataSource() {...} @Bean("dataSource") @Profile("development") public DataSource standaloneDataSource() {...}
如何在Spring的属性中嵌入简单值?您可以@Value
使用@Value
批注。
可以从属性文件,垃圾箱等中获取此类值。
@Value("$some.key") public String stringWithDefaultValue;
字符串将嵌入到此变量中,例如,从属性或视图中。
与往常一样,请发送在PM中发现的更正或错误。