Spring相关
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#populateBean->执行InstantiationAwareBeanPostProcessor的postProcessProperties如:org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor(解析之前标记的@value、@autowire)#postProcessProperties->metadata.inject->element.inject->beanFactory.resolveDependency->DefaultListableBeanFactory#doResolveDependency {
//从环境变量中解析${param}
...String strVal = resolveEmbeddedValue((String) value){
//embeddedValueResolvers在finishBeanFactoryInitialization方法中赋值的
//beanFactory.addEmbeddedValueResolver
//(strVal ->getEnvironment().resolvePlaceholders(strVal))最后执行是从环境变量中取值
...for (StringValueResolver resolver : this.embeddedValueResolvers) {
//执行是从环境变量中取值
result = resolver.resolveStringValue(result)(函数式接口)->org.springframework.core.env.AbstractEnvironment#resolvePlaceholders{
//propertyResolver为PropertySourcesPropertyResolver
...propertyResolver.resolvePlaceholders(text){
...doResolvePlaceholders{
//PropertyPlaceholderHelper相关处理
...helper.replacePlaceholders{
...parseStringValue{
...placeholderResolver.resolvePlaceholder{
..replacePlaceholders(text, this::getPropertyAsRawString)->getPropertyAsRawString.getProperty->propertySource.getProperty(环境变量中取值:包含PropertiesPropertySource、SystemEnvironmentPropertySource、ResourcePropertySource)...
}...
}...
}...
}...
}...
}...
}...
//el表达式,此时传入的applicationcontext对象的beanfactory属性(非environment属性)解析#{param}
...value = evaluateBeanDefinitionString(strVal, bd){
...evaluate{
//ExpressionParser有三个实现类:SpelExpressionParser、TemplateAwareExpressionParser(SpelExpressionParser的父类)、InternalSpelExpressionParser此处expressionParser为TemplateAwareExpressionParser其中beanExpressionParserContext为StandardBeanExpressionResolver(含#{})
...expressionParser.parseExpression(value, this.beanExpressionParserContext){
...>>process>>...
}...
//此处的evalContext为beanfactory
...this.evaluationCache.get(evalContext)...
//返回值
...expr.getValue(sec)...
}...
}...
}
//对于bean注释的解析,都是先解析对象交给bean管理(如@ComponentScan先只解析@Component类,import解析类后再递归遍历他们解析的类的其它配置注解如:Component、PropertySources、ComponentScan、Import)
new AnnotationConfigApplicationContext(MyConfig.class){
this(){
new AnnotatedBeanDefinitionReader{
this{
//注册内置bean如ConfigurationClassPostProcessor、AutowiredAnnotationBeanPostProcessor、CommonAnnotationBeanPostProcessor等
AnnotationConfigUtils.registerAnnotationConfigProcessors
}
}
}
//注册传入的配置类
register(componentClasses)
refresh{
invokeBeanFactoryPostProcessors->invokeBeanFactoryPostProcessors->invokeBeanDefinitionRegistryPostProcessors->postProcessBeanDefinitionRegistry->ConfigurationClassPostProcessor.processConfigBeanDefinitions{
//此时candidateNames只有注册的内置的和注册传入的配置类
...for (String beanName : candidateNames) {
//Configuration注解的类设置属性configurationClass值为full,Component、ComponentScan、Import、ImportResource、@Bean methods注解的类设置属性configurationClass值为lite
...else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {
//将上述full和lite对应的添加到configCandidates中
configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
}...
}...
//candidates = new LinkedHashSet<>(configCandidates)
parser.parse(candidates)->...->processConfigurationClass->doProcessConfigurationClass{@1
//此时暂时只有配置类,处理配置类中的PropertySources、ComponentScan->componentScanParser.parse代码如下:
scannedBeanDefinitions =componentScanParser.parse->scanner.doScan{
...Set
...scanCandidateComponents->根据basePackage构建resources遍历配置类配置的扫描路径下的所有类识别含@Component的类返回candidates->isCandidateComponent{
return candidates
}...
}...
}
for (BeanDefinitionHolder holder : scannedBeanDefinitions) {
...parse{
...processConfigurationClass{
//同@1,对扫描识别的@Component的类处理它的其它配置注解Component、PropertySources、ComponentScan、Import(也是类似:先把注释中的类注入交给bean管理后再解析这个交给bean管理的类的的其它配置注解)、ImportResource、Bean
...doProcessConfigurationClass...
}
}
}
}
}
}
}
//@Bean方法的bd.创建beanDef即ConfigurationClassBeanDefinition并且 beanDef.setUniqueFactoryMethodName(methodName即@Bean的方法,设置工厂方法)
invokeBeanFactoryPostProcessors->invokeBeanFactoryPostProcessors->invokeBeanDefinitionRegistryPostProcessors->postProcessBeanDefinitionRegistry->processConfigBeanDefinitions->loadBeanDefinitions(处理上述parse的candidates)->loadBeanDefinitionsForConfigurationClass->loadBeanDefinitionsForBeanMethod(@bean和@import都是通过各自处理注册bd)->{
beanDef = new ConfigurationClassBeanDefinition(configClass, metadata)...
...beanDef.setFactoryBeanName(configClass.getBeanName());
beanDef.setUniqueFactoryMethodName(methodName)...
registry.registerBeanDefinition...
}
//@Enable 引入 DelegatingWebMvcConfiguration 继承自WebMvcConfigurationSupport(会通过@Bean定义一系列的HandlerMapping(如:RequestMappingHandlerMapping等)、HandlerAdapter(如:RequestMappingHandlerAdapter)、ViewResolver(@Bean注入InternalResourceViewResolver这个类)等)DispatcherServlet静态代码块中会加载DispatcherServlet.properties文件中默认的一些配置类信息进入properties.
org.springframework.web.servlet.DispatcherServlet#onRefresh->initStrategies{
...initMultipartResolver(context);
initLocaleResolver(context);
initThemeResolver(context);
initHandlerMappings(context);
initHandlerAdapters(context);
initHandlerExceptionResolvers(context);
initRequestToViewNameTranslator(context);
initViewResolvers(context);
initFlashMapManager(context)...
}
//其中initHandlerMappings会先加载WebMvcConfigurationSupport
initHandlerMappings{
//通过@Bean(bean方法会创建一个bd)注入的handlermapping
...BeanFactoryUtils.beansOfTypeIncludingAncestors(context, HandlerMapping.class...
//如果没有@bean引入的就会采用dispatchservlet静态代码块中默认的一些配置类
...this.handlerMappings = getDefaultStrategies(context, HandlerMapping.class)...
}
RequestMappingHandlerMapping.afterPropertiesSet->super.afterPropertiesSet->initHandlerMethods->processCandidateBean->(isHandler表示有Controller注解或者RequestMapping注解)detectHandlerMethods->将controller解析为map(method,requestMappingInfo),后面gethandler遍历handlerMappings就是从这个map中找到handler.通过handler找到HandlerAdapter注入convertservice解析参数及返回值执行方法
spring 父容器和 springmvc 子容器:
org.apache.catalina.core.StandardContext#startInternal{
listenerStart->contextInitialized->initWebApplicationContext{
//把当前spring容器的context放入servletcontext ...servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.context)...
}
}
org.apache.catalina.core.StandardContext#startInternal{
...loadOnStartup(findChildren())->...->initWebApplicationContext{
//从servletcontext中取出 spring容器中的context
...rootContext =
WebApplicationContextUtils.getWebApplicationContext(getServletContext())...
createWebApplicationContext->同->createWebApplicationContext{
//mvc context设置spring容器中的context作为parent
...wac.setParent(parent)...
}->configureAndRefreshWebApplicationContext->...->refresh->obtainFreshBeanFactory->refreshBeanFactory->设置parentBeanFactory 创建createBeanFactory{
new DefaultListableBeanFactory(getInternalParentBeanFactory(){
getParent()
})
}
}
}
//mvc容器中没有的bd 则去parent即spring的容器中查找
org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean{
BeanFactory parentBeanFactory = getParentBeanFactory();
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
...doGetBean
}
//dispatchServlet初始化调用refresh后会发布ContextRefreshedEvent事件,触发监听器org.springframework.web.servlet.FrameworkServlet.ContextRefreshListener.onApplicationEvent事件->同->onRefresh->initStrategies->initHandlerAdapters->getDefaultStrategies->createDefaultStrategy->包含org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter#getDefaultArgumentResolvers,其中RequestMappingHandlerAdapter构造函数默认添加了四个messageConverters(ByteArrayHttpMessageConverter,StringHttpMessageConverter等不含MappingJackson2HttpMessageConverter),如果adapter需要转换json类型的参数则需要添加MappingJackson2HttpMessageConverter这个转换器。如下:
//处理request请求参数
org.springframework.web.servlet.HandlerAdapter#handle->...->org.springframework.web.method.support.InvocableHandlerMethod#invokeForRequest->getMethodArgumentValues->resolveArgument->resolveArgument->readWithMessageConverters->遍历messageConverters转换参数,会执行beforeBodyRead,afterBodyRead
在Java中,枚举类的构造函数在定义时就已经完成了初始化,这意味着在你定义枚举类并为其常量提供初始值时,这些常量的值就已经确定并存储在内存中。当你使用这些枚举常量时,不需要再次进行初始化。当你定义这个枚举类时,Java编译器会为每个常量创建一个实例,并调用其构造函数进行初始化。例如,SUNDAY 被初始化为 0,MONDAY 被初始化为 1,依此类推。这些初始化在定义时就已经完成了,因此在使用这些枚举常量时,你只需要直接引用它们,而不需要再次进行初始化
public enum Day {
SUNDAY(0),
MONDAY(1),
TUESDAY(2),
WEDNESDAY(3),
THURSDAY(4),
FRIDAY(5),
SATURDAY(6);
private int value;
// 构造函数
Day(int value) {
this.value = value;
}
// 获取值的方法
public int getValue() {
return value;
}
// 其他方法
public boolean isWeekend() {
return this == SUNDAY || this == SATURDAY;
}
}
public class EnumExample {
public static void main(String[] args) {
Day today = Day.MONDAY;
System.out.println("Today is " + today);
System.out.println("Today's value is " + today.getValue());
System.out.println("Is today weekend? " + today.isWeekend());
}
}
在Java中,泛型参数的声明用于指定泛型方法或泛型类可以处理的数据类型。泛型参数在方法的返回类型之前声明,并且通常用一个大写字母表示,例如 T、E、K 等。如果你需要指定泛型参数的边界类型(即泛型参数必须是某个类的子类),可以使用 extends 关键字。如: public
在Java中,泛型类的泛型参数声明跟在类名后面,这是因为Java的语法设计要求类型参数在使用之前必须先声明。如:public class Box
这样做有几个原因:
编译时类型检查:Java的泛型系统设计目的是为了在编译时提供类型检查。将类型参数放在类名之后,可以让编译器在解析类的其他部分之前,先了解和确认类型参数的约束。
类型擦除(Type Erasure):Java的泛型实现采用了类型擦除机制,这意味着在编译期间,泛型类型会被擦除,不会直接保存到字节码中。因此,运行时无法获取泛型的实际类型信息。将类型参数放在类名之后,有助于编译器在类型擦除之前完成必要的类型检查。
HTTPS证书的生效原理基于公钥加密和数字签名技术。以下是证书生效的主要步骤:
证书申请:服务器管理员向证书颁发机构(CA)申请证书。在申请过程中,管理员需要生成一个公钥和一个私钥,并将公钥发送给CA。
身份验证:CA对申请者的身份进行验证。这通常包括验证域名的所有权和组织的真实性。验证过程的严格程度取决于证书的类型。
证书签发:验证通过后,CA会签发一个数字证书。这个证书包含申请者的公钥、CA的数字签名、证书的有效期以及其他相关信息。
证书安装:服务器管理员将签发的证书安装到服务器上。当客户端(如浏览器)访问服务器时,服务器会将证书发送给客户端。
证书验证:客户端接收到证书后,会验证证书的合法性。这包括验证证书的签名是否有效、证书是否在有效期内、证书是否被吊销等。
加密通信:如果证书验证通过,客户端会使用证书中的公钥加密数据,并发送给服务器。服务器使用私钥解密数据,从而确保通信的机密性和完整性。
以下是证书生效的关键技术:
公钥加密:使用公钥加密的数据只能用对应的私钥解密。这确保了数据的机密性。
数字签名:CA使用私钥对证书进行签名,客户端使用CA的公钥验证签名。这确保了证书的完整性和可信度。
证书链:证书通常包含一个证书链,这个链从根 CA 一直延伸到最终用户证书。客户端会验证整个证书链,以确保每个证书都是由受信任的 CA 签发的。
总之,HTTPS证书的生效原理基于公钥加密和数字签名技术,通过证书颁发机构的身份验证和签名,确保服务器的身份和数据的机密性、完整性。
doCreateBean->applyMergedBeanDefinitionPostProcessors->org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor#postProcessMergedBeanDefinition->findAutowiringMetadata->buildAutowiringMetadata{
//遍历属性查看是否有Autowired、Value注解,后面遍历方法也是一样
...ReflectionUtils.doWithLocalFields(targetClass, field -> {
MergedAnnotation<?> ann = findAutowiredAnnotation(field)...
//注入元素放InjectionMetadata中
...InjectionMetadata.forElements(elements, clazz)...
}->
populateBean->org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor#postProcessProperties{
...InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs)...
...metadata.inject->org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.AutowiredFieldElement#inject->value = beanFactory.resolveDependency...
//@autowired,value属性注入,通过filed直接赋值所以不需要setter方法
...if (value != null) {
ReflectionUtils.makeAccessible(field);
field.set(bean, value);
}...
}
//xml配置的bean属性赋值
org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader#parseDefaultElement->processBeanDefinition->parseBeanDefinitionElement..->parsePropertyElements{
...if (isCandidateElement(node) && nodeNameEquals(node, PROPERTY_ELEMENT)) {
...parsePropertyElement((Element) node, bd){
//添加到了bd中的PropertyValues
...bd.getPropertyValues().addPropertyValue(pv)...
}...
}...
}
populateBean->applyPropertyValues->setPropertyValues..->processLocalProperty->ph.setValue{
//通过反射方法执行的,所以xml配置的bean需要setter方法
...ReflectionUtils.makeAccessible(writeMethod);
writeMethod.invoke(getWrappedInstance(), value)...
}