容器中相关概念:
1. 什么是BeanDefinition?
BeanDefinition标识Bean定义,Spring根据BeanDefinition来创建Bean对象,BeanDefinition有很多的属性用来描述Bean,BeanDefinition是Spring中非常核心的概念。
重要属性包括:
beanClass:
表示一个bean的类型,比如:UserService.class,OrderService.class,Spring在创建Bean的过程中会根据此属性来实例化得到对象。
scope:
表示一个bean的作用域,比如:
scope等于singleton,该bean就是一个单例Bean;
scope等于prototype,该bean就是一个原型bean。
isLazy
表示一个bean是不是需要懒加载,原型bean的isLazy属性不起作用,懒加载的单例bean,会在第一个getBean的时候生成该bean,非懒加载的单例bean,则会在Spring启动过程中直接生成好。
dependsOn
表示一个bean在创建之前所依赖的其他bean,在一个bean创建之前,它所依赖的这些bean得先全部创建好。
primary
表示一个bean是主bean,在Spring中一个类型可以有多个bean对象,在进行依赖注入时,如果根据类型找到了多个bean,此时会判断这些bean中是否存在一个主bean,如果存在,则直接将这个bean注入给属性。
initMethodName
表示一个bean的初始化方法,一个bean的生命周期过程中有一个步骤叫初始化,Spring会在这个步骤中去调用bean的初始化方法,初始化逻辑由程序员自己控制,表示程序员可以自定义逻辑对bean进行加工。
2. 什么是BeanFactory?
BeanDefinition和BeanFactory和Bean对象之间的关系:
BeanFactory的核心子接口和实现类
ListableBeanFactory
ConfigurableBeanFactory
AutowireCapableBeanFactory
AbstractBeanFactory
重要:DefaultListableBeanFactory
3. 什么是Bean生命周期?
过程:
A:
B:
C:
D:
E:
F:
4. @Autowired是如何工作的?
5. @Resource是如何工作的?
6. @Value是如何工作的?
7. FactoryBean是什么?
FactoryBean接口中的方法
8. 什么是ApplicationContext?
EnvironmentCapable:
ListableBeanFactory:
HierarchicalBeanFactory:
MessageSource:
ApplicationEventPublisher:
ResourcePatternResolver:
9. 什么是BeabPostProcessor?
BeabPostProcessor中的方法
InstantiationAwareBeanPostProcessor:
10. AOP是什么?
AOP中的核心概念:
Advice
Pointcut
Advisor
Weaving
Target
Join Point
Spring容器的分类:
BeanFactory:
是Bean的工厂,可以说是不同分类容器的最基础的Bean工厂,它是实现及子类是它的扩展,有更多的功能。
ApplicationContext:
是BeanFactory的子类,在BeanFactory的基础上,拥有获取资源,发布事件,国际化,获取系统环境等功能。
AnnotationConfigApplicationContext:
该类是根据一个类作为构造参数拿到bean
ClassPathXmlApplicationContext:
该类是根据相对于程序类路径下寻找配置文件作为构造参数拿到bean。
FileSystemXmlApplicationContext:
该类是根据相对当前工程下寻找配置文件作为构造参数拿到bean。。
Bean的生命周期概述
在传统的Java应用中,bean的生命周期很简单,使用Java关键字 new 进行Bean 的实例化,然后该Bean 就能够使用了。一旦bean不再被使用,则由Java自动进行垃圾回收。
相比之下,Spring管理Bean的生命周期就复杂多了,正确理解Bean 的生命周期非常重要,因为Spring对Bean的管理可扩展性非常强,下面展示了一个Bean的构造过程
实例化前
实现InstantiationAwareBeanPostProcessor 接口,重写两个方法
/**
* @author lzc
* @version 1.0.0
* @ClassName LzcBeanPostProcessor.java
* @Description TODO
* @createTime 2021年04月10日 12:12:00
*/
@Component
public class LzcBeanPostProcessor implements InstantiationAwareBeanPostProcessor {
/**
* 实例化前
* @param beanClass
* @param beanName
* @return
* @throws BeansException
*/
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
if("userService".equals(beanName)){
System.out.println("实例化前");
}
return null;
}
/**
* 实例化后
* @param bean
* @param beanName
* @return
* @throws BeansException
*/
@Override
public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
if("userService".equals(beanName)){
System.out.println("实例化后");
}
return false;
}
}
public static void main(String[] args) {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(Config.class);
UserService userservice = applicationContext.getBean("userService", UserService.class);
System.out.println(userservice);
}
看到打印
实例化
推断构造方法:
当有多个构造方法的时候,会报错并不知道使用哪个构造方法创建Bean,可以使用@Autowired注解指定,当都有指定的时候,如果设置属性required为false的话,会优先采用多个参数的构造方法,根据参数类型去 找bean,有多个的话再根据名字找到对应的bean
实例化后
在实例化前一样,里面另一个方法
初始化前
@PostConstruct注解标记在方法上是在初始化之前执行,也可以说是容器启动之后会执行该方法。
初始化
/**
* 实现InitializingBean接口
* @author lzc
* @version 1.0.0
* @ClassName UserService.java
* @Description TODO
* @createTime 2021年04月10日 12:06:00
*/
@Component
public class UserService implements InitializingBean {
private Person person;
@Autowired
public void setPerson(Person person) {
this.person = person;
}
/**
* 该方法在bean初始化的时候可以做的一些操作
* @throws Exception
*/
@Override
public void afterPropertiesSet() throws Exception {
System.out.println(this);
System.out.println(this.person);
System.out.println("初始化中");
}
}
打印
初始化后