@ComponentScan(value = "com.lmx", includeFilters = {@ComponentScan.Filter(type = FilterType.ANNOTATION, classes = Controller.class)}, useDefaultFilters = false)
public void registerBeanDefinitions(AnnotationMetadata metadata,
BeanDefinitionRegistry registry) {
registerDefaultConfiguration(metadata, registry);
registerFeignClients(metadata, registry);
}
`
BeanFactory
对象工厂/IOC容器。Spring中所有对象实例都交由BeanFactory进行管理。
FactoryBean
一个Bean实例,但又不同于普通实例,是能够生产并修饰Bean实例的工厂实例,是工厂模式和装饰器模式结合的产物。
BeanFactoryAware API
实现了BeanFactoryAware接口的bean,可以直接通过beanfactory来访问spring的容器。
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>5.0.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>5.0.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.11</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.5.RELEASE</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.66</version>
</dependency>
<!-- mysql 依赖 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.46</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.0.5.RELEASE</version>
</dependency>
·
@Data
public class UserEntity {
private Integer userId;
private String userName;
public UserEntity(Integer userId, String userName) {
this.userId = userId;
this.userName = userName;
}
}
@Configuration
@ComponentScan(value = {"com.lming"})
public class MySpringConfig {
@Bean
public UserEntity userEntity() {
return new UserEntity(1, "zhangsan");
}
}
public class TestMain {
public static void main(String[] args) {
ApplicationContext context = new AnnotationConfigApplicationContext(MySpringConfig.class);
System.out.println("------->>>>打印所有IOC中的实例");
String[] beanDefinitionNames = context.getBeanDefinitionNames();
for (String name : beanDefinitionNames) {
System.out.println(name);
}
UserEntity userEntity = context.getBean("userEntity", UserEntity.class);
System.out.println("获取到实例:" + userEntity);
}
}
Spring将IOC的加载分为三个阶段。初始化阶段加载基础环境,注册阶段注入一个或多个注解类到IOC,刷新上下文阶段进行扫包刷新配置信息,若IOC容器已存在,则销毁注册阶段创建的IOC容器,重新创建容器,完成容器初始化工作。
public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
// 1.初始化阶段
this();
// 2.注册阶段
register(annotatedClasses);
// 3.刷新上下文阶段
refresh();
}
初始化阶段完成读取器和扫描器的加载。
public AnnotationConfigApplicationContext() {
// 注解实例读取器
this.reader = new AnnotatedBeanDefinitionReader(this);
// 类扫描器
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
`
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) {
// getOrCreateEnvironment获取运行环境信息
this(registry, getOrCreateEnvironment(registry));
}
——> public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
Assert.notNull(environment, "Environment must not be null");
this.registry = registry;
this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
}
——> public static void registerAnnotationConfigProcessors(BeanDefinitionRegistry registry) {
registerAnnotationConfigProcessors(registry, null);
}
registerAnnotationConfigProcessors()中将注解处理器加载到IOC中,比如@Configuration、@Autowired、BeanFactory的驱动处理器等。
// 省略部分代码……
// 初始化2 - 比如@Configuration注解的驱动处理器
if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
}
// 初始化3 - 比如@Autowired注解的驱动处理器
if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
}
// 省略部分代码……
类扫描器初始化工作包括三部分,注入过滤器、环境变量、加载类资源。
public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry) {
this(registry, true);
}
——> public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters) {
// getOrCreateEnvironment获取运行环境信息
this(registry, useDefaultFilters, getOrCreateEnvironment(registry));
}
——> public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters,
Environment environment) {
this(registry, useDefaultFilters, environment,
(registry instanceof ResourceLoader ? (ResourceLoader) registry : null));
}
——> public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters,
Environment environment, @Nullable ResourceLoader resourceLoader) {
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
this.registry = registry;
if (useDefaultFilters) {
// 初始化4.1 - 注册默认过滤器(@Service @Controller @Repostory @Component全靠这里,includeFilters指定装载那些实例)
registerDefaultFilters();
}
// 初始化4.2 - 装载系统环境配置,比如os.name,系统版本win7/10等
setEnvironment(environment);
// 初始化4.3 - 装载资源加载器,主要用来在程序内加载一些外部资源文件
setResourceLoader(resourceLoader);
}
在registerDefaultFilters()中会注册一个默认的过滤器,与@ComponentScan注解配置includeFilters息息相关。
protected void registerDefaultFilters() {
this.includeFilters.add(new AnnotationTypeFilter(Component.class));
ClassLoader cl = ClassPathScanningCandidateComponentProvider.class.getClassLoader();
try {
this.includeFilters.add(new AnnotationTypeFilter(
((Class<? extends Annotation>) ClassUtils.forName("javax.annotation.ManagedBean", cl)), false));
logger.trace("JSR-250 'javax.annotation.ManagedBean' found and supported for component scanning");
}
catch (ClassNotFoundException ex) {
// JSR-250 1.1 API (as included in Java EE 6) not available - simply skip.
}
try {
this.includeFilters.add(new AnnotationTypeFilter(
((Class<? extends Annotation>) ClassUtils.forName("javax.inject.Named", cl)), false));
logger.trace("JSR-330 'javax.inject.Named' annotation found and supported for component scanning");
}
catch (ClassNotFoundException ex) {
// JSR-330 API not available - simply skip.
}
}
初始阶段完成后,我们将得到一个具备处理关键注解、获取系统环境信息、可加载外部资源的应用程序上下文对象AnnotationConfigApplicationContext。
注册阶段通过初始化的注解读取器向上下文中注入一个或多个配置类实例,配置类优先于其他实例加载,使后续规则得以应用。例如:MySpringConfig。
public void register(Class<?>... componentClasses) {
Assert.notEmpty(componentClasses, "At least one component class must be specified");
this.reader.register(componentClasses);
}
——> public void register(Class<?>... componentClasses) {
// 依次解析配置
for (Class<?> componentClass : componentClasses) {
registerBean(componentClass);
}
}
——> public void registerBean(Class<?> beanClass) {
doRegisterBean(beanClass, null, null, null);
}
// 核心注册逻辑
——> <T> void doRegisterBean(Class<T> beanClass, @Nullable Supplier<T> instanceSupplier, @Nullable String name,
@Nullable Class<? extends Annotation>[] qualifiers, BeanDefinitionCustomizer... definitionCustomizers) {
// 注册1 - 解析@Configuration,将注解装换为实例,注册到IOC
AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);
// 注册1.1 - 执行Bean过滤规则@Conditional
if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
return;
}
// 注册1.2 - 指定创建 bean 实例的回调方法,此时为 null
abd.setInstanceSupplier(instanceSupplier);
// 解析bean作用域(单例或者原型),如果有@Scope注解,则解析@Scope,没有则默认为singleton
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
// 作用域写回BeanDefinition数据结构, abd中缺损的情况下为空,将默认值singleton重新赋值到abd
abd.setScope(scopeMetadata.getScopeName());
// 生成bean配置类beanName
String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));
// 注册1.3 - 通用注解解析到abd结构中,主要是处理Lazy, primary DependsOn, Role ,Description这五个注解
AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
if (qualifiers != null) {
for (Class<? extends Annotation> qualifier : qualifiers) {
// 如果配置@Primary注解,则设置当前Bean为自动装配autowire时首选bean
if (Primary.class == qualifier) {
abd.setPrimary(true);
}
// 设置当前bean为延迟加载
else if (Lazy.class == qualifier) {
abd.setLazyInit(true);
}
// 其他注解,则添加到abd结构中
else {
abd.addQualifier(new AutowireCandidateQualifier(qualifier));
}
}
}
for (BeanDefinitionCustomizer customizer : definitionCustomizers) {
customizer.customize(abd);
}
// 注册1.4 - 根据Bean名称和BeanDefinition创建一个Holder,Holder是二者的映射对象
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
}
——> public static void registerBeanDefinition(
BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
throws BeanDefinitionStoreException {
// 获取主选项的实例名称.
String beanName = definitionHolder.getBeanName();
// 注册1.5 - 将BeanDefinition注入到IOC容器(所有实例都将被封装为BeanDefinition)
registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
// (如果有)注册次级选项bean名称的别名。
String[] aliases = definitionHolder.getAliases();
if (aliases != null) {
for (String alias : aliases) {
registry.registerAlias(beanName, alias);
}
}
}
IDEA Ctrl+ALT+B查看BeanDefinitionRegistry API的DefaultListableBeanFactory的注册实现:
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
throws BeanDefinitionStoreException {
// 省略部分代码……
if (existingDefinition != null) {
// 省略部分代码……
// 注册1.6 - Spring使用ConcurrentHashMap保存BeanDefinition
this.beanDefinitionMap.put(beanName, beanDefinition);
}
else {
// 省略部分代码……
}
}
查看beanDefinitionMap,是ConcurrentHashMap的BeanDefinition集合,故我们可以得知IOC默认是采用ConcurrentHashMap存储实例。
刷新上下文阶段是对整个Spring框架是至关重要的,同时也非常的复杂。这里只专注于联合研究IOC与AOP,因此省略其他部分的内容。
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// 刷新前的预处理
prepareRefresh();
// 获取刷新后的内部Bean工厂
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// BeanFactory的预准备工作
prepareBeanFactory(beanFactory);
try {
// BeanFactory准备工作完成后,可以做一些后置处理工作,空方法,用于在容器的子类中扩展
postProcessBeanFactory(beanFactory);
// 刷新上下文1.1.1 - 执行BeanFactory后置处理器 ,在IOC初始化后实例构造方法之前执行
invokeBeanFactoryPostProcessors(beanFactory);
// 刷新上下文1.2.1 - 注册拦截Bean的相关处理器,这是实现AOP的核心
registerBeanPostProcessors(beanFactory);
// 初始化MessageSource组件(做国际化功能;消息绑定,消息解析)
initMessageSource();
// 初始化事件派发器
initApplicationEventMulticaster();
// 空方法,可以用于子类实现在容器刷新时自定义逻辑
onRefresh();
// 注册时间监听器,将所有项目里面的ApplicationListener注册到容器中来
registerListeners();
// 刷新上下文1.3.1 - 实例化所有剩余的单例Bean(非延迟初始化)。
finishBeanFactoryInitialization(beanFactory);
// 完成BeanFactory的初始化创建工作,IOC容器就创建完成;
finishRefresh();
}
catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - "
"cancelling refresh attempt: " + ex);
}
// 销毁已创建的单例以避免资源悬空。
destroyBeans();
// 重置'active' 旗帜.
cancelRefresh(ex);
throw ex;
}
finally {
// 重置Spring核心中的常见自省缓存,因为我们 //可能不再需要单例bean的元数据...
resetCommonCaches();
}
}
}
作用:允许我们在工厂里所有的bean被加载进来后但是还没初始化前,对所有bean的属性进行修改也可以add属性值。
执行时机:在IOC初始化后实例构造方法之前执行。
在MySpringConfig类上添加:@Import({MyBeanFactoryPostProcessor.class})
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
String[] beanDefinitionNames = beanFactory.getBeanDefinitionNames();
System.out.println("BeanFactory后置处理器,筛选所有Bean实例中名称为“payEntity”的实例,并将其amount改为500");
for (String beanDefinitionName : beanDefinitionNames) {
System.out.println("当前迭代实例------>>>" + beanDefinitionName);
if (beanDefinitionName.equals("payEntity")) {
BeanDefinition beanDefinition = beanFactory.getBeanDefinition(beanDefinitionName);
System.out.println("开始修改,对象原属性值为:" + JSON.toJSONString(beanDefinition.getPropertyValues()));
beanDefinition.getPropertyValues().add("amount", "500");
System.out.println("修改后,对象原属性值为:" + JSON.toJSONString(beanDefinition.getPropertyValues()));
return;
}
}
}
}
我将BeanFactory后处理器分为两步进行分析,注册以及执行。
我们回到刷新上下文阶段 invokeBeanFactoryPostProcessors(beanFactory)阶段,官方给定的解释是:
Instantiate and invoke all registered BeanFactoryPostProcessor beans,respecting explicit order if given.
翻译过来就是:实例化并调用所有已注册的BeanFactoryPostProcessor,(如果给定的话)遵循显式顺序。也就是说注册和执行皆由invokeBeanFactoryPostProcessors完成,它是至关重要的。
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
// 省略部分代码……
}
// invokeBeanFactoryPostProcessors代码比较长,这里只贴关键代码
——> public static void invokeBeanFactoryPostProcessors(
// 省略部分代码…… 这部分代码主要是对BeanDefinitionRegistryPostProcessor进行排序
List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
// 1、首先,调用PriorityOrdered接口实现,其拥有调用最高优先级;
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
// 2、然后,调用Ordered接口实现,我们写的MyBeanFactoryPostProcessor不在这两个层次;
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
// 3、最后, 调用其他BeanDefinitionRegistryPostProcessors.
boolean reiterate = true;
while (reiterate) {
reiterate = false;
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (!processedBeans.contains(ppName)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
reiterate = true;
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
}
// 省略BeanFactory后置处理器执行部分代码……
// 我们重点关注invokeBeanDefinitionRegistryPostProcessors的调用
}
——> private static void invokeBeanDefinitionRegistryPostProcessors(
Collection<? extends BeanDefinitionRegistryPostProcessor> postProcessors, BeanDefinitionRegistry registry) {
for (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) {
postProcessor.postProcessBeanDefinitionRegistry(registry);
}
}
IDEA快捷键Ctrl+Alt+B查看postProcessBeanDefinitionRegistry实现,默认只有ConfigurationClassPostProcessor。我们继续查看其postProcessBeanDefinitionRegistry的调用链,解析注册过程:
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
int registryId = System.identityHashCode(registry);
// 省略部分日志代码……
this.registriesPostProcessed.add(registryId);
processConfigBeanDefinitions(registry);
}
// 这里是Spring 扫包的入口
——> public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
List<BeanDefinitionHolder> configCandidates = new ArrayList<>();
String[] candidateNames = registry.getBeanDefinitionNames();
for (String beanName : candidateNames) {
BeanDefinition beanDef = registry.getBeanDefinition(beanName);
if (ConfigurationClassUtils.isFullConfigurationClass(beanDef) ||
ConfigurationClassUtils.isLiteConfigurationClass(beanDef)) {
if (logger.isDebugEnabled()) {
logger.debug("Bean definition has already been processed as a configuration class: " + beanDef);
}
}
// checkConfigurationClassCandidate检索IOC中所有的@Configuration注解类,到这一步为止IOC中只有一个@Configuration注解类他就是我们自定义的MySpringConfig,在注册阶段注入IOC。
else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {
configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
}
}
// 如果未找到@Configuration类,则立即返回
if (configCandidates.isEmpty()) {
return;
}
// 省略部分代码……主要是排序
// 接下来我们看Spring是如何扫包的,如何解析Configuration类的
do {
parser.parse(candidates);
parser.validate();
// 省略部分重织代码,即将candidates重置后重新织入,我们主要关注parse中扫包注入过程
}
while (!candidates.isEmpty());
// 省略部分注入代码……
}
——> public void parse(Set<BeanDefinitionHolder> configCandidates) {
this.deferredImportSelectors = new LinkedList<>();
for (BeanDefinitionHolder holder : configCandidates) {
BeanDefinition bd = holder.getBeanDefinition();
try {
// MySpringConfig是注解式的所以走这里
if (bd instanceof AnnotatedBeanDefinition) {
parse(((AnnotatedBeanDefinition) bd).getMetadata(), holder.getBeanName());
}
else if (bd instanceof AbstractBeanDefinition && ((AbstractBeanDefinition) bd).hasBeanClass()) {
parse(((AbstractBeanDefinition) bd).getBeanClass(), holder.getBeanName());
}
else {
parse(bd.getBeanClassName(), holder.getBeanName());
}
}
// 省略部分catch代码……
// 处理延迟导入的ImportSelectors
processDeferredImportSelectors();
}
——> protected final void parse(AnnotationMetadata metadata, String beanName) throws IOException {
processConfigurationClass(new ConfigurationClass(metadata, beanName));
}
——> protected void processConfigurationClass(ConfigurationClass configClass) throws IOException {
// 执行@Condition选择性注入的条件
if (this.conditionEvaluator.shouldSkip(configClass.getMetadata(), ConfigurationPhase.PARSE_CONFIGURATION)) {
return;
}
// 获取到@Configuration注解类,也就是MySpringConfig
ConfigurationClass existingClass = this.configurationClasses.get(configClass);
// 省略部分非必要性代码……
// 递归处理配置类及其超类层次结构。实际上是在检测注解或是超类的一些格式/规范问题。
SourceClass sourceClass = asSourceClass(configClass);
do {
sourceClass = doProcessConfigurationClass(configClass, sourceClass);
}
while (sourceClass != null);
this.configurationClasses.put(configClass, configClass);
}
// Spring 扫描的核心
——> protected final SourceClass doProcessConfigurationClass(ConfigurationClass configClass, SourceClass sourceClass)
throws IOException {
// 首先递归处理任何成员(嵌套)类
processMemberClasses(configClass, sourceClass);
// 解析@PropertySource注解,@PropertySource用来加载指定的属性文件。
for (AnnotationAttributes propertySource : AnnotationConfigUtils.attributesForRepeatable(
// 省略@PropertySource解析代码……
}
// 解析 @ComponentScan 注解
Set<AnnotationAttributes> componentScans = AnnotationConfigUtils.attributesForRepeatable(
sourceClass.getMetadata(), ComponentScans.class, ComponentScan.class);
if (!componentScans.isEmpty() &&
!this.conditionEvaluator.shouldSkip(sourceClass.getMetadata(), ConfigurationPhase.REGISTER_BEAN)) {
for (AnnotationAttributes componentScan : componentScans) {
// 通过初始化阶段的类路径扫描器扫描@ComponentScan标注范围内的所有类(ClassPathBeanDefinitionScanner)
Set<BeanDefinitionHolder> scannedBeanDefinitions =
this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName());
// 检查扫描的定义集是否有其他配置类,并在需要时递归解析
for (BeanDefinitionHolder holder : scannedBeanDefinitions) {
if (ConfigurationClassUtils.checkConfigurationClassCandidate(
holder.getBeanDefinition(), this.metadataReaderFactory)) {
parse(holder.getBeanDefinition().getBeanClassName(), holder.getBeanName());
}
}
}
}
// 处理所有的 @Import 注解,我们自定的BeanFactory后置处理器就是在这里被注册的!!
processImports(configClass, sourceClass, getImports(sourceClass), true);
// 处理所有@ImportResource 注解,@ImportResource主要用来装配XML配置文件
AnnotationAttributes importResource =
AnnotationConfigUtils.attributesFor(sourceClass.getMetadata(), ImportResource.class);
if (importResource != null) {
String[] resources = importResource.getStringArray("locations");
Class<? extends BeanDefinitionReader> readerClass = importResource.getClass("reader");
for (String resource : resources) {
String resolvedResource = this.environment.resolveRequiredPlaceholders(resource);
configClass.addImportedResource(resolvedResource, readerClass);
}
}
// 处理单个 @Bean 注解方法
Set<MethodMetadata> beanMethods = retrieveBeanMethodMetadata(sourceClass);
for (MethodMetadata methodMetadata : beanMethods) {
configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));
}
// 处理接口的默认方法
processInterfaces(configClass, sourceClass);
// (如果有)处理超类
if (sourceClass.getMetadata().hasSuperClass()) {
String superclass = sourceClass.getMetadata().getSuperClassName();
if (superclass != null && !superclass.startsWith("java") &&
!this.knownSuperclasses.containsKey(superclass)) {
this.knownSuperclasses.put(superclass, configClass);
// 到超类,返回其注释元数据并递归
return sourceClass.getSuperClass();
}
}
// 没有超类->处理完成
return null;
}
// @Import的解析是比较复杂的,Spring单独拿了出来
——> private void processImports(ConfigurationClass configClass, SourceClass currentSourceClass,
Collection<SourceClass> importCandidates, boolean checkForCircularImports) {
// 省略非核心代码……
for (SourceClass candidate : importCandidates) {
// 候选类是ImportSelector实现类,走这里进行注册
// 例如@EnableTransactionManagement注解,就是ImportSelector的实现
if (candidate.isAssignable(ImportSelector.class)) {
Class<?> candidateClass = candidate.loadClass();
ImportSelector selector = BeanUtils.instantiateClass(candidateClass, ImportSelector.class);
ParserStrategyUtils.invokeAwareMethods(
selector, this.environment, this.resourceLoader, this.registry);
if (this.deferredImportSelectors != null && selector instanceof DeferredImportSelector) {
this.deferredImportSelectors.add(
new DeferredImportSelectorHolder(configClass, (DeferredImportSelector) selector));
}
else {
String[] importClassNames = selector.selectImports(currentSourceClass.getMetadata());
Collection<SourceClass> importSourceClasses = asSourceClasses(importClassNames);
processImports(configClass, currentSourceClass, importSourceClasses, false);
}
}
// 候选类是ImportBeanDefinitionRegistrar实现类,从这里进行注册
// 例如,@EnableAspectJAutoProxy的关键类AspectJAutoProxyRegistrar就是这种实现,@EnableTransactionManagemen也有它的身影。
// BeanFactory后置处理器,并非上诉两种实现类型
else if (candidate.isAssignable(ImportBeanDefinitionRegistrar.class)) {
Class<?> candidateClass = candidate.loadClass();
ImportBeanDefinitionRegistrar registrar =
BeanUtils.instantiateClass(candidateClass, ImportBeanDefinitionRegistrar.class);
ParserStrategyUtils.invokeAwareMethods(
registrar, this.environment, this.resourceLoader, this.registry);
configClass.addImportBeanDefinitionRegistrar(registrar, currentSourceClass.getMetadata());
}
// BeanFactory直接实现BeanFactoryPostProcessor接口,既没有实现ImpostSelector也没有实现ImportBeanDefinitionRegistrar,则直接按照@Configuration方式解析
else {
this.importStack.registerImport(
currentSourceClass.getMetadata(), candidate.getMetadata().getClassName());
// BeanFactory后置处理器走processConfigurationClass递归完成解析工作
processConfigurationClass(candidate.asConfigClass(configClass));
}
}
// 省略异常处理代码……
}
到这里所有IOC的注册/扫描已经完成,也就是说这是容器中包括了项目中所需要的用到的大部分实例,当然@Lazy延迟加载的除外。
现在我们来总结一下注册过程:
ImportSelector实现型,例如@EnableTransactionManagement注解,就是ImportSelector的实现;
ImportBeanDefinitionRegistrar手动注入型,例如,@EnableAspectJAutoProxy的关键类AspectJAutoProxyRegistrar就是这种实现,@EnableTransactionManagement中也有它的身影;
其他类型Import,都按照@Configuration进行递归解析。 BeanFactory后置处理器既没有实现ImpostSelector也没有实现ImportBeanDefinitionRegistrar,则直接按照@Configuration方式解析。
现在我们回到注册/扫描阶段我们忽略掉的那部分后置处理器执行代码。
// 以下代码来自,PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors
// 省略注册/扫描阶段代码……
// 现在,调用到目前为止已处理的所有处理器的postProcessBeanFactory回调。
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
}
else {
// 调用向上下文实例注册的工厂处理器。
invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
}
// 不要在这里初始化FactoryBeans:我们需要保留所有常规bean //未初始化,以使Bean工厂后处理器对其应用!!
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
// 对BeanFactory后置处理器排序
List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
List<String> orderedPostProcessorNames = new ArrayList<>();
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
for (String ppName : postProcessorNames) {
if (processedBeans.contains(ppName)) {
// 跳过-已在上述第一阶段处理过
}
else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
}
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
}
else {
nonOrderedPostProcessorNames.add(ppName);
}
}
// 首先, 调用PriorityOrdered实现的BeanFactory后置处理器.
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
// 其次, 调用Ordered实现.
List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>();
for (String postProcessorName : orderedPostProcessorNames) {
orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
sortPostProcessors(orderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
// 最后, 调用其他BeanFactoryPostProcessors.
List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
for (String postProcessorName : nonOrderedPostProcessorNames) {
nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
// 清除缓存的合并bean定义,因为后处理器可能具有修改了原始元数据,例如替换值中的占位符...
beanFactory.clearMetadataCache();
}
// 重点关注
——> private static void invokeBeanFactoryPostProcessors(
Collection<? extends BeanFactoryPostProcessor> postProcessors, ConfigurableListableBeanFactory beanFactory) {
for (BeanFactoryPostProcessor postProcessor : postProcessors) {
postProcessor.postProcessBeanFactory(beanFactory);
}
}
BeanFactory后置处理器的执行和注册一样,也会分为三种优先级,PriorityOrdered—>Ordered—>其他BeanFactoryPostProcessors,演示中自定义的MyBeanFactoryPostProcessor 属于最后一级。
执行时,直接从IOC中获取到通过Bean名称到对应的BeanFactoryPostProcessor对象,最后调用postProcessBeanFactory方法,postProcessBeanFactory就是我们MyBeanFactoryPostProcessor 中实现的BeanFactory后置增强方法。
Spring首先通过类路径加载器进行扫包同时完成BeanFactoryPost后置处理器的注册,注册完成后,根据指定的BeanName从容器中获取BeanFactoryPost后置处理器,并执行postProcessBeanFactory方法,实现增强。
BeanFactory后置处理器在IOC初始化扫描后Bean实例构造方法执行前执行,可以实现对Bean实例的增强。但应用面比较鸡肋,而且在后续刷新上下文过程中Spring提供了更加强大的Bean前置增强处理器以及后置增强处理器。
这也是AOP的实现的依仗,下面我们开始它的分析!
Spring为Bean实例提供了两种Bean增强处理器,前置/后置处理器。也正是因为IOC提供的增强处理器,使得AOP可以在类初始化之前织入代码实现增强,这个过程是通过动态代理实现的。
想要在后续使用增强处理器,首先将其注入到容器中,下面我们来看一下它的调用链。
非常建议开启AOP注解@EnableAspectJAutoProxy(MySpringConfig上标注),这样可以更加直观的进行调试。
// 调用过程从AbstractApplicationContext.refresh()开始registerBeanPostProcessors(beanFactory);
——> protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}
// 在之前阶段IOC已经做了非常多的工作,使得后续注入工作变得非常简单
——> public static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
// 与之前注入一样,
int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
// 排序 PriorityOrdered —> Ordered —> 其他.
// 省略部分代码……
// 首先, 注册PriorityOrdered实现的BeanPostProcessors.
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
// 其次, 注册Ordered实现的BeanPostProcessors.
List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>();
for (String ppName : orderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
orderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
sortPostProcessors(orderedPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, orderedPostProcessors);
// 然后,注册其他的BeanPostProcessors
List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
for (String ppName : nonOrderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
nonOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);
// 最后, 重新注册所有内部BeanPostProcessor.
sortPostProcessors(internalPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, internalPostProcessors);
// 重新注册用于将内部bean检测为ApplicationListener的后处理器,将其移至处理器链的末尾(用于拾取代理等).
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}
——> private static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanPostProcessor> postProcessors) {
for (BeanPostProcessor postProcessor : postProcessors) {
beanFactory.addBeanPostProcessor(postProcessor);
}
}
——> public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) {
// 省略日志部分代码……
this.beanPostProcessors.add(beanPostProcessor);
}
——> private final List<BeanPostProcessor> beanPostProcessors = new CopyOnWriteArrayList<>();
实现一个增强处理器,只需要实现BeanPostProcessor接口。Spring对于这类增强处理器,使用CopyOnWriteArrayList进行存储,间接的说明了这类数据是读多写少的。
这一阶段需要将之前阶段注入的Bean进行实例化(调用构造),除此之外在实例化过程中实现增强。
// 调用过程从AbstractApplicationContext.refresh()开始finishBeanFactoryInitialization(beanFactory);
——> protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// 省略部分组件初始化代码……
// 实例化所有剩余的(非延迟初始化)单例
beanFactory.preInstantiateSingletons();
}
// 查看preInstantiateSingletons的默认实现DefaultListableBeanFactory
——> public void preInstantiateSingletons() throws BeansException {
// 省略获取所有实例代码……
// 非惰性单例bean的初始化...
for (String beanName : beanNames) {
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
if (isFactoryBean(beanName)) {
Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
if (bean instanceof FactoryBean) {
final FactoryBean<?> factory = (FactoryBean<?>) bean;
boolean isEagerInit;
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>)
((SmartFactoryBean<?>) factory)::isEagerInit,
getAccessControlContext());
}
else {
isEagerInit = (factory instanceof SmartFactoryBean &&
((SmartFactoryBean<?>) factory).isEagerInit());
}
if (isEagerInit) {
getBean(beanName);
}
}
}
else {
getBean(beanName);
}
}
}
// 触发所有适用bean的初始化后回调...
// 忽略部分代码……
}
// 我们只看关键代码,Bean如何实例化的?
——> public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
}
// doGetBean代码比较长,主要区别是否有构造方法,有参/无参构造、单例/原型等,最终调用createBean进行创建,这里就不贴代码了。
//IDEA Ctrl+Alt+B 查看createBean的默认实现AbstractAutowireCapableBeanFactory
——> protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
// createBean中主要是为后阶段反射以及后置增强做准备工作。
// 部分准备代码……
try {
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isTraceEnabled()) {
logger.trace("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
// 忽略catch……
}
——> protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {
// 忽略部分代码……
// 允许后处理器修改合并的bean定义。
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Post-processing of merged bean definition failed", ex);
}
mbd.postProcessed = true;
}
}
// 主要解决生成Bean实例的循环依赖问题
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isTraceEnabled()) {
logger.trace("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
// 初始化bean实例.
Object exposedObject = bean;
try {
populateBean(beanName, mbd, instanceWrapper);
// 初始化给定的bean实例,应用工厂回调以及init方法和bean后处理器
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
// 省略部分代码……
return exposedObject;
}
——> protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
// 调用实现Aware接口方法,只针对三种Aware接口BeanNameAware、BeanClassLoaderAware、BeanFactoryAware
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
}
else {
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
// Bean前置增强处理器
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
// 反射生成Bean实例
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
if (mbd == null || !mbd.isSynthetic()) {
// Bean前置增强处理器
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
——> public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) {
Object current = processor.postProcessBeforeInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
——> public List<BeanPostProcessor> getBeanPostProcessors() {
return this.beanPostProcessors;
}
还记得Spring注入Bean增强处理器时存放的CopyOnWriteArrayList名称吗?是不是也是beanPostProcessors?所以,我们来总结一下。
通过以上分析,我们可以知道,加载的过程大概是这样的:
从上诉分析中我们了解到,Spring IOC采用一个ConcurrentHashMap来存储BeanDefinition(Bean实例)。
同时,为所有的Bean提供了Bean的前置/后置增强处理器,而且只需要实现BeanPostProcessor接口IOC就会在启动时我们执行对应的增强方法。
上面这两点恰恰就是AOP的关键,接下来我们就看看AOP在Bean的增强处理器中做了什么事。
// 1、MySpringConfig加上@EnableAspectJAutoProxy标注
@Aspect
@Component
public class LoginAop {
/**
* @Pointcut 定义切入点
*
* @Pointcut(value = "execution (* com.lming.service.*..*.*(..))") service.所有子包 下面所有的类所有的方案
*/
@Pointcut("execution (* com.lming.service..*.*(..))")
public void loginAop() {
}
/**
* 前置通知
*
* @param joinPoint
*/
@Before("loginAop()")
public void doBefore(JoinPoint joinPoint) {
System.out.println(">>>>>>>前置通知<<<<<<<<<<< ");
}
/**
* 后置通知
*/
@After("loginAop()")
public void doAfter(JoinPoint joinPoint) {
System.out.println(">>>>>>>>后置通知<<<<<<<<<");
}
/**
* 环绕通知
*
* @param joinPoint
*/
@Around("loginAop()")
public void around(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println(">>>>环绕通知之前执行...>>>>>>");
joinPoint.proceed();// 执行目标方案
System.out.println(">>>>环绕通知之后执行...>>>>>>");
}
/**
* 运行通知
*/
@AfterReturning("loginAop()")
public void afterReturning(JoinPoint joinPoint) {
System.out.println("运行通知执行.....");
}
/**
* 异常通知
*
* @param joinPoint
*/
@AfterThrowing("loginAop()")
public void afterThrowing(JoinPoint joinPoint) {
System.out.println(">>>>>异常通知");
}
}
@Component
public class MemberServiceImpl implements InitializingBean, MemberService {
public MemberServiceImpl() {
System.out.println("执行无参构造函数....");
}
public String login(String userName, String passWord) {
int i = 1 / 0;
System.out.println(">>>>正在执行登陆业务逻辑>>>>> userName:" + userName + "passWord:" + passWord);
return ">>>>登陆业务逻辑..<<<<";
}
public void afterPropertiesSet() throws Exception {
System.out.println("执行自定义bean的init方法");
}
}
public interface MemberService {
public String login(String userName, String passWord);
}
分析一个框架的源码,首先需要知道它解决了什么问题、怎么使用的、了解他的大致原理,这在我们分析源码时是不可或缺的知识。
随后,分析源码首先需要有一个目的,然后找到入口,步步深入,并记录整个过程,这也是非常重要的,特别想面对Spring这种代码非常紧密的框架时,书签笔迹可以帮你快速定位代码。
目的: AOP在Bean的增强处理器中做了什么事?如何实现的切面编程?
入口: @EnableAspectJAutoProxy
@Import(AspectJAutoProxyRegistrar.class)
// ImportBeanDefinitionRegistrar 手动注入
——> class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(
AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
AnnotationAttributes enableAspectJAutoProxy =
AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);
if (enableAspectJAutoProxy != null) {
if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
// 将创建好的AOP代理注入到IOC,BeanName = internalAutoProxyCreator
AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
}
if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
}
}
}
}
——> public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry) {
return registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry, null);
}
// 注入了AnnotationAwareAspectJAutoProxyCreator
——> public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(
BeanDefinitionRegistry registry, @Nullable Object source) {
return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
}
@EnableAspectJAutoProxy注解最终注入了AnnotationAwareAspectJAutoProxyCreator类。
这时候线索中断了,接下来应该调用哪个方法呢?
我们查看一下AnnotationAwareAspectJAutoProxyCreator类图:
我们可以发现在AnnotationAwareAspectJAutoProxyCreator的类图中实现了BeanPostProcessor、ProxyConfig4、BeanFactoryAware5 等几个超类。
在IOC中我们叙述过,实现BeanPostProcessor可以对Bean进行增强。IOC在第三阶段刷新上下文时会调用所有BeanPostProcessor实现的前置增强postProcessBeforeInitialization以及后置增强方法postProcessAfterInitialization。
也就是说,AOP这时候注入的AnnotationAwareAspectJAutoProxyCreator类中(间接)实现了这两个方法,并且在IOC刷新上下文时会被调用,所以找到它们就可以继续分析。
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) {
return bean;
}
// 如果Bean被子类标识为要代理的Bean,则使用配置的拦截器创建代理。
@Override
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
if (bean != null) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (this.earlyProxyReferences.remove(cacheKey) != bean) {
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
最终,我们在AbstractAutoProxyCreator中找到了他们,AOP在其前置增强中并未做任何操作,所以我们关注后置增强,通过标注我们可以发现它是在创建一个代理。
我们知道代理分为两种,动态代理和静态代理6,这里的程序必然是使用动态代理,那么动态代理又分为两种方式创建JDK、CGlib动态代理,AOP是采用的何种方式进行创建的呢?
继续调用链:
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
return bean;
}
if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
return bean;
}
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
// 如果有建议,请创建代理。
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
if (specificInterceptors != DO_NOT_PROXY) {
this.advisedBeans.put(cacheKey, Boolean.TRUE);
Object proxy = createProxy(
bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
——> protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
@Nullable Object[] specificInterceptors, TargetSource targetSource) {
// 依靠是否具有实现类(setProxyTargetClass),判断使用JDK还是CGlib动态代理
if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
}
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.copyFrom(this);
if (!proxyFactory.isProxyTargetClass()) {
if (shouldProxyTargetClass(beanClass, beanName)) {
// 设置代理类型
proxyFactory.setProxyTargetClass(true);
}
else {
evaluateProxyInterfaces(beanClass, proxyFactory);
}
}
Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
proxyFactory.addAdvisors(advisors);
proxyFactory.setTargetSource(targetSource);
customizeProxyFactory(proxyFactory);
proxyFactory.setFrozen(this.freezeProxy);
if (advisorsPreFiltered()) {
proxyFactory.setPreFiltered(true);
}
return proxyFactory.getProxy(getProxyClassLoader());
}
——> public Object getProxy(@Nullable ClassLoader classLoader) {
return createAopProxy().getProxy(classLoader);
}
我们首先观察AOP是如何选用何种方式创建代理类的,再来看具体的创建过程。
protected final synchronized AopProxy createAopProxy() {
if (!this.active) {
activate();
}
return getAopProxyFactory().createAopProxy(this);
}
// 查看createAopProxy(this)的默认实现DefaultAopProxyFactory
——> public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
Class<?> targetClass = config.getTargetClass();
if (targetClass == null) {
throw new AopConfigException("TargetSource cannot determine target class: " +
"Either an interface or a target is required for proxy creation.");
}
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
return new JdkDynamicAopProxy(config);
}
return new ObjenesisCglibAopProxy(config);
}
else {
return new JdkDynamicAopProxy(config);
}
}
所以我们可以得知,Spring AOP依据getTargetClass选择何种动态代理来创建实例,也就是说Spring AOP根据当前类是否是一个实现类来选择具体的动态代理创建方式。
若当前Bean实例是接口的实现类,则使用JDK动态代理创建;
若当前Bean实例没有实现任何接口,则使用CGlib动态代理创建。
回到,getProxy,继续观察getProxy(classLoader)是如何创建动态代理的,查看getProxy的JdkDynamicAopProxy实现,发现JdkDynamicAopProxy实现了InvocationHandler接口。
这时候我们就明白了,通过JDK创建动态代理必须实现InvocationHandler接口,实现invoke方法,通过Proxy.newProxyInstance()即可动态的创建一个代理类。
public Object getProxy(@Nullable ClassLoader classLoader) {
if (logger.isTraceEnabled()) {
logger.trace("Creating JDK dynamic proxy: " + this.advised.getTargetSource());
}
Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
}
CglibAopProxy的getProxy()实现调用了getCallbacks(),getCallbacks()根据ProxyConfig4中targetSource判断使用什么方式创建代理类。
Cglib方式默认提供两种静态内部内实现,StaticUnadvisedExposedInterceptor(单例)、DynamicUnadvisedExposedInterceptor(原型),根据targetSource判断Bean实例是单例还是原型,选择不同的方式管理代理类7。
最后,我们获取到了代理类对象的话,就可以在invoke方法中,拦截切面配置的需要织入的方法,对其进行前置/后置/异常/环绕/事务等增强操作。
但是,这些增强并不是无需执行的,那么Spring怎么保证这些增强执行顺序的呢?Spring通过递归实现了一个调用链,通过控制递归的条件可以保证不同类型增强代码的链型执行顺序。
Spring AOP通过IOC提供实现BeanPostProcessor接口的来执行后置增强方法,在后置增强方法中对实例Bean创建代理对象,并根据实例是否为接口实现类来判断采用JDK还是CGlib动态代理。
当被代理的对象的方法执行时,判断是否属于需要织入切面的方法,切面配置由IOC刷新上下文是注入容器。
AOP是支持多种增强的(前置、后置、异常、环绕等),而其执行的顺序则是通过递归实现的调用链设计模式,保证不同增强代码的链型执行顺序。
本文重点考量IOC、AOP的源码实现以及它们之间的内在联系,忽略了其他的散项代码。Spring中还包含了非常多的设计模式以及优秀的设计理念,这是值得我们仔细考量的,比如AOP中的调用链模式、Bean实例的循环依赖问题等等。
有兴趣的同学就去干它吧!
好啦!本文到这里就结束啦,篇幅比较长,耐心阅读,相信你会有所得~
差点忘了,最后的分析图,赶紧贴上。
表示针对每次请求都会产生一个新的Bean对象,并且该Bean对象仅在当前Http请求内有效。 ↩︎
作用域表示煤气请求都会产生一个新的Bean对象,并且该Bean仅在当前Http session内有效。 ↩︎
@ComponentScan中的includeFilters、excludeFilters都将在此时被解析。 ↩︎
ProxyConfigAOP创建代理的配置API。 ↩︎ ↩︎
BeanFactoryAware实现了BeanFactoryAware接口的bean,可以直接通过beanfactory来访问spring的容器。 ↩︎
静态代理需要生成代理类,动态代理可以通过字节码技术动态构建。 ↩︎
对应到实例中就是LoginAop。 ↩︎