解析的方法有:
3.prepareBeanFactory(beanFactory);为beanFactory在上下文使用做准备,也就是扩展bean的功能
4.postProcessBeanFactory(beanFactory);允许子类进行功能扩展的方法
5.invokeBeanFactoryPostProcessors(beanFactory);在上下文中以bean的形式激活工厂处理器
1.prepareBeanFactory(beanFactory);为beanFactory在上下文使用做准备,也就是扩展bean的功能:
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// Tell the internal bean factory to use the context's class loader etc.
beanFactory.setBeanClassLoader(getClassLoader());
//设置el表达式解析器
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
//设置属性编辑器
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
// Configure the bean factory with context callbacks.
//设置bean后处理器
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
//设置忽略依赖的接口
beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
beanFactory.ignoreDependencyInterface(EnvironmentAware.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);
// 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());
}
}
完成的功能:
(1)对SPEL语言的支持
(2)增加对属性编辑器的支持
(3)增加对一些内置类的支持,如EnvironmentAware、MessageSourceAware的注入
(4)设置了依赖功能可忽略的接口
(5)注册一些固定依赖的属性
(6)增加了AspectJ的支持
(7)将相关环境变量及属性以单例模式注册
1.1对SPEL语言的支持:好像在工程里使用的很少,至今没有见过。
1.2增加对属性编辑器的支持。spring默认支持bean的很多属性的自动注入,但有些是不支持的,如date类型。举个例子:
有个用户bean。
public class User {
private String username;
private Date birthday;
}
在applicationContext.xml中配置:
<bean id="user" class="com.shidebin.mongodb.springAop2.User">
<property name="username" value="shidebin"></property>
<property name="birthday" value="2019-02-21"></property>
</bean>
然后进行测试:
@Test
public void testUser() {
User user = (User)app.getBean("user");
System.out.println(user.getBirthday());
}
此时会报错:
Caused by: org.springframework.beans.ConversionNotSupportedException: Failed to convert property value of type 'java.lang.String' to required type 'java.util.Date' for property 'birthday'; nested exception is java.lang.IllegalStateException: Cannot convert value of type [java.lang.String] to required type [java.util.Date] for property 'birthday': no matching editors or conversion strategy found
at org.springframework.beans.BeanWrapperImpl.convertIfNecessary(BeanWrapperImpl.java:476)
at org.springframework.beans.BeanWrapperImpl.convertForProperty(BeanWrapperImpl.java:512)
at org.springframework.beans.BeanWrapperImpl.convertForProperty(BeanWrapperImpl.java:506)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.convertForProperty(AbstractAutowireCapableBeanFactory.java:1521)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1480)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1220)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537)
... 39 more
这说明spring认为你配置的是一个stirng类型的2019-02-21不能转换成date类型。此时就应该增加一个对date属性编辑器了。
方法一:继承PropertyEditorSupport
public class DateEditor extends PropertyEditorSupport{
public String format = "yyyy-MM-dd";
public String getFormat() {
return format;
}
public void setFormat(String format) {
this.format = format;
}
@Override
public void setAsText(String text) throws IllegalArgumentException {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat(format);
try {
setValue(simpleDateFormat.parse(text));
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
把DateEditor 注册到CustomEditorConfigurer的属性customEditors中:
@org.springframework.context.annotation.Configuration
public class Configuration {
@Bean
public CustomEditorConfigurer customEditorConfigurer() {
CustomEditorConfigurer editor = new CustomEditorConfigurer();
Map<Class<?>, Class<? extends PropertyEditor>> customEditors = new HashMap<Class<?>, Class<? extends PropertyEditor>>();
customEditors.put(Date.class, DateEditor.class);
editor.setCustomEditors(customEditors);
return editor;
}
}
然后再调刚才的测试就好了:
2019-02-21 14:03:09 INFO [com.shidebin.mongodb.springAop2.User]
调用方法:<getBirthday>的返回值为:1550678400000
方法二:实现PropertyEditorRegistrar接口:
public class DateEditor2 implements PropertyEditorRegistrar{
public void registerCustomEditors(PropertyEditorRegistry registry) {
registry.registerCustomEditor(Date.class, new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd"),true));
}
}
把DateEditor2 注册到CustomEditorConfigurer到propertyEditorRegistrars的属性中:
@org.springframework.context.annotation.Configuration
public class Configuration {
@Bean
public CustomEditorConfigurer customEditorConfigurer() {
CustomEditorConfigurer editor = new CustomEditorConfigurer();
editor.setPropertyEditorRegistrars(new PropertyEditorRegistrar[] {new DateEditor2()});
return editor;
}
}
按上面方法测试通过。
那么为什么往CustomEditorConfigurer 注册就可以调到我们自定义的解析器呢?
我们来看看CustomEditorConfigurer 中postProcessBeanFactory方法的调用关系:
CustomEditorConfigurer 中postProcessBeanFactory
-》PostProcessorRegistrationDelegate中的invokeBeanFactoryPostProcessors
-》PostProcessorRegistrationDelegate 中的invokeBeanFactoryPostProcessors
-》AbstractApplicationContext 中的invokeBeanFactoryPostProcessors(beanFactory);
-》 AbstractApplicationContext 中的invokeBeanFactoryPostProcessors。
至此可以看出,invokeBeanFactoryPostProcessors是我们fresh()方法中的第六步。所以会在第六步解析到我们自定义的解析类。
其他步骤都是为接下来的功能注入相关的解析器。
2.postProcessBeanFactory:允许子类进行功能扩展的方法:
默认为空。
3.invokeBeanFactoryPostProcessors在上下文中以bean的形式激活工厂处理器
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
}
public static void invokeBeanFactoryPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
// Invoke BeanDefinitionRegistryPostProcessors first, if any.
Set<String> processedBeans = new HashSet<String>();
//判断beanFactory是否继承于BeanDefinitionRegistry,我们此时的beanFactory实际上是
//DefaultListableBeanFactory,那么应该true。
if (beanFactory instanceof BeanDefinitionRegistry) {
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
List<BeanFactoryPostProcessor> regularPostProcessors = new LinkedList<BeanFactoryPostProcessor>();
//储存注册的后处理器
List<BeanDefinitionRegistryPostProcessor> registryPostProcessors =
new LinkedList<BeanDefinitionRegistryPostProcessor>();
//首先加入AbstractApplicationContext类中通过addBeanFactoryPostProcessor方法加入的
//PostProcessors
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
BeanDefinitionRegistryPostProcessor registryPostProcessor =
(BeanDefinitionRegistryPostProcessor) postProcessor;
registryPostProcessor.postProcessBeanDefinitionRegistry(registry);
registryPostProcessors.add(registryPostProcessor);
}
else {
regularPostProcessors.add(postProcessor);
}
}
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let the bean factory post-processors apply to them!
// Separate between BeanDefinitionRegistryPostProcessors that implement
// PriorityOrdered, Ordered, and the rest.
//加载bean中继承于PriorityOrdered, Ordered,BeanFactoryPostProcessor的
//BeanDefinitionRegistryPostProcessors
//加载顺序是PriorityOrdered, Ordered, and the rest.
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
// First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
List<BeanDefinitionRegistryPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanDefinitionRegistryPostProcessor>();
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
OrderComparator.sort(priorityOrderedPostProcessors);
registryPostProcessors.addAll(priorityOrderedPostProcessors);
invokeBeanDefinitionRegistryPostProcessors(priorityOrderedPostProcessors, registry);
// Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
List<BeanDefinitionRegistryPostProcessor> orderedPostProcessors = new ArrayList<BeanDefinitionRegistryPostProcessor>();
for (String ppName : postProcessorNames) {
if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
OrderComparator.sort(orderedPostProcessors);
registryPostProcessors.addAll(orderedPostProcessors);
invokeBeanDefinitionRegistryPostProcessors(orderedPostProcessors, registry);
// Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
boolean reiterate = true;
while (reiterate) {
reiterate = false;
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (!processedBeans.contains(ppName)) {
BeanDefinitionRegistryPostProcessor pp = beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class);
registryPostProcessors.add(pp);
processedBeans.add(ppName);
pp.postProcessBeanDefinitionRegistry(registry);
reiterate = true;
}
}
}
// Now, invoke the postProcessBeanFactory callback of all processors handled so far.
//执行所有的BeanDefinitionRegistryPostProcessor处理器
invokeBeanFactoryPostProcessors(registryPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
}
else {
// Invoke factory processors registered with the context instance.
invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
}
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let the bean factory post-processors apply to them!
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
// Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
// Ordered, and the rest.
//加载bean中继承于PriorityOrdered, Ordered,BeanFactoryPostProcessor的
//BeanFactoryPostProcessors
List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
List<String> orderedPostProcessorNames = new ArrayList<String>();
List<String> nonOrderedPostProcessorNames = new ArrayList<String>();
for (String ppName : postProcessorNames) {
if (processedBeans.contains(ppName)) {
// skip - already processed in first phase above
}
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);
}
}
// First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
OrderComparator.sort(priorityOrderedPostProcessors);
invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
// Next, invoke the BeanFactoryPostProcessors that implement Ordered.
List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
for (String postProcessorName : orderedPostProcessorNames) {
orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
OrderComparator.sort(orderedPostProcessors);
invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
// Finally, invoke all other BeanFactoryPostProcessors.
List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
for (String postProcessorName : nonOrderedPostProcessorNames) {
nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
}
完成的功能:
(1)判断beanFactory是否继承于BeanDefinitionRegistry,我们此时的beanFactory实际上是DefaultListableBeanFactory,那么应该true
(2)首先加入AbstractApplicationContext类中通过addBeanFactoryPostProcessor方法加入的PostProcessors
(3)加载bean中继承于PriorityOrdered, Ordered,BeanFactoryPostProcessor的BeanDefinitionRegistryPostProcessors 加载顺序是PriorityOrdered, Ordered, and the rest.
(4)执行所有的BeanDefinitionRegistryPostProcessor处理器
(5)加载bean中继承于PriorityOrdered, Ordered,BeanFactoryPostProcessor的BeanDefinitionRegistryPostProcessors 加载顺序是PriorityOrdered, Ordered, and the rest,并分别执行
代码都很清晰,现在我们来试试我们分析的对不对:
我们新建八个类,分别实现:
BeanDefinitionRegistryPostProcessor
BeanDefinitionRegistryPostProcessor,Ordered
BeanDefinitionRegistryPostProcessor,PriorityOrdered
BeanDefinitionRegistryPostProcessor,PriorityOrdered
BeanDefinitionRegistryPostProcessor,PriorityOrdered
BeanFactoryPostProcessor
Ordered,BeanFactoryPostProcessor
PriorityOrdered,BeanFactoryPostProcessor
PriorityOrdered,BeanFactoryPostProcessor
@Component
public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor{
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
System.out.println("MyBeanDefinitionRegistryPostProcessor is here +++");
}
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
// TODO Auto-generated method stub
}
}
@Component
public class MyBeanDefinitionRegistryPostProcessorOrder implements
BeanDefinitionRegistryPostProcessor,Ordered{
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
System.out.println("MyBeanDefinitionRegistryPostProcessorOrder is here +++");
}
public int getOrder() {
// TODO Auto-generated method stub
return 0;
}
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
// TODO Auto-generated method stub
}
}
@Component
public class MyBeanDefinitionRegistryPostProcessorPriorityOrder1 implements
BeanDefinitionRegistryPostProcessor,PriorityOrdered{
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
System.out.println("MyBeanDefinitionRegistryPostProcessorPriorityOrder1 is here +++");
}
public int getOrder() {
return 0;
}
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
// TODO Auto-generated method stub
}
}
@Component
public class MyBeanDefinitionRegistryPostProcessorPriorityOrder2 implements
BeanDefinitionRegistryPostProcessor,PriorityOrdered{
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
System.out.println("MyBeanDefinitionRegistryPostProcessorPriorityOrder2 is here ++++");
}
public int getOrder() {
// TODO Auto-generated method stub
return 1;
}
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
// TODO Auto-generated method stub
}
}
@Component
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor{
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
System.out.println("我的BeanFactoryPostProcessor处理器++");
}
}
@Component
public class MyOrder implements Ordered,BeanFactoryPostProcessor{
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
System.out.println("MyOrder is here++++");
}
public int getOrder() {
return 0;
}
}
@Component
public class MyPriorityOrdered implements PriorityOrdered,BeanFactoryPostProcessor{
public int getOrder() {
return 0;
}
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
System.out.println("MyPriorityOrdered is here+++");
}
}
@Component
public class MyPriorityOrdered2 implements PriorityOrdered,BeanFactoryPostProcessor{
public int getOrder() {
return 1;
}
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
System.out.println("MyPriorityOrdered2 is here+++");
}
}
然后使用main方法测试:
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext2.xml");
}
输出:
MyBeanDefinitionRegistryPostProcessorPriorityOrder1 is here +++
MyBeanDefinitionRegistryPostProcessorPriorityOrder2 is here ++++
MyBeanDefinitionRegistryPostProcessorOrder is here +++
MyBeanDefinitionRegistryPostProcessor is here +++
MyPriorityOrdered is here+++
MyPriorityOrdered2 is here+++
2019-02-21 17:04:31 WARN [org.springframework.context.annotation.ConfigurationClassEnhancer]
@Bean method Configuration.customEditorConfigurer is non-static and returns an object assignable to Spring's BeanFactoryPostProcessor interface. This will result in a failure to process annotations such as @Autowired, @Resource and @PostConstruct within the method's declaring @Configuration class. Add the 'static' modifier to this method to avoid these container lifecycle issues; see @Bean javadoc for complete details.
MyOrder is here++++
我的BeanFactoryPostProcessor处理器++
从结果可以看出我们的分析是正确的,但这些在我们开发当中有什么运用的地方呢。目前不知道。