Spring知识扫盲

1、bean生命周期:看BeanFactory注释

翻译成中文

Bean工厂实现应该尽可能的支持标准的Bean生命周期接口。整套初始化方法及其标准顺序如下:
BeanNameAware{@code setBeanName}
BeanClassLoaderware{@code setBeanClassLoader}
BeanFactoryAware{@code setBeanFactory}
EnvironmentAware{@code setEnvironment}
EmbeddedValueResolverAware{@code setEmbeddedValueResolver}
ResourceLoaderware{@code setResourceLoader}(仅在应用程序上下文中运行时适用)
ApplicationEventPublisherAware{@code setApplicationEventPublisher}(仅在应用程序上下文中运行时适用)
MessageSourceAware{@code setMessageSource}(仅在应用程序上下文中运行时适用)
ApplicationContextAware{@code setApplicationContext}(仅在应用程序上下文中运行时适用)
ServletContextAware{@code setServletContext}(仅在web应用程序上下文中运行时适用)
BeanPostProcessor{@code postprocessabefore initialization}方法
初始化Bean的{@code afterPropertieSet}自定义init方法定义
BeanPostProcessor{@code postProcessAfterInitialization}方法


关闭Bean工厂时,以下生命周期方法适用:
{@code postprocessabeforedisplation}销毁方法Warebean后处理器
DisposableBean的{@code destroy}
自定义销毁方法

 

 

2、Aware接口的作用:可以理解为是个插件,如果自己创建的bean对象需要容器的内置对象,可以通过Aware接口把对象设置到这个bean里

查看代码

package beans;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

/**
 * 只要实现Aware接口,就可自动注入容器内置的某些属性,比如注入ApplicationContext、beanName
 */
public class MyAwareBean implements ApplicationContextAware, BeanNameAware {

    private ApplicationContext applicationContext;
    
    private String beanName;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

    public ApplicationContext getApplicationContext() {
        return applicationContext;
    }

    @Override
    public void setBeanName(String name) {
        this.beanName = name;
    }

    public String getBeanName() {
        return beanName;
    }
}

 

3、BeanFactoryPostProcessor与BeanPostProcessor
BeanFactoryPostProcessor:在refresh方法的第5步执行(invokeBeanFactoryPostProcessors方法)此时已经创建好了beanFactory,并且加载好了BeanDefinition,可以在这一阶段增强(修改)BeanDefinition属性。
BeanPostProcessor:在refresh方法的第11步执行(finishBeanFactoryInitialization方法),在这一步创建bean实例 -> 属性依赖注入 -> 初始化bean(initializeBean方法)。其中initializeBean方法包括:1、调用Aware接口方法 2、调用BeanPostProcessor.before方法 3、调用init-method方法  4、调用BeanPostProcessor.after方法  可以在这一阶段增强(修改)Bean对象属性

查看代码
package beans;

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;

/**
 * BeanFactoryPostProcessor 用于增强(修改)BeanDefinition
 * 这里把org.springframework包下所有的bean设置了Lazy
 */
@Component
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
	@Override
	public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {

		String[] beanDefinitionNames = beanFactory.getBeanDefinitionNames();
		for (String beanDefinitionName : beanDefinitionNames) {
			System.out.println(beanDefinitionName);
			if (beanDefinitionName.startsWith("org.springframework")) {
				continue;
			}

			BeanDefinition beanDefinition = beanFactory.getBeanDefinition(beanDefinitionName);
			beanDefinition.setLazyInit(true);
		}
	}
}
查看代码
package beans;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;

/**
 * BeanPostProcessor用法
 *
 * 每个bean实例化之后,都会触发该方法。用于增强(修改)bean对象
 */
public class MyBeanPostProcessor implements BeanPostProcessor {

	public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		System.out.println("[BeanPostProcessor] 后置处理 " + beanName);
		if (bean instanceof User) {
			System.out.println(String.format("[BeanPostProcessor] 在bean初始化之后 init方法之前 beanName %s bean实例 %s 修改为 %s",
					beanName, bean, "Before修改的值"));
			User user = (User) bean;
			user.setName("Before修改的值");
		}

		return bean;
	}

	public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
		if (bean instanceof User) {
			System.out.println(String.format("[BeanPostProcessor] 在bean初始化之后 init方法之后 beanName %s bean实例 %s 修改为 %s",
					beanName, bean, "After修改的值"));
			User user = (User) bean;
			user.setName("After修改的值");
		}
		return bean;
	}

}

 

 4、beanFactory与factoryBean区别?
     1)都是用来创建对象的
     2)使用beanFactory时,必须要遵循完整的创建过程,这个过程是由spring来控制的
     3)当使用factoryBean只需要调用getObject()可以返回具体的对象,对象的创建过程由自己来控制,更加灵活

查看代码
package beans;

import org.springframework.beans.factory.FactoryBean;
import org.springframework.stereotype.Component;

/**
 * 可以自定义FactoryBean来创建bean对象,避开beanFactory的创建过程
 *
 * 获取bean
 * Object user = ctx.getBean("userFactoryBean");
 * System.out.println(user);
 * 
 * 获取FactoryBean
 * Object userFactoryBean = ctx.getBean("&userFactoryBean");
 * System.out.println(userFactoryBean);
 */
@Component
public class UserFactoryBean implements FactoryBean<User> {

    @Override
    public User getObject() throws Exception {
        return new User();
    }

    @Override
    public Class<?> getObjectType() {
        return User.class;
    }
}

 

5、父子容器概念

Spring是SpringMVC父容器,SpringMVC可以获取Spring配置的bean,反之不行。

 

6、循环依赖针对单例bean和原型bean会发生什么

单例bean发生循环依赖,Spring会使用三级缓存来解决。原型bean发生循环依赖,会直接报异常。

 

 

posted on 2022-01-30 21:54  wzyy  阅读(43)  评论(0编辑  收藏  举报