Spring 第五讲 Bean
pom.xml 准备
xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.5</version>
<relativePath/>
</parent>
<groupId>org.laoshiren</groupId>
<artifactId>spring-bean-init</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
</project>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
Aware和 InitializingBean
Aware
Aware 接口用于注入一些与容器相关的信息例如
- BeanNameAware 注入的BeanName
- BeanFactoryAware 注入的Beanfactory
- ApplicationContextAware 注入的ApplicationContext
- EmbeddedValueResolverAware ${}
java
public class BeanNameAwareBean implements BeanNameAware, BeanFactoryAware,
ApplicationContextAware, EmbeddedValueResolverAware {
@Override
public void setBeanName(String name) {
System.out.println("name:" +name);
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
System.out.println("applicationContext:"+ applicationContext.getClass());
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
System.out.println("beanFactory:"+ beanFactory.getClass());
}
@Override
public void setEmbeddedValueResolver(StringValueResolver resolver) {
}
@Autowired
public void laoshiren(ApplicationContext applicationContext){
System.out.println("注解的方式 applicationContext:"+ applicationContext.getClass());
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
shell
# 打印结果
name:myBean
beanFactory:class org.springframework.beans.factory.support.DefaultListableBeanFactory
applicationContext:class org.springframework.context.support.GenericApplicationContext
1
2
3
4
2
3
4
InitializingBean
给我们实现这个接口的类做初始化方法的接口
java
public class InitializingRealBean implements InitializingBean {
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("初始化 ");
}
@PostConstruct
public void init(){
System.out.println("注解的方式");
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
shell
# 打印结果
初始化
1
2
2
这些接口的执行是在BeanPostProcessor 执行之后执行的
为什么有了@Autowired 还需要Aware接口
@Autowired
注解属于扩展功能,实际是通过Bean 的后置处理器去解决,而Aware
接口属于内置功能,并不需要扩展,Spring本身就能识别,而内置的功能永远不会失效。
我们的程序中没有加载各种BeanPostProcessor 所以导致不识别对应的注解
java
public class AwareMain {
public static void main(String[] args) {
GenericApplicationContext context = new GenericApplicationContext();
context.registerBean(AutowiredAnnotationBeanPostProcessor.class);
context.registerBean(CommonAnnotationBeanPostProcessor.class);
context.registerBean("myBean", BeanNameAwareBean.class);
context.registerBean("myInitBean", InitializingRealBean.class);
context.refresh();
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
@Autowired 依然失效
我们的配置类在家@Bean 对应的BeanFactoryPostProcessor 之前是完全没有问题的
java
@Configuration
public class AutowireNotWorkConfig {
@Autowired
public void setApplication(ApplicationContext applicationContext){
System.out.println("application" + applicationContext.getClass());
}
@PostConstruct
public void init(){
System.out.println("初始化");
}
@Bean
public BeanFactoryPostProcessor postProcessor1(){
return postProcessor1->{
System.out.println("hello ");
};
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
Java 配置类包含BeanFactoryPostProcessor 的情况下,因为要创建其中的后置处理器的前提必须创建Java 配置类,而此时Bean后置处理器还未准备好,导致@Autowired 失效,注册后处理器在前,而@Autowired 注解在后,所以会导致此类的注解失效。
其他
@PostConstruct 、InitializingBean 和 @Bean(initMethod = "init") 三种方法的优先级?
- @PostConstruct 因为是Bean 的后置处理器执行的
- InitializingBean
- @Bean 是定义成BeanDefinition 后在执行的