“Spring Boot 2 自动配置流程”的版本间的差异

来自姬鸿昌的知识库
跳到导航 跳到搜索
 
(未显示同一用户的8个中间版本)
第1行: 第1行:
 
https://www.bilibili.com/video/BV19K4y1L7MT?p=15
 
https://www.bilibili.com/video/BV19K4y1L7MT?p=15
 +
 +
=== 以 AopAutoConfiguration 为例分析自动配置类 ===
 +
  
 
以 spring-boot-autoconfigure-2.3.4.RELEASE.jar 中的 org.springframework.boot.autoconfigure.aop.AopAutoConfiguration 为例,分析自动配置流程
 
以 spring-boot-autoconfigure-2.3.4.RELEASE.jar 中的 org.springframework.boot.autoconfigure.aop.AopAutoConfiguration 为例,分析自动配置流程
 +
 +
spring-boot-autoconfigure-2.3.4.RELEASE.jar\META-INF\spring.factories<syntaxhighlight lang="properties">
 +
……
 +
# Auto Configure
 +
……
 +
org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\
 +
……
 +
</syntaxhighlight><syntaxhighlight lang="java">
 +
package org.springframework.boot.autoconfigure.aop;
 +
 +
import org.aspectj.weaver.Advice;
 +
 +
……
 +
@Configuration(proxyBeanMethods = false)
 +
@ConditionalOnProperty(prefix = "spring.aop", name = "auto", havingValue = "true", matchIfMissing = true)
 +
public class AopAutoConfiguration {
 +
 +
@Configuration(proxyBeanMethods = false)
 +
@ConditionalOnClass(Advice.class)
 +
static class AspectJAutoProxyingConfiguration {
 +
 +
@Configuration(proxyBeanMethods = false)
 +
@EnableAspectJAutoProxy(proxyTargetClass = false)
 +
@ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "false",
 +
matchIfMissing = false)
 +
static class JdkDynamicAutoProxyConfiguration {
 +
 +
}
 +
 +
@Configuration(proxyBeanMethods = false)
 +
@EnableAspectJAutoProxy(proxyTargetClass = true)
 +
@ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "true",
 +
matchIfMissing = true)
 +
static class CglibAutoProxyConfiguration {
 +
 +
}
 +
 +
}
 +
 +
@Configuration(proxyBeanMethods = false)
 +
@ConditionalOnMissingClass("org.aspectj.weaver.Advice")
 +
@ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "true",
 +
matchIfMissing = true)
 +
static class ClassProxyingConfiguration {
 +
 +
ClassProxyingConfiguration(BeanFactory beanFactory) {
 +
if (beanFactory instanceof BeanDefinitionRegistry) {
 +
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
 +
AopConfigUtils.registerAutoProxyCreatorIfNecessary(registry);
 +
AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
 +
}
 +
}
 +
 +
}
 +
}
 +
</syntaxhighlight>
 +
 +
 +
<code>@Configuration</code> 说明这是一个配置类;
 +
 +
<code>@ConditionalOnProperty(prefix = "spring.aop", name = "auto", havingValue = "true", matchIfMissing = true)</code>
 +
 +
配置文件中是否存在 <code>spring.aop</code> 这个配置,如果存在了 <code>spring.aop.auto</code> 这个配置,并且它的值是“true”,那么这个类中的其他配置就生效,<code>matchIfMissing = true</code> 就算没有响应的配置,也认为满足条件,所以相当于这个配置是生效的
 +
 +
再来看<syntaxhighlight lang="java">
 +
@Configuration(proxyBeanMethods = false)
 +
@ConditionalOnClass(Advice.class)
 +
static class AspectJAutoProxyingConfiguration {
 +
 +
@Configuration(proxyBeanMethods = false)
 +
@EnableAspectJAutoProxy(proxyTargetClass = false)
 +
@ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "false",
 +
matchIfMissing = false)
 +
static class JdkDynamicAutoProxyConfiguration {
 +
 +
}
 +
 +
@Configuration(proxyBeanMethods = false)
 +
@EnableAspectJAutoProxy(proxyTargetClass = true)
 +
@ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "true",
 +
matchIfMissing = true)
 +
static class CglibAutoProxyConfiguration {
 +
 +
}
 +
 +
}
 +
</syntaxhighlight><code>@Configuration</code> 说明这是一个配置类;
 +
 +
<code>@ConditionalOnClass(Advice.class)</code> 类路径中是否存在 <code>org.aspectj.weaver.Advice</code> 这个类,在 IDEA 中 按两下 Shift 只有选择 Classes tab 页,没有 <code>org.aspectj.weaver.Advice</code>这个类,所以这个类中的其他配置也就不生效了
 +
 +
 +
接着再来看<syntaxhighlight lang="java">
 +
@Configuration(proxyBeanMethods = false)
 +
@ConditionalOnMissingClass("org.aspectj.weaver.Advice")
 +
@ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "true",
 +
matchIfMissing = true)
 +
static class ClassProxyingConfiguration {
 +
 +
ClassProxyingConfiguration(BeanFactory beanFactory) {
 +
if (beanFactory instanceof BeanDefinitionRegistry) {
 +
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
 +
AopConfigUtils.registerAutoProxyCreatorIfNecessary(registry);
 +
AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
 +
}
 +
}
 +
 +
}
 +
</syntaxhighlight><code>@Configuration</code> 说明这是一个配置类;
 +
 +
<code>@ConditionalOnMissingClass("org.aspectj.weaver.Advice")</code> 当系统中没有 <code>org.aspectj.weaver.Advice</code> 这个类的时候生效;
 +
 +
<code>@ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "true", matchIfMissing = true)</code> 配置文件中是不是配置了 <code>spring.aop.proxy-target-class=true</code>,没配也当配了生效;
 +
 +
 +
 +
 +
 +
 +
=== 以 CacheAutoConfiguration 为例分析自动配置类 ===
 +
spring-boot-autoconfigure-2.3.4.RELEASE.jar\META-INF\spring.factories<syntaxhighlight lang="properties">
 +
……
 +
# Auto Configure
 +
……
 +
org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration,\
 +
……
 +
</syntaxhighlight><syntaxhighlight lang="java">
 +
 +
package org.springframework.boot.autoconfigure.cache;
 +
 +
……
 +
import org.springframework.cache.CacheManager;
 +
……
 +
 +
@Configuration(proxyBeanMethods = false)
 +
@ConditionalOnClass(CacheManager.class)
 +
@ConditionalOnBean(CacheAspectSupport.class)
 +
@ConditionalOnMissingBean(value = CacheManager.class, name = "cacheResolver")
 +
@EnableConfigurationProperties(CacheProperties.class)
 +
@AutoConfigureAfter({ CouchbaseDataAutoConfiguration.class, HazelcastAutoConfiguration.class,
 +
HibernateJpaAutoConfiguration.class, RedisAutoConfiguration.class })
 +
@Import({ CacheConfigurationImportSelector.class, CacheManagerEntityManagerFactoryDependsOnPostProcessor.class })
 +
public class CacheAutoConfiguration {
 +
 +
    ……
 +
 +
}
 +
</syntaxhighlight><code>@ConditionalOnClass(CacheManager.class)</code> 类路径中有,是 spring-context-5.2.9.RELEASE.jar 中的包,所以这个条件是成立的<code>@ConditionalOnBean(CacheAspectSupport.class)</code> 判断容器中是否存在 CacheAspectSupport 类型的组件:<syntaxhighlight lang="java">
 +
@SpringBootApplication(scanBasePackages = "io.github.jihch")
 +
public class MainApplication {
 +
 +
    public static void main(String[] args) {
 +
        //1、返回 IOC 容器
 +
        ConfigurableApplicationContext context = SpringApplication.run(MainApplication.class, args);
 +
 +
        //2、查看容器里面的组件
 +
        String[] beanDefinitionNames = context.getBeanDefinitionNames();
 +
        Arrays.sort(beanDefinitionNames);
 +
        for (String name : beanDefinitionNames) {
 +
            System.out.println(name);
 +
        }
 +
 +
        int beanDefinitionCount = context.getBeanDefinitionCount();
 +
        System.out.printf("beanDefinitionCount:%d\n", beanDefinitionCount);
 +
 +
        String[] beanNamesForType = context.getBeanNamesForType(CacheAspectSupport.class);
 +
        System.out.printf("beanNamesForType.length:%d\n", beanNamesForType.length);
 +
        for (String s : beanNamesForType) {
 +
            System.out.println(s);
 +
        }
 +
    }
 +
 +
}
 +
</syntaxhighlight><syntaxhighlight lang="console">
 +
……
 +
beanDefinitionCount:129
 +
beanNamesForType.length:0
 +
</syntaxhighlight>容器中没有 CacheAspectSupport 类型的组件,条件不成立,所以这个类中的其他 <code>@Bean</code> 的配置就不会生效
 +
 +
 +
 +
 +
=== 以 DispatcherServletAutoConfiguration 为例分析自动配置类 ===
 +
spring-boot-autoconfigure-2.3.4.RELEASE.jar 中的 org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration<syntaxhighlight lang="java">
 +
package org.springframework.boot.autoconfigure.web.servlet;
 +
……
 +
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE)
 +
@Configuration(proxyBeanMethods = false)
 +
@ConditionalOnWebApplication(type = Type.SERVLET)
 +
@ConditionalOnClass(DispatcherServlet.class)
 +
@AutoConfigureAfter(ServletWebServerFactoryAutoConfiguration.class)
 +
public class DispatcherServletAutoConfiguration {
 +
    ……
 +
 +
}
 +
</syntaxhighlight>

2023年3月5日 (日) 09:33的最新版本

https://www.bilibili.com/video/BV19K4y1L7MT?p=15

以 AopAutoConfiguration 为例分析自动配置类

以 spring-boot-autoconfigure-2.3.4.RELEASE.jar 中的 org.springframework.boot.autoconfigure.aop.AopAutoConfiguration 为例,分析自动配置流程

spring-boot-autoconfigure-2.3.4.RELEASE.jar\META-INF\spring.factories

……
# Auto Configure
……
org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\
……
package org.springframework.boot.autoconfigure.aop;

import org.aspectj.weaver.Advice;

……
@Configuration(proxyBeanMethods = false)
@ConditionalOnProperty(prefix = "spring.aop", name = "auto", havingValue = "true", matchIfMissing = true)
public class AopAutoConfiguration {

	@Configuration(proxyBeanMethods = false)
	@ConditionalOnClass(Advice.class)
	static class AspectJAutoProxyingConfiguration {

		@Configuration(proxyBeanMethods = false)
		@EnableAspectJAutoProxy(proxyTargetClass = false)
		@ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "false",
				matchIfMissing = false)
		static class JdkDynamicAutoProxyConfiguration {

		}

		@Configuration(proxyBeanMethods = false)
		@EnableAspectJAutoProxy(proxyTargetClass = true)
		@ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "true",
				matchIfMissing = true)
		static class CglibAutoProxyConfiguration {

		}

	}

	@Configuration(proxyBeanMethods = false)
	@ConditionalOnMissingClass("org.aspectj.weaver.Advice")
	@ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "true",
			matchIfMissing = true)
	static class ClassProxyingConfiguration {

		ClassProxyingConfiguration(BeanFactory beanFactory) {
			if (beanFactory instanceof BeanDefinitionRegistry) {
				BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
				AopConfigUtils.registerAutoProxyCreatorIfNecessary(registry);
				AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
			}
		}

	}
}


@Configuration 说明这是一个配置类;

@ConditionalOnProperty(prefix = "spring.aop", name = "auto", havingValue = "true", matchIfMissing = true)

配置文件中是否存在 spring.aop 这个配置,如果存在了 spring.aop.auto 这个配置,并且它的值是“true”,那么这个类中的其他配置就生效,matchIfMissing = true 就算没有响应的配置,也认为满足条件,所以相当于这个配置是生效的

再来看

	@Configuration(proxyBeanMethods = false)
	@ConditionalOnClass(Advice.class)
	static class AspectJAutoProxyingConfiguration {

		@Configuration(proxyBeanMethods = false)
		@EnableAspectJAutoProxy(proxyTargetClass = false)
		@ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "false",
				matchIfMissing = false)
		static class JdkDynamicAutoProxyConfiguration {

		}

		@Configuration(proxyBeanMethods = false)
		@EnableAspectJAutoProxy(proxyTargetClass = true)
		@ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "true",
				matchIfMissing = true)
		static class CglibAutoProxyConfiguration {

		}

	}

@Configuration 说明这是一个配置类;

@ConditionalOnClass(Advice.class) 类路径中是否存在 org.aspectj.weaver.Advice 这个类,在 IDEA 中 按两下 Shift 只有选择 Classes tab 页,没有 org.aspectj.weaver.Advice这个类,所以这个类中的其他配置也就不生效了


接着再来看

	@Configuration(proxyBeanMethods = false)
	@ConditionalOnMissingClass("org.aspectj.weaver.Advice")
	@ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "true",
			matchIfMissing = true)
	static class ClassProxyingConfiguration {

		ClassProxyingConfiguration(BeanFactory beanFactory) {
			if (beanFactory instanceof BeanDefinitionRegistry) {
				BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
				AopConfigUtils.registerAutoProxyCreatorIfNecessary(registry);
				AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
			}
		}

	}

@Configuration 说明这是一个配置类;

@ConditionalOnMissingClass("org.aspectj.weaver.Advice") 当系统中没有 org.aspectj.weaver.Advice 这个类的时候生效;

@ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "true", matchIfMissing = true) 配置文件中是不是配置了 spring.aop.proxy-target-class=true,没配也当配了生效;




以 CacheAutoConfiguration 为例分析自动配置类

spring-boot-autoconfigure-2.3.4.RELEASE.jar\META-INF\spring.factories

……
# Auto Configure
……
org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration,\
……
package org.springframework.boot.autoconfigure.cache;

……
import org.springframework.cache.CacheManager;
……

@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(CacheManager.class)
@ConditionalOnBean(CacheAspectSupport.class)
@ConditionalOnMissingBean(value = CacheManager.class, name = "cacheResolver")
@EnableConfigurationProperties(CacheProperties.class)
@AutoConfigureAfter({ CouchbaseDataAutoConfiguration.class, HazelcastAutoConfiguration.class,
		HibernateJpaAutoConfiguration.class, RedisAutoConfiguration.class })
@Import({ CacheConfigurationImportSelector.class, CacheManagerEntityManagerFactoryDependsOnPostProcessor.class })
public class CacheAutoConfiguration {

    ……

}

@ConditionalOnClass(CacheManager.class) 类路径中有,是 spring-context-5.2.9.RELEASE.jar 中的包,所以这个条件是成立的@ConditionalOnBean(CacheAspectSupport.class) 判断容器中是否存在 CacheAspectSupport 类型的组件:

@SpringBootApplication(scanBasePackages = "io.github.jihch")
public class MainApplication {

    public static void main(String[] args) {
        //1、返回 IOC 容器
        ConfigurableApplicationContext context = SpringApplication.run(MainApplication.class, args);

        //2、查看容器里面的组件
        String[] beanDefinitionNames = context.getBeanDefinitionNames();
        Arrays.sort(beanDefinitionNames);
        for (String name : beanDefinitionNames) {
            System.out.println(name);
        }

        int beanDefinitionCount = context.getBeanDefinitionCount();
        System.out.printf("beanDefinitionCount:%d\n", beanDefinitionCount);

        String[] beanNamesForType = context.getBeanNamesForType(CacheAspectSupport.class);
        System.out.printf("beanNamesForType.length:%d\n", beanNamesForType.length);
        for (String s : beanNamesForType) {
            System.out.println(s);
        }
    }

}
……
beanDefinitionCount:129
beanNamesForType.length:0

容器中没有 CacheAspectSupport 类型的组件,条件不成立,所以这个类中的其他 @Bean 的配置就不会生效



以 DispatcherServletAutoConfiguration 为例分析自动配置类

spring-boot-autoconfigure-2.3.4.RELEASE.jar 中的 org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration

package org.springframework.boot.autoconfigure.web.servlet;
……
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE)
@Configuration(proxyBeanMethods = false)
@ConditionalOnWebApplication(type = Type.SERVLET)
@ConditionalOnClass(DispatcherServlet.class)
@AutoConfigureAfter(ServletWebServerFactoryAutoConfiguration.class)
public class DispatcherServletAutoConfiguration {
    ……

}