Spring源码面试

难度1-5

1.属性填充 难度1

方法调用完整路径

package: com.mashibing.selfeditor2.EditorTest.java

描述:案例一,spring通过子类继承PropertyEditorSupport调用setAsText解析Adress数据。将String数据转换成Address对象。
spring容器启动的时候需要注册PropertyEditorRegistrar的子类实现registerCustomEditors,注入相应的解析类和对应的实现类。
补充:此处的数据使用此标签解析.properties文件获取对象。
@PropertySource(“classpath:customer.properties”)
@Value(“ c u s t o m e r . n a m e " ) @ V a l u e ( " {customer.name}") @Value(" customer.name")@Value("{customer.address}”)

public class AddressPropertyEditor  extends PropertyEditorSupport {

    @Override
    public void setAsText(String text) throws IllegalArgumentException {
        String[] s = text.split("_");
        Address address = new Address();
        address.setProvince(s[0]);
        address.setCity(s[1]);
        address.setTown(s[2]);
        this.setValue(address);
    }
}
public class AddressPropertyEditorRegistrar implements PropertyEditorRegistrar {

    @Override
    public void registerCustomEditors(PropertyEditorRegistry registry) {
        registry.registerCustomEditor(Address.class, new AddressPropertyEditor());
    }
}

2.代理实现 难度2

cglib

程序运行时ASM修改class字节码文件,需要创建Enhancer对象调用create完成对象调用。(启动时不生成文件)
 1.实现MethodInterceptor接口,重写intercept()
 2.使用Enhancer对象.create()产生代理对象

jdk

扩展部分:
程序编译的时候生成代理class文件,使用InvocationHandler的回调方法invoke执行具体方法。
使用Proxy.newProxyInstance(loader, interfaces, h);创建具体类对象。

1、如果目标对象实现了接口,默认情况下会采用JDK的动态代理
2、如果目标对象实现了接口,也可以强制使用CGLIB
3、如果目标对象没有实现了接口,必须采用CGLIB库,spring会自动在JDK动态代理和CGLIB之间转换

JDK和CGLIB动态代理的区别
https://blog.csdn.net/weixin_45723046/article/details/124422910

3.tx 难度5

https://blog.csdn.net/yangxiaofei_java/article/details/113634986

事物传播机制
https://blog.csdn.net/szy350/article/details/122466050

4.AOP 难度5

https://blog.csdn.net/yangxiaofei_java/article/details/113634986

5.IOC 难度5

循环依赖
https://blog.csdn.net/a745233700/article/details/110914620

6.常用注解 难度3

此类被用来扫描注解,比如@Component,@Repository,@Service,@Controller,在创建对象的时候做一些基本的配置工作
ClassPathBeanDefinitionScanner

7.对象实例after postProcessor 难度1,同1#

测试案例path:
com.mashibing.resolveBeforeInstantiation.Test.java
com.mashibing.populateBean.TestPopulate.java
可以用来做什么,条件判断,日志记录?属性填充
path全路径:

AbstractAutowireCapableBeanFactory.java
	@Override
	protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
			throws BeanCreationException {}
			// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
			// 给BeanPostProcessors一个机会来返回代理来替代真正的实例,应用实例化前的前置处理器,用户自定义动态代理的方式,针对于当前的被代理类需要经过标准的代理流程来创建对象
			Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
	@Nullable
	protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {	}
					bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
	@Nullable
	protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {}
				InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
				Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
AbstractAutowireCapableBeanFactory.java
	@Override
	protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
			throws BeanCreationException {}
			// 对bean的属性进行填充,将各个属性值注入,其中,可能存在依赖于其他bean的属性,则会递归初始化依赖的bean
			populateBean(beanName, mbd, instanceWrapper);
	protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {}
					// //postProcessAfterInstantiation:一般用于设置属性
					if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
						return;
					}
AbstractAutowireCapableBeanFactory.java
	@Override
	protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
			throws BeanCreationException {}
			// 对bean的属性进行填充,将各个属性值注入,其中,可能存在依赖于其他bean的属性,则会递归初始化依赖的bean
			populateBean(beanName, mbd, instanceWrapper);
	protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {}
					//postProcessProperties:在工厂将给定的属性值应用到给定Bean之前,对它们进行后处理,不需要任何属性扫描符。该回调方法在未来的版本会被删掉。
					// -- 取而代之的是 postProcessPropertyValues 回调方法。
					// 让ibp对pvs增加对bw的Bean对象的propertyValue,或编辑pvs的proertyValue
					PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
AbstractAutowireCapableBeanFactory.java
	@Override
	protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
			throws BeanCreationException {}
			// 对bean的属性进行填充,将各个属性值注入,其中,可能存在依赖于其他bean的属性,则会递归初始化依赖的bean
			populateBean(beanName, mbd, instanceWrapper);
	protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {}
						//postProcessPropertyValues:一般进行检查是否所有依赖项都满足,例如基于"Require"注释在 bean属性 setter,
						// 	-- 替换要应用的属性值,通常是通过基于原始的PropertyValues创建一个新的MutablePropertyValue实例, 添加或删除特定的值
						// 	-- 返回的PropertyValues 将应用于bw包装的bean实例 的实际属性值(添加PropertyValues实例到pvs 或者 设置为null以跳过属性填充)
						//回到ipd的postProcessPropertyValues方法
						pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);

子类实现InstantiationAwareBeanPostProcessor,重写

1.在bean实例化之前调用
postProcessBeforeInstantiation

2.在bean实例化之后调用
postProcessAfterInstantiation

3.当使用注解的时候,通过这个方法来完成属性的注入
postProcessProperties

4.属性注入后执行的方法,在5.1版本被废弃
postProcessPropertyValues

8.Bean定义注入 难度1

BeanDefinitionRegistryPostProcessor.java
	void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException;
BeanFactoryPostProcessor.java
	void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;

注入PropertyValues,修改value

  1. selfAutowired 注入板块忘记了。

9.Bean定义注入 难度1 案例不全,没有记录正确的过程

@FunctionalInterface
public interface Converter<S, T> {

	/**
	 * 将S类型转换成T类型
	 *
	 * Convert the source object of type {@code S} to target type {@code T}.
	 * @param source the source object to convert, which must be an instance of {@code S} (never {@code null})
	 * @return the converted object, which must be an instance of {@code T} (potentially {@code null})
	 * @throws IllegalArgumentException if the source cannot be converted to the desired target type
	 */
	@Nullable
	T convert(S source);

}
    <bean id="studentConverter" class="com.mashibing.selfConverter.StudentConverter"></bean>
    <bean id ="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
        <property name="converters">
            <set>
                <ref bean="studentConverter"></ref>
            </set>
        </property>
    </bean>

10 AnnotationUtils

11 AnnotatedElementUtils

12 DI注入的七种方式

  1. 使用xml的方式来声明Bean的定义Spring容器在启动的时候会加载并解析这个xml,把bean装在到IOC容器中
  2. 使用@ComponentScan注解来扫描声明了@Controller,@Service,@Repository,@Component注解的类
  3. 使用@Confinguration注解声明配置类,并使用@Bean注解实现Bean的定义,这种方式其实是xml配置方式的一种演变,是Spring迈入到无配置化时代的里程碑
  4. 使用@Import注解,导入配置类或者普通的Bean
  5. 使用FactoryBean工厂bean,动态构建一个Bean实例,Spring Could OpenFeign里面的动态代理实例就是使用FactoryBean来实现的。
  6. 实现ImportBeanDefinitionResgister接口,可以动态注入Bean实例。这个在Spring Boot里面的启动注解用到
  7. 实现ImportSelector接口,动态批量注入配置类或者Bean对象,这个在SpringBoot里面的自动装配机制里面有用到

https://www.bilibili.com/video/BV1BP4y127jA/?spm_id_from=333.337.search-card.all.click

spring boot,补充

https://blog.csdn.net/woshilijiuyi/article/details/84147483

https://blog.csdn.net/woshilijiuyi/article/details/83934407

spring could,补充

https://blog.csdn.net/duqingqing5666/article/details/119395052?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522166793922816800184153631%2522%252C%2522scm%2522%253A%252220140713.130102334…%2522%257D&request_id=166793922816800184153631&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allsobaiduend~default-2-119395052-null-null.142v63control,201v3add_ask,213v2t3_esquery_v2&utm_term=springcould%E6%BA%90%E7%A0%81&spm=1018.2226.3001.4187

https://blog.csdn.net/qq_34684394/article/details/120103677?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522166793922816800184153631%2522%252C%2522scm%2522%253A%252220140713.130102334…%2522%257D&request_id=166793922816800184153631&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allsobaiduend~default-1-120103677-null-null.142v63control,201v3add_ask,213v2t3_esquery_v2&utm_term=springcould%E6%BA%90%E7%A0%81&spm=1018.2226.3001.4187

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring源码面试题涉及到对Spring框架的原理和核心组件的理解。以下是一些可能的面试题: 1. 请解释一下Spring框架的IoC容器是什么? 引用中提到,Spring的IoC容器是用来管理和组织对象及其依赖关系的容器。它负责创建、配置和管理应用程序中的对象,并将它们装配在一起。通过IoC容器,我们可以将对象之间的依赖关系委托给容器来处理,而不是在代码中显式地进行依赖关系的管理。 2. 请描述一下Spring Bean的生命周期。 引用中提到,Spring Bean的生命周期包括以下几个阶段: - 实例化:创建Bean的实例。 - 属性填充:将Bean的属性值通过依赖注入的方式填充到Bean中。 - 初始化:调用Bean的初始化方法,可以在配置文件中定义或使用注解标记。 - 销毁:当容器关闭时,调用Bean的销毁方法进行清理工作。 3. 请解释一下Spring中的事件传播器是什么? 引用中提到,Spring的事件传播器是一个组件,它可以接受特定的事件并将其传播给对应的监听器。当某个事件发生时,通过事件传播器,我们可以方便地将事件通知多个监听器,以便它们做出相应的处理。 4. 请解释一下BeanFactory和ApplicationContext的区别是什么? BeanFactory是Spring框架的根接口,它定义了IoC容器的基本功能。它提供了创建、配置和管理Bean的能力。而ApplicationContext是BeanFactory的子接口,扩展了更多的功能,如国际化、事件传播器、资源加载等。ApplicationContext是更高级、更全面的容器。 以上是一些可能的面试题,希望能对你有所帮助。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [SSM框架的学习与应用-Java EE企业级应用开发学习记录-(第六天)初识Spring框架](https://download.csdn.net/download/m0_53659738/88275704)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [spring相关的源码面试题](https://blog.csdn.net/weixin_56993128/article/details/125944512)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [Spring常见面试题(源码)](https://blog.csdn.net/qq_46312987/article/details/118068743)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值