查看spring源码方法
1,使用intellJ IDEA 反编译class文件,反编译过来的文件不能编辑,也没有注释。
2,使用maven自动下载下来的,此时的文件也不能编辑,有注释。
3,在github上下载spring源码,然后在本地构建。
第3中种方式是极力推荐的方式
AnnotationConfigApplicationContext 注解配置应用上下文
下面这行代码就会把spring所有的前提环境都准备好,bean工厂,容器以及对象的实例化都会准备好
AnnotationConfigApplicationContext actxt = new AnnotationConfigApplicationContext(initalizespring.AppConfig.class);
下面我们使用javaConfig技术,根据上面actxt对象的创建来进入spring的源码世界吧!
/**
* Create a new AnnotationConfigApplicationContext, deriving bean definitions
* from the given component classes and automatically refreshing the context.
* @param componentClasses one or more component classes — for example,
* {@link Configuration @Configuration} classes
*/
public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
// this()中会调用父类的构造方法,然后才调用子类的构造方法,然后才调用到这里
// 在自己的构造方法中初始化一个读取器和扫描器
this();
register(componentClasses);
refresh();
}
其中this()中源码如下:
/**
* Create a new AnnotationConfigApplicationContext that needs to be populated
* through {@link #register} calls and then manually {@linkplain #refresh refreshed}.
*/
public AnnotationConfigApplicationContext() {
// AnnotationConfigApplicationContext有父类,故而这里先调用父类的构造方法,然后才调用子类的构造方法
// 创建一个读取用注解标记的bean定义的读取器,此读取器用于读取有注解的bean
// 什么是BeanDefinition???描述spring管理的bean的对象,类似于用class对象描述某一个类
this.reader = new AnnotatedBeanDefinitionReader(this); //reader的类型是AnnotatedBeanDefinitionReader
this.scanner = new ClassPathBeanDefinitionScanner(this); //scanner的类型是ClassPathBeanDefinitionScanner
}
构造方法会首先调用父类的构造方法,AnnotationConfigApplicationContext的父类是GenericApplicationContext,GetionContext的构造方法做了以下事情:没错就是初始化了初始化了spring的bean工厂,因此,环境上下文有就有spring的BeanFactory
public class GenericApplicationContext extends AbstractApplicationContext implements BeanDefinitionRegistry {
private final DefaultListableBeanFactory beanFactory;
/**
* Create a new GenericApplicationContext.
* @see #registerBeanDefinition
* @see #refresh
*/
public GenericApplicationContext() {
this.beanFactory = new DefaultListableBeanFactory();
}
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
throws BeanDefinitionStoreException {
//所谓注册即是将beanName, beanDefinition传入工厂的beanDefinitionMap中
this.beanFactory.registerBeanDefinition(beanName, beanDefinition);
}
}
在GenericApplicationContext中还有一个比较重要的方法:将beanName,BD对象注册到beanFactory,也就是放入bean工厂的beanDefinitionMap中,这里这是先讲到环境上下文可以注册这个功能,什么时候注册后面会讲到。
下面我们接着初始化环境上下文的下一步讲解:初始化new AnnotatedBeanDefinitionReader(this)和new ClassPathBeanDefinitionScanner(this)
reader读取器的类型是AnnotatedBeanDefinitionReader,读取被加了注解的bean,AnnotatedBeanDefinition类继承了BeanDefinition。BeanDefinition是spring中bean的定义,它类似于Class类,每个类都有一个Class对象,如果被spring管理,spring使用BeanDefinition来描述它管理的类。下面是AnnotatedBeanDefinitionReader类中的高能部分:
// 注册器,可以理解为环境上下文对象
private final BeanDefinitionRegistry registry;
// beanName生成器,默认是取类名且将第一个字母小写,作为beanName
private BeanNameGenerator beanNameGenerator = new AnnotationBeanNameGenerator();
private ScopeMetadataResolver scopeMetadataResolver = new AnnotationScopeMetadataResolver();
// 由此构造方法即可得知:环境上下文对象与BeanDefinitionRegistry等同,你中有我,我中有你。
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) {
this(registry, getOrCreateEnvironment(registry));
}
// 还记得初始化环境上下文时会调用register(componentClasses)方法,本质就是调用这个,它可以接受多个对象。
public void register(Class<?>... componentClasses) {
for (Class<?> componentClass : componentClasses) {
registerBean(componentClass);
}
}
因此,reader是读取被加了注解的类的描述bean的读取器
- spring管理着四种bean,
- 被注解的bean
- 使用xml描述的bean
- 使用@bean的bean
- spring内部使用的bean
//scanner的类型是ClassPathBeanDefinitionScanner,扫描器。
第一个代码块中中执行register(componentClasses)的代码如下:
/**
* 注册一个或多个component类去注册,但是注册之后必须手动refresh去触发容器解析注解
* 此方法有两个作用,1,是将配置类注册如AppConfig类,一般是作为构造方法的入参,此时无需手动refresh
* 2,将某个未被spring注解的类交给spring去管理,注册后需要手动refresh
* Register one or more component classes to be processed.
* <p>Note that {@link #refresh()} must be called in order for the context
* to fully process the new classes.
* @param componentClasses one or more component classes — for example,
* {@link Configuration @Configuration} classes
* @see #scan(String...)
* @see #refresh()
*/
@Override
public void register(Class<?>... componentClasses) {
Assert.notEmpty(componentClasses, "At least one component class must be specified");
this.reader.register(componentClasses);
}
最终上面的register(componentClasses)会变成执行这段代码:
/**
* Register a bean from the given bean class, deriving its metadata from
* class-declared annotations.
* @param beanClass the class of the bean
* @param instanceSupplier a callback for creating an instance of the bean
* (may be {@code null})
* @param name an explicit name for the bean
* @param qualifiers specific qualifier annotations to consider, if any,
* in addition to qualifiers at the bean class level
* @param definitionCustomizers one or more callbacks for customizing the
* factory's {@link BeanDefinition}, e.g. setting a lazy-init or primary flag
* @since 5.0
*/
<T> void doRegisterBean(Class<T> beanClass, @Nullable Supplier<T> instanceSupplier, @Nullable String name,
@Nullable Class<? extends Annotation>[] qualifiers, BeanDefinitionCustomizer... definitionCustomizers) {
/**
* 根据指定的bean创建一个AnnotationGenericBeanDefinition
* 这个AnnotationGenericBeanDefinition可以理解为一个数据结构
* 它包含了类的其他信息,比如一些元信息,scope, lazy等
*/
AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);
/**
* 判断这个类是否需要跳过解析
* 通过代码可以知道spring判断是否跳过解析,主要判断类有没有添加注解,abd.getMetadata()获取元数据
*/
if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
return;
}
abd.setInstanceSupplier(instanceSupplier);
//得到类的作用域
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
//把类的作用域添加到数据结构中
abd.setScope(scopeMetadata.getScopeName());
//通过beanNameGenerator生成类的对象的名字
String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));
/**
* 处理类中的通用注解
* 主要处理Lazy,DependsOn,Primary,Role,Description五种注解
* 处理完成后依然把他们添加进数据结构
*/
AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
/**
* 如果向容器注册注解bean定义时,使用了额外的限定符注解则解析
* 关于Qualifier和Primary前面的课当中讲过,主要涉及spring的自动装配
* 这里需要注意的视byName和qualifier视Annotation类型的数组,里面不仅仅是Qualifier注解
* 理论上里面存的是一切注解,所以可以看到下面的代码spring去循环了这个数组
* 然后依次判断注解当中是否包含了Primary和Lazy
* qualifiers对象其实是null的,所以使用new AnnotationConfigApplicationContext(initalizespring.AppConfig.class)时并不会执行下面的代码
*/
if (qualifiers != null) {
for (Class<? extends Annotation> qualifier : qualifiers) {
if (Primary.class == qualifier) {
abd.setPrimary(true);
} else if (Lazy.class == qualifier) {
abd.setLazyInit(true);
} else {
abd.addQualifier(new AutowireCandidateQualifier(qualifier));
}
}
}
for (BeanDefinitionCustomizer customizer : definitionCustomizers) {
customizer.customize(abd);
}
// BeanDefinitionHolder 这个也是个数据结构,可以理解为一个map对象
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
/**
* ScopedProxyMode 知识点比较复杂,需要结合web去理解,现在暂时搁置此问题,后面讲解springmvc时在说
* 代理模型
*/
definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
/**
* 把上述的数据结构注册给registry
* registry就是AnnotationConfigApplication
* AnnotationConfigApplication在初始化的时候通过调用父类的构造方法
* 实例化一个DefaultListableBeanFactory
* registerBeanDefinition()方法就是把definitionHolder这个数据结构包含的信息注册到
* DefaultListableBeanFactory这个工厂
*/
BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
}
将definitionHolder注册的代码如下,也就是上面最后一行代码:这也验证了前面讲解register时它拥有的注册功能,将BD注册进beanDefinitionMap中。
/**
* Register the given bean definition with the given bean factory.
* @param definitionHolder the bean definition including name and aliases
* @param registry the bean factory to register with
* @throws BeanDefinitionStoreException if registration failed
*/
public static void registerBeanDefinition(BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry) throws BeanDefinitionStoreException {
// Register bean definition under primary name.
String beanName = definitionHolder.getBeanName();
registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
// Register aliases for bean name, if any.
/**
* 处理别名
*/
String[] aliases = definitionHolder.getAliases();
if (aliases != null) {
for (String alias : aliases) {
registry.registerAlias(beanName, alias);
}
}
}
registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition())的源码如下,下面代码在DefaultListableBeanFactory中,这个类就是大名鼎鼎的spring的bean工厂,由它来创建对象。
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
throws BeanDefinitionStoreException {
Assert.hasText(beanName, "Bean name must not be empty");
Assert.notNull(beanDefinition, "BeanDefinition must not be null");
if (beanDefinition instanceof AbstractBeanDefinition) {
try {
((AbstractBeanDefinition) beanDefinition).validate();
} catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
"Validation of bean definition failed", ex);
}
}
BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);
if (existingDefinition != null) {
if (!isAllowBeanDefinitionOverriding()) {
throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition);
} else if (existingDefinition.getRole() < beanDefinition.getRole()) {
// e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE
if (logger.isInfoEnabled()) {
logger.info("Overriding user-defined bean definition for bean '" + beanName +
"' with a framework-generated bean definition: replacing [" +
existingDefinition + "] with [" + beanDefinition + "]");
}
} else if (!beanDefinition.equals(existingDefinition)) {
if (logger.isDebugEnabled()) {
logger.debug("Overriding bean definition for bean '" + beanName +
"' with a different definition: replacing [" + existingDefinition +
"] with [" + beanDefinition + "]");
}
} else {
if (logger.isTraceEnabled()) {
logger.trace("Overriding bean definition for bean '" + beanName +
"' with an equivalent definition: replacing [" + existingDefinition +
"] with [" + beanDefinition + "]");
}
}
this.beanDefinitionMap.put(beanName, beanDefinition);
} else {
if (hasBeanCreationStarted()) {
// Cannot modify startup-time collection elements anymore (for stable iteration)
synchronized (this.beanDefinitionMap) {
this.beanDefinitionMap.put(beanName, beanDefinition);
List<String> updatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() + 1);
updatedDefinitions.addAll(this.beanDefinitionNames);
updatedDefinitions.add(beanName);
this.beanDefinitionNames = updatedDefinitions;
removeManualSingletonName(beanName);
}
} else {
// Still in startup registration phase
this.beanDefinitionMap.put(beanName, beanDefinition); // 使用一个map维护所有spring管理的bean
this.beanDefinitionNames.add(beanName); // beanDefinitionNames是List<String>类型,存放所有bean的名字beanName
removeManualSingletonName(beanName); // 为了去重
}
this.frozenBeanDefinitionNames = null;
}
if (existingDefinition != null || containsSingleton(beanName)) {
resetBeanDefinition(beanName);
}
}
beanDefinitionMap存放完毕后,里面会存在多个对象(除了业务对象以外的对象),他们就是著名的spring的后置处理器,它是在this.reader = new AnnotatedBeanDefinitionReader(this)初始化时创建的。
上面讲解这么多还没有对象产生,都是起初register(componentClasses)引发的,到现在它主要是为了beanDefinitionHolder放入beanDefinitionMap,将beanName放入beanDefinitionNames。讲解这么多,其实spring这是还未开始初始化业务的bean,只是生成他们的业务对象的描述对象,并交给了bean工厂管理,可以这么认为,之前所有的只是给bean工厂准备好了原料,真正开始生产bean是在refresh()时才开始的。
调用getBean()方法时会调用refresh()方法里面的逻辑。
refresh()方法初始化spring环境,refresh()方法在AbstractApplicationContext即上下文中。如
看完 register(componentClasses),我们再看看refresh()方法做了哪些事情
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
/**
* 准备工作包括设置启动时间,是否激活标识位,是否初始化属性源
*/
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory);
// Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);
// Initialize message source for this context.
initMessageSource();
// Initialize event multicaster for this context.
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
onRefresh();
// Check for listener beans and register them.
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
finishRefresh();
}catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
// Destroy already created singletons to avoid dangling resources.
destroyBeans();
// Reset 'active' flag.
cancelRefresh(ex);
// Propagate exception to caller.
throw ex;
} finally {
// Reset common introspection caches in Spring's core, since we
// might not ever need metadata for singleton beans anymore...
resetCommonCaches();
}
}
}
其中 prepareRefresh()的功能只是准备工作包括设置启动时间,是否激活标识位,是否初始化属性源,没有那么重要。
/**
* 准备工作包括设置启动时间,是否激活标识位,是否初始化属性源
* Prepare this context for refreshing, setting its startup date and
* active flag as well as performing any initialization of property sources.
*/
protected void prepareRefresh() {
// Switch to active.
this.startupDate = System.currentTimeMillis();
this.closed.set(false); // 当前类是AbstractApplicationContext类,这里设置非关闭状态和激活的状态
this.active.set(true);
if (logger.isDebugEnabled()) {
if (logger.isTraceEnabled()) {
logger.trace("Refreshing " + this);
}
else {
logger.debug("Refreshing " + getDisplayName());
}
}
// Initialize any placeholder property sources in the context environment.
/**
* 默认不做任何事情,留给子类去实现。
*/
initPropertySources();
// Validate that all properties marked as required are resolvable:
// see ConfigurablePropertyResolver#setRequiredProperties
// getEnvironment()获取环境
getEnvironment().validateRequiredProperties();
// Store pre-refresh ApplicationListeners...
if (this.earlyApplicationListeners == null) {
this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
}
else {
// Reset local application listeners to pre-refresh state.
this.applicationListeners.clear();
this.applicationListeners.addAll(this.earlyApplicationListeners);
}
// Allow for the collection of early ApplicationEvents,
// to be published once the multicaster is available...
this.earlyApplicationEvents = new LinkedHashSet<>();
}
看完prepareRefresh(),我们在看refresh里的下面一步,获取bean之前的bean工厂DefaultListableBeanFactory:
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); // beanFactory得到的便是DefaultListableBeanFactory
然后下面进入高能区prepareBeanFactory(beanFactory):
/**
* 配置其标准特征,比如上下文的加载器和post-processors的回调
* Configure the factory's standard context characteristics,
* such as the context's ClassLoader and post-processors.
* 此处的beanFactory几乎等同于DefaultListableBeanFactory
* @param beanFactory the BeanFactory to configure
* 此处的入参beanFactory就是spring的bean工厂,它用来产生对象
*/
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// Tell the internal bean factory to use the context's class loader etc.
// 告诉工厂需要使用的类加载器
beanFactory.setBeanClassLoader(getClassLoader());
// 表达式解释器
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
// Configure the bean factory with context callbacks.
// 添加一个后置处理器
// 这些后置处理器允许程序员在spring初始化bean时干涉,AOP就是使用了后置处理器技术
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
// BeanFactory interface not registered as resolvable type in a plain factory.
// MessageSource registered (and found for autowiring) as a bean.
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
beanFactory.registerResolvableDependency(ApplicationContext.class, this);
// Register early post-processor for detecting inner beans as ApplicationListeners.
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
// Detect a LoadTimeWeaver and prepare for weaving, if found.
if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
// Set a temporary ClassLoader for type matching.
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
// Register default environment beans.
if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
}
if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
}
if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
}
}
spring的后置处理器有7种,其中ApplicationContextAwareProcessor只是其中一种中的一个,它实现了BeanPostProcessor,它是bean后置处理器
/**
* BeanPostProcessor是spring框架通过的一个扩展类点(有七个)
* 通过BeanPostProcessor接口,程序员就可以插手bean实例化的过程,从而减轻了beanFactory的负担
* 需要进行说明的是这个接口的实现可以有多个,这样这多个实现会形成一个列表,然后依次执行
* 比如AOP就是在Bean实例化后期间将切面逻辑织入bean实例中的,和IOC容器建立联系
* spring本身也提供了很多BeanPostProcessor的实现,它的实现类复杂得令人发指,它们是spring自己添加的容器中的
* 常见的实现类有
* 1,ApplicationContextAwareProcessor,它的作用是当某个业务类实现了它时,它会自动将ApplicationContext注入
*,2,InstantiationAwareBeanPostProcessor 用于处理自定义的初始化方法和销毁方法
* 之前讲过spring提供了三种自定义初始化和销毁的方法,分别是
* a,通过给bean指定init-method和destroy-method属性
* b,实现InitializingBean接口和实现DisposableBean
* c, @PostConstruct和@PreDestroy
*
* 3
*/
public interface BeanPostProcessor {
@Nullable
default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
@Nullable
default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
}
BeanFactoryPostProcessor bean工厂后置处理器
那么添加beanPostProcessor后置处理器是干嘛呢,它的功能或者说作用是什么??
下面我们以ApplicationContextAwareProcessor后置处理器来说明,它实现了BeanPostProcessor接口,有两个方**法:
@Override
@Nullable
public Object postProcessBeforeInitialization(final Object bean, String beanName) throws BeansException {
AccessControlContext acc = null;
if (System.getSecurityManager() != null &&
(bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware ||
bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware ||
bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware)) {
acc = this.applicationContext.getBeanFactory().getAccessControlContext();
}
if (acc != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareInterfaces(bean);
return null;
}, acc);
}
else {
invokeAwareInterfaces(bean);
}
return bean;
}
private void invokeAwareInterfaces(Object bean) {
if (bean instanceof Aware) {
if (bean instanceof EnvironmentAware) {
((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment());
}
if (bean instanceof EmbeddedValueResolverAware) {
((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(this.embeddedValueResolver);
}
if (bean instanceof ResourceLoaderAware) {
((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext);
}
if (bean instanceof ApplicationEventPublisherAware) {
((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext);
}
if (bean instanceof MessageSourceAware) {
((MessageSourceAware) bean).setMessageSource(this.applicationContext);
}
if (bean instanceof ApplicationContextAware) {
((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
}
}
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) {
return bean;
}
由上方标记代码可以,会将应用上下文setter给bean(实现某接口)的属性
第二种后置处理器BeanFactoryPostProcessor,可以在创建bean时修改bd的一些属性,例如,某些全部是原型,然后某些需要改成单例,便可以自己写一个bean工厂后置处理器来实现BeanFactoryPostProcessor,然后重写这个接口的方法,获取到工厂,取到自己想要修改的bean的bd,修改bd的scop属性即可。不多说了,下面我手写了一个自己的bean工厂后置处理器。
package main.java.initalizespring;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.stereotype.Component;
@Component
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
BeanDefinition newsDaoBd = beanFactory.getBeanDefinition("newsDao");
newsDaoBd.setScope("singleton");
}
}
手写的后置处理器一定要在类上加上注解,交给spring管理,这样就能起到干涉bean工厂创建对象了。
其他后置处理器就交给读者自己去研读源码吧,方法和思维都差不多。
值得说明的是当自己定义了多个后置处理器时,此时后置处理器犹如形成了列表一样,会一个接着一个执行的。