在编译好的源码工程中创建测试model
几个测试类,就写在一起了
@ComponentScan("com.liaoxiang")
@Configuration
public class AppConfig {
}
@Component
public class User {
public void info(){
System.out.println("Hello Spring");
}
}
public class Test {
public static void main(String[] args) {
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);
User user = (User) ac.getBean("user");
user.info();
}
}
从测试方法new AnnotationConfigApplicationContext(AppConfig.class)
,
进入AnnotationConfigApplicationContext
类的构造方法,下面从这三行代码开始分析
public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
//1、调用自身无惨构造方法
this();
//2
register(annotatedClasses);
//3
refresh();
}
this()
在执行本类的构造器之前,会执行父类的构造器
/**
* Create a new GenericApplicationContext.
* @see #registerBeanDefinition
* @see #refresh
* 创建spring bean工厂
*/
public GenericApplicationContext() {
this.beanFactory = new DefaultListableBeanFactory();
}
简单看一下DefaultListableBeanFactory
里定义的一些成员变量,后面用到了再说
/**
* Spring's default implementation of the {@link ConfigurableListableBeanFactory}
* and {@link BeanDefinitionRegistry} interfaces: a full-fledged bean factory
* based on bean definition metadata, extensible through post-processors.
*
* Typical usage is registering all bean definitions first (possibly read
* from a bean definition file), before accessing beans. Bean lookup by name
* is therefore an inexpensive operation in a local bean definition table,
* operating on pre-resolved bean definition metadata objects.
*
*
Note that readers for specific bean definition formats are typically
* implemented separately rather than as bean factory subclasses:
* see for example {@link PropertiesBeanDefinitionReader} and
* {@link org.springframework.beans.factory.xml.XmlBeanDefinitionReader}.
*
*
For an alternative implementation of the
* For an alternative implementation of the
* have a look at {@link StaticListableBeanFactory}, which manages existing
* bean instances rather than creating new ones based on bean definitions.
*
* Spring的{@link ConfigurableListableBeanFactory}和{@link BeanDefinitionRegistry}接口的默认实现:
* 基于bean定义元数据的成熟bean工厂,可以通过后置处理器进行扩展。
*
* 典型的用法是在访问bean之前先注册所有bean定义(可能是从bean定义文件中读取)。
* 因此,按名称查找Bean是对本地Bean定义表进行的廉价操作,该操作对预先解析的Bean定义元数据对象进行操作。
*
* 请注意,特定bean定义格式的阅读器通常是单独实现的,而不是作为bean工厂的子类实现的:例如
* 参见{@link PropertiesBeanDefinitionReader}和{@link org.springframework.beans.factory.xml.XmlBeanDefinitionReader}。
*
* 作为的另一种实现,请查看{@link StaticListableBeanFactory},它管理现有的Bean实例,而不是根据Bean定义创建新的Bean实例。
* @author Rod Johnson
* @author Juergen Hoeller
* @author Sam Brannen
* @author Costin Leau
* @author Chris Beams
* @author Phillip Webb
* @author Stephane Nicoll
* @since 16 April 2001
* @see #registerBeanDefinition
* @see #addBeanPostProcessor
* @see #getBean
* @see #resolveDependency
*/
@SuppressWarnings("serial")
public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory
implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable {
@Nullable
private static Class<?> javaxInjectProviderClass;
static {
try {
javaxInjectProviderClass =
ClassUtils.forName("javax.inject.Provider", DefaultListableBeanFactory.class.getClassLoader());
}
catch (ClassNotFoundException ex) {
// JSR-330 API not available - Provider interface simply not supported then.
javaxInjectProviderClass = null;
}
}
/** Map from serialized id to factory instance */
/** 从序列化的id映射到工厂实例 */
private static final Map<String, Reference<DefaultListableBeanFactory>> serializableFactories =
new ConcurrentHashMap<>(8);
/** Optional id for this factory, for serialization purposes */
/** 这个工厂的可选id,用于序列化 */
@Nullable
private String serializationId;
/** Whether to allow re-registration of a different definition with the same name */
/** 是否允许用相同的名称重新注册不同的定义 */
private boolean allowBeanDefinitionOverriding = true;
/** Whether to allow eager class loading even for lazy-init beans */
/** 即使对于惰性init bean,是否允许立即加载类 */
private boolean allowEagerClassLoading = true;
/** Optional OrderComparator for dependency Lists and arrays */
/** 可选的排序器,用于依赖列表和数组 */
@Nullable
private Comparator<Object> dependencyComparator;
/** Resolver to use for checking if a bean definition is an autowire candidate */
/** 解析器,用于检查bean定义是否为自动装配候选 */
private AutowireCandidateResolver autowireCandidateResolver = new SimpleAutowireCandidateResolver();
/** Map from dependency type to corresponding autowired value */
/** 从依赖类型映射到相应的自动获取值 */
private final Map<Class<?>, Object> resolvableDependencies = new ConcurrentHashMap<>(16);
/** Map of bean definition objects, keyed by bean name */
/** bean定义对象的映射,由bean名称键控 */
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);
/** Map of singleton and non-singleton bean names, keyed by dependency type */
/** 单例和非单例Bean名称的映射,按依赖项类型进行键控 */
private final Map<Class<?>, String[]> allBeanNamesByType = new ConcurrentHashMap<>(64);
/** Map of singleton-only bean names, keyed by dependency type */
/** 仅依赖单例的bean名称的映射,按依赖项类型进行键控 */
private final Map<Class<?>, String[]> singletonBeanNamesByType = new ConcurrentHashMap<>(64);
/** List of bean definition names, in registration order */
/** bean定义名称列表,按注册顺序排列 */
private volatile List<String> beanDefinitionNames = new ArrayList<>(256);
/** List of names of manually registered singletons, in registration order */
/** 手动注册单例的名称列表,按注册顺序 */
private volatile Set<String> manualSingletonNames = new LinkedHashSet<>(16);
/** Cached array of bean definition names in case of frozen configuration */
/** 缓存的bean定义名数组,以防冻结配置 */
@Nullable
private volatile String[] frozenBeanDefinitionNames;
/** Whether bean definition metadata may be cached for all beans */
/** 是否可以缓存所有bean的bean定义元数据 */
private volatile boolean configurationFrozen = false;
}
下面执行自己的构造方法
public AnnotationConfigApplicationContext() {
this.reader = new AnnotatedBeanDefinitionReader(this);
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
在这个构造函数中初始化了两个AnnotatedBeanDefinitionReader,ClassPathBeanDefinitionScanner
后面讨论再讨论
AnnotatedBeanDefinitionReader
类的描述如下:
/**
* Convenient adapter for programmatic registration of annotated bean classes.
* This is an alternative to {@link ClassPathBeanDefinitionScanner}, applying
* the same resolution of annotations but for explicitly registered classes only.
*
* @author Juergen Hoeller
* @author Chris Beams
* @author Sam Brannen
* @author Phillip Webb
* @since 3.0
* @see AnnotationConfigApplicationContext#register
*/
public class AnnotatedBeanDefinitionReader {}
根据名字可以猜测其作用是读取AnnotatedBeanDefinition
类型的类,看一下果然有AnnotatedBeanDefinition
它是一个接口,继承了BeanDefinition
,BeanDefinition
描述如下:
可以看出BeanDefinition
在Spring中用来描述一个bean实例,包括了属性值,构造函数参数值等,在其具体实现类(XxxBeanDefinition)中可以获得关于Bean实例的更多信息
下面看一下在new AnnotatedBeanDefinitionReader(this)
的时候做了什么,首先进入AnnotatedBeanDefinitionReader
一个参数的构造方法,然后调用两个参数的构造方法:
/**
* Create a new {@code AnnotatedBeanDefinitionReader} for the given registry.
* If the registry is {@link EnvironmentCapable}, e.g. is an {@code ApplicationContext},
* the {@link Environment} will be inherited, otherwise a new
* {@link StandardEnvironment} will be created and used.
* @param registry the {@code BeanFactory} to load bean definitions into,
* in the form of a {@code BeanDefinitionRegistry}
* @see #AnnotatedBeanDefinitionReader(BeanDefinitionRegistry, Environment)
* @see #setEnvironment(Environment)
* ================================================================================================================!!
* 传递过来的是:AnnotationConfigApplicationContext对象
*/
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) {
this(registry, getOrCreateEnvironment(registry));
}
/**
* Create a new {@code AnnotatedBeanDefinitionReader} for the given registry and using
* the given {@link Environment}.
* @param registry the {@code BeanFactory} to load bean definitions into,
* in the form of a {@code BeanDefinitionRegistry}
* @param environment the {@code Environment} to use when evaluating bean definition
* profiles.
* @since 3.1
* ================================================================================================================!!
*/
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);
}
在第二个构造方法中调用了AnnotationConfigUtils
的registerAnnotationConfigProcessors()
方法,进入到AnnotationConfigUtils类中看一下
/**
* Register all relevant annotation post processors in the given registry.
* @param registry the registry to operate on
*/
public static void registerAnnotationConfigProcessors(BeanDefinitionRegistry registry) {
registerAnnotationConfigProcessors(registry, null);
}
/**
* Register all relevant annotation post processors in the given registry.
* @param registry the registry to operate on
* @param source the configuration source element (already extracted)
* that this registration was triggered from. May be {@code null}.
* @return a Set of BeanDefinitionHolders, containing all bean definitions
* that have actually been registered by this call
* =================================================================================================================!!
*/
public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
BeanDefinitionRegistry registry, @Nullable Object source) {
// 获取到工厂,判断后向工厂中set一些对象
DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
if (beanFactory != null) {
if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
// 添加一个排序器
beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
}
if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
// 处理延迟加载的
beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
}
}
Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);
/**
* 构造了7个后置处理器的BeanDefinition,放到BeanDefinitionHolder中
* BeanDefinitionHolder可以类比为DefaultListableBeanFactory中的beanDefinitionMap
* ConfigurationClassPostProcessor会在下一节的3.5方法中用到
* invokeBeanFactoryPostProcessors()
*/
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));
}
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));
}
if (!registry.containsBeanDefinition(REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(RequiredAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
}
// Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor.
if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
}
// Check for JPA support, and if present add the PersistenceAnnotationBeanPostProcessor.
if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition();
try {
def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME,
AnnotationConfigUtils.class.getClassLoader()));
}
catch (ClassNotFoundException ex) {
throw new IllegalStateException(
"Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex);
}
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME));
}
if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME));
}
if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME));
}
return beanDefs;
}
/**
* 在上面的方法中被调用,返回BeanDefinitionHolder对象
* 并将bd注册到工厂中
* @param registry
* @param definition
* @param beanName
* @return
* ================================================================================================================!!
*/
private static BeanDefinitionHolder registerPostProcessor(
BeanDefinitionRegistry registry, RootBeanDefinition definition, String beanName) {
definition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
registry.registerBeanDefinition(beanName, definition);
return new BeanDefinitionHolder(definition, beanName);
}
首先进入一个参数的registerAnnotationConfigProcessors()方法,然后调用两个参数的registerAnnotationConfigProcessors()方法,在第二个方法中拿出创建好的工厂设置了一些对象进去,然后创建了一个Set集合,存放的是BeanDefinitionHolder
对象,在下面的几条判断语句中调用了很多后置处理器创建了BeanDefinition接口的实现类RootBeanDefinition的对象,然后调用上面代码中第三个方法registerPostProcessor()
在这个方法中又调用了registry.registerBeanDefinition(beanName, definition);
然后new了一个BeanDefinitionHolder
对象并返回,返回的对象被加到Set集合中
有个问题:第二个方法是有返回值的,返回的就是这个BeanDefinitionHolder
对象的集合,但是在第一个方法中并没有接收返回值作出处理,这个问题先留在这!
看一下registry.registerBeanDefinition(beanName, definition)
做了什么,打断点跟进去到了DefaultListableBeanFactory
类中的registerBeanDefinition()
方法:
在方法的最下面,将beanDefinition,beanName加入到了DefaultListableBeanFactory类中定义的成员变量中
到此处调用this(),调用自己构造器执行的new AnnotatedBeanDefinitionReader(this)代码已经执行完成
register(annotatedClasses)
进入到AnnotatedBeanDefinitionReader
doRegisterBean
方法:
下面测试创建单个对象,注释掉AppConfig
类上的@ComponentScan("com.liaoxiang")
注解,和User类上的@Component
注解,修改测试方法如下,结果同样输出打印。
public class Test {
public static void main(String[] args) {
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext();
ac.register(User.class);
ac.refresh();
User user = (User) ac.getBean("user");
user.info();
}
}
打断点看一看
abd对象包含的内容:
Generic bean: class [com.liaoxiang.bean.User]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null
进入到shouldSkip方法,可以看到metada不为null,shouldSkip方法返回false
下面接着设置关于User这个Bean的其他信息
我们先在User类上加一个注解,然后debug,看是否解析到
进入AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
获取到这些注解之后,设置到AnnotationAttributes
接下来回到AnnotatedBeanDefinitionReader
的doRegisterBean
进入到BeanDefinitionReaderUtils
当beanName为user的时候,我们在这停下来
进入到DefaultListableBeanFactory
的registerBeanDefinition()
方法
接着往下走一点
这里将beanName
作为key,将beanDefinition
作为value存入beanDefinitionMap
同时将beanName
加入beanDefinitionNames
可以看到此时的beanDefinitionMap
中已经有7个元素,这些元素就是在上面提到this中加入进去的
到这里可以看到spring通过第一步构造AnnotationConfigApplicationContext
的时候初始化了一个AnnotatedBeanDefinitionReader
对象,在执行构造方法的时候,来注册spring框架自己的BeanDefinition,然后用创建好的对象来注册一个应用程序中的BeanDefinition
refresh()
给AppConfig类加上注解@ComponentScan("com.liaoxiang")
,修改测试主方法,在refresh方法里面打断点
public class Test {
public static void main(String[] args) {
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);
User user = (User) ac.getBean("user");
user.info();
}
}
点击进入AbstractApplicationContext
类,refresh()
定义如下,给每行代码编个号,方便说明
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
//1、设置启动时间、是否激活标志位、初始化属性源(property source)配置
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
// 2、获取register方法流程中的 DefaultListableBeanFactory
// 初始化bean可以认为是从这里开始的
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// 3、Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory);
try {
// 4、Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory);
// 5、Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory);
// 6、Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);
// 7、Initialize message source for this context.
initMessageSource();
// 8、Initialize event multicaster for this context.
initApplicationEventMulticaster();
// 9、Initialize other special beans in specific context subclasses.
onRefresh();
// 10、Check for listener beans and register them.
registerListeners();
// 11、Instantiate all remaining (non-lazy-init) singletons.!!
finishBeanFactoryInitialization(beanFactory);
// 12、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);
this.active.set(true);
if (logger.isInfoEnabled()) {
logger.info("Refreshing " + this);
}
// Initialize any placeholder property sources in the context environment.
initPropertySources();
// Validate that all properties marked as required are resolvable:
// see ConfigurablePropertyResolver#setRequiredProperties
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<>();
}
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory()
拿到上面提到的工厂类:DefaultListableBeanFactory
prepareBeanFactory(beanFactory)
在拿到工厂之后,对工厂做一些准备工作,加入一些标准配置
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// 1、Tell the internal bean factory to use the context's class loader etc.
beanFactory.setBeanClassLoader(getClassLoader());
// 2、bean的表达式解释器
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
// 3、
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
// 4、 Configure the bean factory with context callbacks.添加一个bean的后置处理器
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
// 5、
beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
// 6、
beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
// 7、
beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
// 8、
beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
// 9、
beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
// 10、
beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
// BeanFactory interface not registered as resolvable type in a plain factory.
// 11、 MessageSource registered (and found for autowiring) as a bean.
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
// 12、
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
// 13、
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
// 14、
beanFactory.registerResolvableDependency(ApplicationContext.class, this);
// 15、Register early post-processor for detecting inner beans as ApplicationListeners.
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
// 16、Detect a LoadTimeWeaver and prepare for weaving, if found.
if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
// 17、
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
// 18、 Set a temporary ClassLoader for type matching.
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
// 19、Register default environment beans.
if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
}
// 20、
if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
}
// 21、
if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
}
}
addBeanPostProcessor()
方法定义在AbstractBeanFactory
抽象类中,Spring添加自己定义的后置处理器
@Override
public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) {
Assert.notNull(beanPostProcessor, "BeanPostProcessor must not be null");
// Remove from old position, if any
this.beanPostProcessors.remove(beanPostProcessor);
// Track whether it is instantiation/destruction aware
if (beanPostProcessor instanceof InstantiationAwareBeanPostProcessor) {
this.hasInstantiationAwareBeanPostProcessors = true;
}
if (beanPostProcessor instanceof DestructionAwareBeanPostProcessor) {
this.hasDestructionAwareBeanPostProcessors = true;
}
// Add to end of list
this.beanPostProcessors.add(beanPostProcessor);
}
最后,后置处理器被加入到一个beanPostProcessors
的List集合中,在此时还没有用到这些后置处理器,spring在实例化bean的时候就会循环这个list集合,执行后置处理器中的方法,从而插手bean实例化的过程
我们来看一下BeanPostProcessor
接口
/**
* Factory hook that allows for custom modification of new bean instances,
* e.g. checking for marker interfaces or wrapping them with proxies.
*
* ApplicationContexts can autodetect BeanPostProcessor beans in their
* bean definitions and apply them to any beans subsequently created.
* Plain bean factories allow for programmatic registration of post-processors,
* applying to all beans created through this factory.
*
*
Typically, post-processors that populate beans via marker interfaces
* or the like will implement {@link #postProcessBeforeInitialization},
* while post-processors that wrap beans with proxies will normally
* implement {@link #postProcessAfterInitialization}.
*
* @author Juergen Hoeller
* @since 10.10.2003
* @see InstantiationAwareBeanPostProcessor
* @see DestructionAwareBeanPostProcessor
* @see ConfigurableBeanFactory#addBeanPostProcessor
* @see BeanFactoryPostProcessor
*
* 允许自定义修改新 bean实例的工厂钩子,例如 检查标记界面或使用代理包装它们。
*
* ApplicationContexts可以在其Bean定义中自动检测BeanPostProcessor Bean,并将其应用于随后创建的任何Bean。
* 普通bean工厂允许对后置处理器进行程序化注册,适用于通过该工厂创建的所有bean。
*
* 通常,通过标记器接口等填充bean的后处理器将实现{@link #postProcessBeforeInitialization},
* 而使用代理包装bean的后置处理器通常将实现{@link #postProcessAfterInitialization}。
*/
public interface BeanPostProcessor {
/**
* Apply this BeanPostProcessor to the given new bean instance before any bean
* initialization callbacks (like InitializingBean's {@code afterPropertiesSet}
* or a custom init-method). The bean will already be populated with property values.
* The returned bean instance may be a wrapper around the original.
* The default implementation returns the given {@code bean} as-is.
* @param bean the new bean instance
* @param beanName the name of the bean
* @return the bean instance to use, either the original or a wrapped one;
* if {@code null}, no subsequent BeanPostProcessors will be invoked
* @throws org.springframework.beans.BeansException in case of errors
* @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet
* 在任何bean初始化回调(如InitializingBean的{@code afterPropertiesSet}或自定义的init-method)之前,
* 将此BeanPostProcessor应用于给定的新bean实例。
* 该bean将已经用属性值填充。
* 返回的bean实例可能是原始对象的包装。默认实现按原样返回给定的{@code bean}。
*/
@Nullable
default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
/**
* Apply this BeanPostProcessor to the given new bean instance after any bean
* initialization callbacks (like InitializingBean's {@code afterPropertiesSet}
* or a custom init-method). The bean will already be populated with property values.
* The returned bean instance may be a wrapper around the original.
* In case of a FactoryBean, this callback will be invoked for both the FactoryBean
* instance and the objects created by the FactoryBean (as of Spring 2.0). The
* post-processor can decide whether to apply to either the FactoryBean or created
* objects or both through corresponding {@code bean instanceof FactoryBean} checks.
*
This callback will also be invoked after a short-circuiting triggered by a
* {@link InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation} method,
* in contrast to all other BeanPostProcessor callbacks.
*
The default implementation returns the given {@code bean} as-is.
* @param bean the new bean instance
* @param beanName the name of the bean
* @return the bean instance to use, either the original or a wrapped one;
* if {@code null}, no subsequent BeanPostProcessors will be invoked
* @throws org.springframework.beans.BeansException in case of errors
* @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet
* @see org.springframework.beans.factory.FactoryBean
* 在任何bean初始化回调(例如InitializingBean的{@code afterPropertiesSet}或自定义的init-method)之后,
* 将此BeanPostProcessor应用于给定的新bean实例
* 该bean将已经用属性值填充。
* 返回的bean实例可能是原始实例的包装。
* 如果是FactoryBean,则将为FactoryBean实例和由FactoryBean创建的对象(从Spring 2.0开始)调用此回调。
* 后处理器可以通过相应的{@code bean instanceof FactoryBean}检查来决定是应用到FactoryBean还是创建的对象,还是两者都应用。
* 与所有其他BeanPostProcessor回调相比,此回调还将在{@link InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation}方法触发短路后被调用。
* 默认实现按原样返回给定的{@code bean}。
*/
@Nullable
default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
}
通过这个接口,我们可以插手Bean的创建过程,Spring中为这个接口提供了很多的实现类来控制Bean的创建。如果要自定义我们自己的后置处理器,可以直接实现BeanPostProcessor
接口,并加入到容器中就可以,下面是简单测试
@Component
public class MyBeanPostProcessor1 implements BeanPostProcessor, PriorityOrdered {
/**
* 这里拿到bean之后可以根据此bean创建一个代理类对象
* AOP正是通过BeanPostProcessor和IOC容器建立起了联系
* @param bean the new bean instance
* @param beanName the name of the bean
* @return
* @throws BeansException
*/
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if (beanName.equals("user")){
System.out.println("MyBeanPostProcessor的前置处理器执行1");
}
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (beanName.equals("user")){
System.out.println("MyBeanPostProcessor的后置处理器执行1");
}
return bean;
}
@Override
public int getOrder() {
return 102;
}
}
再定义一个:
@Component
public class MyBeanPostProcessor2 implements BeanPostProcessor, PriorityOrdered {
/**
* 这里拿到bean之后可以根据此bean创建一个代理类对象
* AOP正是通过BeanPostProcessor和IOC容器建立起了联系
* @param bean the new bean instance
* @param beanName the name of the bean
* @return
* @throws BeansException
*/
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if (beanName.equals("user")){
System.out.println("MyBeanPostProcessor的前置处理器执行2");
}
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (beanName.equals("user")){
System.out.println("MyBeanPostProcessor的后置处理器执行2");
}
return bean;
}
@Override
public int getOrder() {
return 101;
}
}
后置处理器的优先级通过继承接口:PriorityOrdered
重写getOrder()
方法来设置,数字越小优先级越高,所以bean后置处理器在AbstractBeanFactory
抽象类中放在一个list的集合中,是一个列表,在创建bean的时候依次执行。
再回到3.3.4的方法:
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this))
,这个方法添加了一个ApplicationContextAwareProcessor后置处理器,它同样实现了BeanPostProcessor
接口
/**
* {@link org.springframework.beans.factory.config.BeanPostProcessor}
* implementation that passes the ApplicationContext to beans that
* implement the {@link EnvironmentAware}, {@link EmbeddedValueResolverAware},
* {@link ResourceLoaderAware}, {@link ApplicationEventPublisherAware},
* {@link MessageSourceAware} and/or {@link ApplicationContextAware} interfaces.
*
* Implemented interfaces are satisfied in order of their mention above.
*
*
Application contexts will automatically register this with their
* underlying bean factory. Applications do not use this directly.
*
* @author Juergen Hoeller
* @author Costin Leau
* @author Chris Beams
* @since 10.10.2003
* @see org.springframework.context.EnvironmentAware
* @see org.springframework.context.EmbeddedValueResolverAware
* @see org.springframework.context.ResourceLoaderAware
* @see org.springframework.context.ApplicationEventPublisherAware
* @see org.springframework.context.MessageSourceAware
* @see org.springframework.context.ApplicationContextAware
* @see org.springframework.context.support.AbstractApplicationContext#refresh()
* 将ApplicationContext传递给实现了
* {@link EnvironmentAware},{@link EmbeddedValueResolverAware},
* {@link ResourceLoaderAware},{@link ApplicationEventPublisherAware},
* {@link MessageSourceAware},{@link ApplicationContextAware}接口的Bean实现。
*/
class ApplicationContextAwareProcessor implements BeanPostProcessor {
private final ConfigurableApplicationContext applicationContext;
private final StringValueResolver embeddedValueResolver;
/**
* Create a new ApplicationContextAwareProcessor for the given context.
*/
public ApplicationContextAwareProcessor(ConfigurableApplicationContext applicationContext) {
this.applicationContext = applicationContext;
this.embeddedValueResolver = new EmbeddedValueResolver(applicationContext.getBeanFactory());
}
@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);
}
/**
* spring帮我们set一个applicationContext对象
* 当我们自己的类实现了ApplicationContextAware,只需要提供setter方法,就能获取到applicationContext
*/
if (bean instanceof ApplicationContextAware) {
((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
}
}
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) {
return bean;
}
}
作用可以参考Spring十七小节,3.3.5-3.3.10标注代码为忽略依赖注入的类型,这些类型的bean将不能依赖注入,后面的用到了再讨论