Spring注解驱动开发(一)-Bean注入相关注解

1.介绍

1.1 目标

通过本系列文章能够熟悉并掌握Spring注解驱动开发。本小结将介绍通过注解给容器中注册组件;通过本小结,将了解如下注解:

  • AnnotationConfigApplicationContext
  • 组件添加

    • @ComponentScan
    • @Bean
    • @PostConstruct
    • @PreDestroy
    • BeanPostProcessor
    • @Configuration
    • @Component
    • @Service
    • @Controller
    • @Repository
    • @Conditional
    • @Primary
    • @Lazy
    • @Scope

    • @Import

    • ImportSelector
    • FactoryBean

1.2 环境信息

环境信息如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.20.RELEASE</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>

2.传统方式使用spring配置文件的方式给容器注入bean

  • (1)定义一个Java类,如定义一个Person类
1
2
3
public class Person {
private String name;
private Integer age;
  • (2)在maven工程的resources文件夹下定义XML文件,如定义beans.xml,并在xml文件中引入命名空间,同时定义bean组件,即Person类的Bean。
1
2
3
4
5
6
7
8
9
10
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- 传统方法使用spring配置文件的方式-->
<bean id="person" class="com.rocklei123.bean.Person">
<property name="name" value="zhangsan"></property>
<property name="age" value="18"></property>
</bean>
</beans>
  • (3)通过ApplicationContext 获取bean,并打印,代码如下:
1
2
3
4
5
6
7
8

public static void main(String[] args) {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:beans.xml");
Person p = (Person) applicationContext.getBean("person");
System.out.println(p);
}

执行结果为Person{name='zhangsan', age=18}

3.注解式开发-通过配置类方式给容器注入bean

  • (1)定义@Configuration 注解标注的配置类,告诉Spring这是一个配置类。
  • (2)通过@Bean 注解给容器中注册一个Bean;类型返回值的类型,id默认是用方法名作为id。也可以通过value属性重新定义id。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

package com.rocklei123.config;

import com.rocklei123.bean.Person;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
* @ClassName: MainConfig
* @Author: rocklei123
* @Date: 2018/12/1 22:05
* @Description:
* @Version 1.0
*/

@Configuration
public class MainConfig {

//给容器中注册一个Bean;类型返回值的类型,id默认是用方法名作为id。也可以通过value属性重新定义id
@Bean(value = "person1")
public Person person() {
return new Person("lisi", 26);
}
}

通过AnnotationConfigApplicationContext 类型的上下文获取bean,测试结果如下:

1
2
3
4
5
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class);
Person p = (Person) applicationContext.getBean("person1");
System.out.println(p);

//结果为Person{name='lisi', age=26}

4.@ComponentScan包扫描

4.1 原有配置文件方式包扫描:

1
2
<!--包扫描:只要标注了@Controller、@Service、@Repository、@Component-->
<context:component-scan base-package="com.rocklei123"></context:component-scan>

4.2 @ComponentScan基本使用

注解方式通过@ComponentScan(value = “com.rocklei123”)设置,value指定要扫描的包

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
@Configuration
@ComponentScan(value = "com.rocklei123")
public class MainConfig {

//给容器中注册一个Bean;类型返回值的类型,id默认是用方法名作为id。也可以通过value属性重新定义id
@Bean(value = "person1")
public Person person() {
return new Person("lisi", 26);
}
}

@Test
public void printBean() {
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class);
String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();//idea 快捷键Ctrl + ALT + V自动补全方法返回值
for (String beanDefinitionName : beanDefinitionNames) { //idea 快捷iter 自动生成for each循环体
System.out.println(beanDefinitionName);
}
}

执行结果:
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalRequiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
mainConfig
personController
personRepository
personService
person1

4.3 @ComponentScan高级用法-ComponentScans 等介绍

  • @ComponentScans通过源码可以需要封装ComponentScan[],即可以定义多个ComponentScan
  • includeFilters = Filter[] :指定扫描的时候只需要包含哪些组件
  • excludeFilters = Filter[] :指定扫描的时候按照什么规则排除那些组件
  • FilterType.ANNOTATION:按照注解
  • FilterType.ASSIGNABLE_TYPE:按照给定的类型;
  • FilterType.ASPECTJ:使用ASPECTJ表达式
  • FilterType.REGEX:使用正则指定
  • FilterType.CUSTOM:使用自定义规则

4.4 includeFilters

  • includeFilters = Filter[] :指定扫描的时候只需要包含哪些组件

示例1 :只包含Controller注解的类注入到Spring容器中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@Configuration
@ComponentScans(value = {@ComponentScan(value = "com.rocklei123", includeFilters = {@ComponentScan.Filter(type = FilterType.ANNOTATION, classes = {Controller.class})}, useDefaultFilters = false)})
public class MainConfig {

//给容器中注册一个Bean;类型返回值的类型,id默认是用方法名作为id。也可以通过value属性重新定义id
@Bean(value = "person1")
public Person person() {
return new Person("lisi", 26);
}
}

结果(不计入Spring本身的类):
mainConfig
personController
person1

4.5 excludeFilters

  • excludeFilters = Filter[] :指定扫描的时候按照什么规则排除那些组件

  • useDefaultFilters 默认为true

示例2 :所有PersonService 类型(包括子类)注不入到Spring容器中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@Configuration
@ComponentScans(value = {@ComponentScan(value = "com.rocklei123", excludeFilters = {@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = {PersonService.class})})})
public class MainConfig {

//给容器中注册一个Bean;类型返回值的类型,id默认是用方法名作为id。也可以通过value属性重新定义id
@Bean(value = "person1")
public Person person() {
return new Person("lisi", 26);
}
}

结果(不计入Spring本身的类):
mainConfig
personController
personRepository
person1

4.6 自定义TypeFilter

示例3 :只包含Controller注解的类、PersonService类或其子类、及匹配自定义注解的类。注入到Spring容器中

1
2
3
4
5
6
7
8
9
10
11
@Configuration
@ComponentScans(value = {@ComponentScan(value = "com.rocklei123", includeFilters = {@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = {PersonService.class}), @ComponentScan.Filter(type = FilterType.ANNOTATION, classes = {Controller.class}), @ComponentScan.Filter(type = FilterType.CUSTOM, classes = {MyTypeFilter.class})}, useDefaultFilters = false)})

public class MainConfig {

//给容器中注册一个Bean;类型返回值的类型,id默认是用方法名作为id。也可以通过value属性重新定义id
@Bean(value = "person1")
public Person person() {
return new Person("lisi", 26);
}
}

自定义过滤规则

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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
package com.rocklei123.config;

import org.springframework.core.io.Resource;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.core.type.ClassMetadata;
import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.core.type.classreading.MetadataReaderFactory;
import org.springframework.core.type.filter.TypeFilter;

import java.io.IOException;

/**
* @ClassName: MyTypeFilter
* @Author: rocklei123
* @Date: 2018/12/1 23:23
* @Description: TODO
* @Version 1.0
*/
public class MyTypeFilter implements TypeFilter {

//metadataReader:读取当前正在扫描的类的信息
//metadataReaderFactory:读取任何类的信息
@Override
public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException {
AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata();
ClassMetadata classMetadata = metadataReader.getClassMetadata();
Resource resource = metadataReader.getResource();
String className = classMetadata.getClassName();
System.out.println("----》" + className);
if (className.contains("tory")) {
return true;
}
return false;
}
}

//结果
----》com.rocklei123.IocTest
----》com.rocklei123.bean.Person
----》com.rocklei123.config.MyTypeFilter
----》com.rocklei123.MainTest
----》com.rocklei123.repository.PersonRepository
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalRequiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
mainConfig
personController
personRepository
personService
person1

5. @Scope

@Scope:注解可以调整作用域

  • prototype:多实例的:ioc容器启动并不会去调用方法创建对象放在容器中。每次获取的时候才会调用方法创建对象;

  • singleton:单实例的(默认值):ioc容器启动会调用方法创建对象放到ioc容器中。以后每次获取就是直接从容器(map.get())中拿。

  • request:同一次请求创建一个实例

  • session:同一个session创建一个实例 默认是单实例的

1
2
3
4
* ConfigurableBeanFactory#SCOPE_PROTOTYPE
* @see ConfigurableBeanFactory#SCOPE_SINGLETON
* @see org.springframework.web.context.WebApplicationContext#SCOPE_REQUEST request
* @see org.springframework.web.context.WebApplicationContext#SCOPE_SESSION sesssion

5.1 singleton(默认)测试示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
@Configuration
public class MainConfig2 {
@Bean
public Person person() {
System.out.println("给容器中添加person bean...");
return new Person("wangwu", 18);
}
}

@Test
public void test2() {
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig2.class);
//从容器获取的Bean为一个bean实例
Person person1 = (Person) applicationContext.getBean("person");
Person person2 = (Person) applicationContext.getBean("person");
System.out.println(person1 == person2);
}

//测试结果
给容器中添加person bean...
true

5.2 @Scope(value = “prototype”)测试示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

@Configuration
public class MainConfig2 {
@Bean
@Scope(value = "prototype")
public Person person() {
System.out.println("给容器中添加person bean...");
return new Person("wangwu", 18);
}
}

@Test
public void test2() {
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig2.class);
Person person1 = (Person) applicationContext.getBean("person");
Person person2 = (Person) applicationContext.getBean("person");
System.out.println(person1 == person2);
}

//结果
给容器中添加person bean...
给容器中添加person bean...
false

6.@Lazy 注解

懒加载:

  • 单实例bean:默认在容器启动的时候创建对象;

  • 懒加载:容器启动不创建对象。第一次使用(获取)Bean创建对象,并初始化;

通过以下测试代码,可以很清楚的看到容器启动不创建对象。第一次使用(获取)Bean创建对象。测试代码如下:

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

@Configuration
public class MainConfig2 {
@Bean
@Lazy
public Person person() {
System.out.println("给容器中添加person bean...");
return new Person("wangwu", 18);
}
}


@Test
public void testLazy() {
System.out.println("IOC容器准备初始化...");
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig2.class);
System.out.println("IOC容器初始化已经完成...打印当前容器中的Bean名称");
String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();//idea 快捷键Ctrl + ALT + V自动补全方法返回值
for (String beanDefinitionName : beanDefinitionNames) { //idea 快捷iter 自动生成for each循环体
System.out.println(beanDefinitionName);
}
System.out.println("通过applicationContext.getBean方法获取Person Bean");
System.out.println("Person Bean Lazy注解标注的Bean添加到容器中...");
Person person = (Person) applicationContext.getBean("person");
System.out.println("打印当前容器中的Bean名称...");
String[] beanDefinitionNames2 = applicationContext.getBeanDefinitionNames();//idea 快捷键Ctrl + ALT + V自动补全方法返回值
for (String beanDefinitionName : beanDefinitionNames2) { //idea 快捷iter 自动生成for each循环体
System.out.println(beanDefinitionName);
}
}

测试结果(过滤Spring自动注入容器的的Bean打印信息)

1
2
3
4
5
6
7
8
9
10
IOC容器准备初始化...
IOC容器初始化已经完成...打印当前容器中的Bean名称
mainConfig2
person
通过applicationContext.getBean方法获取Person Bean
Person Bean Lazy注解标注的Bean添加到容器中...
给容器中添加person bean...
打印当前容器中的Bean名称...
mainConfig2
person

7.@Conditional

7.1 @Conditional 注解介绍

@Conditional 注解: 按照一定的条件进行判断,满足条件给容器中注册bean

可通过实现org.springframework.context.annotation.Condition接口,重写public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata)方法,判断是否加入容器中。返回true表示条件成立,向容器中注入Bean。

  • ConditionContext conditionContext 判断条件能使用的上下文

  • AnnotatedTypeMetadata annotatedTypeMetadata 注释信息

1
2
3
4
5
6
7
8
//1、能获取到ioc使用的beanfactory
ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
//2、获取类加载器
ClassLoader classLoader = context.getClassLoader();
//3、获取当前环境信息
Environment environment = context.getEnvironment();
//4、获取到bean定义的注册类
BeanDefinitionRegistry registry = context.getRegistry();

7.2 @Conditional 注解示例

本例根据操作系统环境信息 os.name 确定加载的Person Bean信息。因为开发环境为Windows 10 操作系统,故本例结果将加载Person Bean为bill。

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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
public class LinuxCondition implements Condition {

@Override
public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
Environment environment = conditionContext.getEnvironment();
String property = environment.getProperty("os.name");
if (property.contains("Linux") || property.contains("linux")) {
return true;
} else {
return false;
}
}
}
public class WinCondition implements Condition {
@Override
public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
Environment environment = conditionContext.getEnvironment();
String property = environment.getProperty("os.name");
if (property.contains("Windows") || property.contains("win")) {
return true;
} else {
return false;
}
}
}

@Configuration
public class MainConfig3 {
@Bean
@Lazy
public Person person() {
System.out.println("给容器中添加person bean...");
return new Person("wangwu", 18);
}

/**
* @return
* @Conditional() 根据条件进行判断,满足条件加入到容器中
*/
@Bean
@Conditional(value = WinCondition.class)
public Person person1() {
return new Person("bill", 43);
}

@Bean
@Conditional(value = LinuxCondition.class)
public Person person2() {
return new Person("linus", 44);
}
}
@Test
public void testCondition() {
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig3.class);
Environment environment = applicationContext.getEnvironment();
String property = environment.getProperty("os.name");
System.out.println("环境信息为:" + property);
String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();
for (String beanDefinitionName : beanDefinitionNames) {
Object bean = applicationContext.getBean(beanDefinitionName);
System.out.println(bean);
}
}

运行结果(过滤Spring自动注入的类)

1
2
3
4
5
环境信息为:Windows 10
com.rocklei123.config.MainConfig3$$EnhancerBySpringCGLIB$$bddb8d66@1e67a849
给容器中添加person bean...
Person{name='wangwu', age=18}
Person{name='bill', age=43}

8.@Import

@Import[快速给容器中导入一个组件]

  • 1)、@Import(要导入到容器中的组件);容器中就会自动注册这个组件,id默认是全类名
  • 2)、ImportSelector:返回需要导入的组件的全类名数组;
  • 3)、ImportBeanDefinitionRegistrar:手动注册bean到容器中

8.1 @Import 使用

@Import 的Value是一个Class[] 数组,可以传入多个值,也可以传入单个值。

1
2
3
public @interface Import {
Class<?>[] value();
}

向Spring容器中导入一个Color组件

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
public class Color {

}

@Configuration
@Import(value = Color.class)
public class MainConfigImport {

}

public class IocTest {
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfigImport.class);

public void printBean(ApplicationContext applicationContext ) {
String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();
for (String beanDefinitionName : beanDefinitionNames) {
System.out.println(beanDefinitionName);
}
}

@Test
public void testImport(){
printBean(applicationContext );
}
}

测试结果

1
2
mainConfigImport
com.rocklei123.bean.Color

8.2 ImportSelector接口

ImportSelector 自定义逻辑返回需要导入的组件。返回值,就是到导入到容器中的组件全类名,方法不要返回null值,否则报空指针。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class MyImportSelector implements ImportSelector {
@Override
public String[] selectImports(AnnotationMetadata annotationMetadata) {
//AnnotationMetadata:当前标注@Import注解的类的所有注解信息
String className = annotationMetadata.getClassName();
System.out.println("---------" + className);
return new String[]{"com.rocklei123.bean.Red", "com.rocklei123.bean.Yellow"};
}
}

@Configuration
@Import({Color.class, MyImportSelector.class})
public class MainConfigImport {

}

测试结果

1
2
3
4
5
---------com.rocklei123.config.MainConfigImport
mainConfigImport
com.rocklei123.bean.Color
com.rocklei123.bean.Red
com.rocklei123.bean.Yellow

8.3 ImportBeanDefinitionRegistrar接口

  • AnnotationMetadata:当前类的注解信息
  • BeanDefinitionRegistry:BeanDefinition注册类;
  • 把所有需要添加到容器中的bean;调用BeanDefinitionRegistry.registerBeanDefinition手工注册进来
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
package com.rocklei123.importSelector;

import com.rocklei123.bean.RainBow;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.type.AnnotationMetadata;

/**
* @ClassName: MyImportBeanDefinitionRegistrar
* @Author: rocklei123
* @Date: 2018/12/9 14:15
* @Description: TODO
* @Version 1.0
*/
public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanDefinitionRegistry beanDefinitionRegistry) {
boolean a = beanDefinitionRegistry.containsBeanDefinition("com.rocklei123.bean.Red");
boolean b = beanDefinitionRegistry.containsBeanDefinition("com.rocklei123.bean.Yellow");
if (a && b) {
RootBeanDefinition rootBeanDefinition = new RootBeanDefinition(RainBow.class);
beanDefinitionRegistry.registerBeanDefinition("rainBow", rootBeanDefinition);
}
}
}

@Configuration
@Import({Color.class, MyImportSelector.class, MyImportBeanDefinitionRegistrar.class})
public class MainConfigImport {

}

9 FactoryBean 接口

通过实现Spring提供的FactoryBean,将Bean注入到容器中。

9.1 FactoryBean方法介绍

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@Override
//获取到的是工厂bean调用getObject创建的对象,将该对象注入到容器中
public Color getObject() throws Exception {
System.out.println("ColorFactoryBean...getObject...");
return new Color();
}

@Override
//返回对象的类型
public Class<?> getObjectType() {
return Color.class;
}

@Override
//true:这个bean是单实例,在容器中保存一份
//false:多实例,每次获取都会创建一个新的bean;
public boolean isSingleton() {
return true;
}

9.2 要获取工厂Bean本身

  • 我们需要给id前面加一个&(如&colorFactoryBean)
1
2
public interface BeanFactory {
String FACTORY_BEAN_PREFIX = "&";

9.3 FactoryBean测试代码及结果

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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
import org.springframework.beans.factory.FactoryBean;

/**
* @ClassName: ColorFactoryBean
* @Author: rocklei123
* @Date: 2018/12/9 19:41
* @Description: TODO
* @Version 1.0
*/
public class ColorFactoryBean implements FactoryBean<Color> {

@Override
public Color getObject() throws Exception {
System.out.println("ColorFactoryBean...getObject...");
return new Color();
}

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

@Override
public boolean isSingleton() {
return true;
}
}

@Configuration
public class MainConfigBeanFactory {
@Bean
public ColorFactoryBean colorFactoryBean() {
return new ColorFactoryBean();
}
}

ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfigBeanFactory.class);
@Test
public void testFactoryBean() {
printBean(applicationContext);

Object colorFactoryBean1 = applicationContext.getBean("colorFactoryBean");
Object colorFactoryBean2 = applicationContext.getBean("colorFactoryBean");
System.out.println("colorFactoryBean1=" + colorFactoryBean1 + ",colorFactoryBeanType=" + colorFactoryBean1
.getClass());
System.out.println("colorFactoryBean2=" + colorFactoryBean2 + ",colorFactoryBeanType=" + colorFactoryBean2
.getClass());
System.out.println(colorFactoryBean1 == colorFactoryBean2);

Object bean = applicationContext.getBean("&colorFactoryBean");
System.out.println(bean.getClass());
}

测试结果:

1
2
3
4
5
6
7
mainConfigBeanFactory
colorFactoryBean
ColorFactoryBean...getObject...
colorFactoryBean1=com.rocklei123.bean.Color@4461c7e3,colorFactoryBeanType=class com.rocklei123.bean.Color
colorFactoryBean2=com.rocklei123.bean.Color@4461c7e3,colorFactoryBeanType=class com.rocklei123.bean.Color
true
class com.rocklei123.bean.ColorFactoryBean

10. Spring容器注册组件总结

给容器中注册组件;

  • 1)、包扫描+组件标注注解(@Controller/@Service/@Repository/@Component)[自己写的类]
  • 2)、@Bean[导入的第三方包里面的组件]
  • 3)、@Import[快速给容器中导入一个组件]

    • 1)、@Import(要导入到容器中的组件);容器中就会自动注册这个组件,id默认是全类名
    • 2)、ImportSelector:返回需要导入的组件的全类名数组;
    • 3)、ImportBeanDefinitionRegistrar:手动注册bean到容器中
  • 4)、使用Spring提供的FactoryBean(工厂Bean);

    • 1)、默认获取到的是工厂bean调用getObject创建的对象
    • 2)、要获取工厂Bean本身,我们需要给id前面加一个&(如&colorFactoryBean)

11. 希望大家手动敲一遍代码,会收获颇丰!

12. 欢迎关注米宝窝,持续更新中,谢谢!

米宝窝 https://rocklei123.github.io/

-------------本文结束感谢您的阅读-------------
欢迎持续关注米宝窝,定期更新谢谢! https://rocklei123.github.io/
欢迎持续关注我的CSDN https://blog.csdn.net/rocklei123
rocklei123的技术点滴
熬夜写博客挺辛苦的,生怕猝死,所以每当写博客都带着听诊器,心脏一有异响,随时按Ctrl+S。
rocklei123 微信支付

微信支付

rocklei123 支付宝

支付宝