一句话,被Spring容器管理的bean就是Spring bean。
Java bean的实例化对象是自己创建出来的,Spring的bean是IOC容器创建出来的。
答:有四种方式,分别如下:
# 第一种:xml方式
# 第二种:注解方式
@Component、@Controller、@Service、@Repostory
前提:需要配置扫描包
# 第三种:JavaConfig方式
@Bean
# 第四种:@Import方式
@Component是通过Spring的反射机制调用构造方法实例化的,@Bean通常和@Configuration注解搭配使用,通过方法返回,自己可以控制实例化过程。
单例bean的情况下,如果在类中声明了成员变量,并且有读写操作,那么这个bean就存在线程安全问题,但是如果把成员变量声明在方法中,那么此时这个单例bean就是线程安全的。
# 源码链接
https://gitee.com/augenstemn/spring-interview-parent.git
方式一由Spring控制bean的实例过程,方式二、三、四由程序员自己控制,更加灵活。
Spring容器创建bean后,这一个个的bean如果不为其装配(又称注入)属性,那么这些bean直接是没有任何联系的,可以手动的在xml中通过property+ref的方式手动维护bean和bean之间的关系,这种方式称为手动注入,也可以通过@Autowired的方式进行自动注入。
在Spring中,对象无需自己查找或者创建与其关联的其他对象,由容器负责把需要相互协作的对象引用赋予各个对象,可以使用@Autowired或者@Resource注解来配置自动装配模式,在Spring框架的xml配置中共有5种自动装配:
答:生命周期的回调方法主要分两种,一种是初始化的时候进行调用的,另外一种是销毁的时候进行调用的,不管是初始化调用还是销毁时调用,都有对应的三种方式。
bean的生命周期是指bean从创建到销毁的整个过程,分为如下四个大的过程,即:
实例化后,属性填充及初始化之前的bean即为不完整的bean。
双重检查锁机制。
主要出于性能的考虑,避免已创建好的bean阻塞等待。
BeanDefinition用来描述bean的生产信息,决定bean如何生产,是一个定义态的bean。我们在创建Spring容器的时候,首先会去读取配置,然后解析配置,将符合条件的bean注册成BeanDefinitionMap,然后工厂根据这些描述信息去生产bean。
循环完所有的DeanDefinition后,bean就创建完了。
# 1
public AnnotationConfigApplicationContext(String... basePackages) {
this();
scan(basePackages);
refresh();
}
# 2、AbstractApplicationContext 550行
finishBeanFactoryInitialization(beanFactory);
# 3、AbstractApplicationContext 878行
beanFactory.preInstantiateSingletons();
# 4、DefaultListableBeanFactory #preInstantiateSingletons 849~903行
@Override
public void preInstantiateSingletons() throws BeansException {
if (logger.isTraceEnabled()) {
logger.trace("Pre-instantiating singletons in " + this);
}
// Iterate over a copy to allow for init methods which in turn register new bean definitions.
// While this may not be part of the regular factory bootstrap, it does otherwise work fine.
List beanNames = new ArrayList<>(this.beanDefinitionNames);
// Trigger initialization of all non-lazy singleton beans...
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)
((SmartFactoryBean>) factory)::isEagerInit,
getAccessControlContext());
}
else {
isEagerInit = (factory instanceof SmartFactoryBean &&
((SmartFactoryBean>) factory).isEagerInit());
}
if (isEagerInit) {
getBean(beanName);
}
}
}
else {
getBean(beanName);
}
}
}
// Trigger post-initialization callback for all applicable beans...
for (String beanName : beanNames) {
Object singletonInstance = getSingleton(beanName);
if (singletonInstance instanceof SmartInitializingSingleton) {
final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction
创建监听器、实现接口
/**
* @Author : 一叶浮萍归大海
* @Date: 2023/10/25 10:58
* @Description:
*/
@Component
public class MyContextRefreshedEventExtend {
@EventListener(ContextRefreshedEvent.class)
public void onContextRefreshedEvent(ContextRefreshedEvent event) {
System.out.println(event);
System.out.println("all singleton beans loaded,onContextRefreshedEvent execute success!");
}
}
/**
* @Author : 一叶浮萍归大海
* @Date: 2023/10/25 11:03
* @Description:
*/
@Component
public class MySmartInitializingSingletonExtend implements SmartInitializingSingleton {
@Override
public void afterSingletonsInstantiated() {
System.out.println("all singleton beans loaded,afterSingletonsInstantiated execute success!");
}
}
实现BeanFactoryPostProcessor接口,做扩展。
/**
* @Author : 一叶浮萍归大海
* @Date: 2023/10/25 11:45
* @Description: bean工厂的后置处理器,用于在所有的BeanDefinition注册完成后做扩展
*/
@Component
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
for (String definitionName : beanFactory.getBeanDefinitionNames()) {
System.out.println("definitionName = " + definitionName);
}
BeanDefinition beanDefinition = beanFactory.getBeanDefinition("userService");
beanDefinition.setScope("prototype");
}
}
bean的创建顺序是由BeanDefinition的注册顺序来决定的,当存在依赖关系时,会影响bean的创建顺序。